OpenCV MFC 模块间通信
1. 新建MFC项目
点击完成。
2. 添加按钮
在“工具箱”中找到“Button”控件,添加至界面:
2. 配置opencv, 添加colordetector.h

#include<iostream> #include "opencv2/opencv.hpp" using namespace std; class ColorDetector{ private: //最小可接受距离 int minDist; //目标色 cv::Vec3b target; //结果图像 cv::Mat result; public: //构造函数 ColorDetector() : minDist(100) { //初始化默认参数 target[0] = target[1] = target[2] = 0; } //设置彩色距离阈值,阈值须为非负数 void setColorDistabceThreshold(int distance) { if (distance < 0) distance = 0; minDist = distance; } //获取彩色距离阈值 int getColorDistanceThreshold() const { return minDist; } //设置需检测的颜色 void setTargetColor(unsigned char red, unsigned char green, unsigned char blue) { target[2] = red; target[1] = green; target[0] = blue; } //设置需检测的颜色 void setTargetColor(cv::Vec3b color) { target = color; } //获取需检测的颜色 cv::Vec3b getTargetColor() const { return target; } //二值化处理函数 cv::Mat_<uchar> process(cv::Mat &image) { result.create(image.rows, image.cols, CV_8U); //得到迭代器 cv::Mat_<cv::Vec3b>::const_iterator it = image.begin<cv::Vec3b>(); cv::Mat_<cv::Vec3b>::const_iterator itend = image.end<cv::Vec3b>(); cv::Mat_<uchar>::iterator itout = result.begin<uchar>(); while (it != itend) { if (getDistance(*it) < minDist) { *itout = 255; } else { *itout = 0; } it++;//更新输入迭代器 itout++;;//更新输出迭代器 } return result; } //计算颜色距离 int getDistance(const cv::Vec3b &color) const { cv::Vec3b dist; cv::absdiff(color, target, dist); return cv::sum(dist)[0]; } }; class ColorDetectController { private: ColorDetector* cdetect;//算法类 cv::Mat image;//待处理的图像 cv::Mat result;//结果 public: ColorDetectController() { cdetect = new ColorDetector(); } //设置色彩距离阈值 void setColorDistanceThreshold(int distance) { cdetect->setColorDistabceThreshold(distance); } //获取色彩距离阈值 int getColorDistancethreshold() const { return cdetect->getColorDistanceThreshold(); } //设置要检测的颜色 void setTargetColor(unsigned char red, unsigned char green, unsigned char blue) { cdetect->setTargetColor(red, green, blue); } //获取要检测的颜色 void getTargetColor(unsigned char& red, unsigned char& green, unsigned char& blue) const { cv::Vec3b color = cdetect->getTargetColor(); red = color[2]; green = color[1]; blue = color[0]; } //设置输入图像,通过文件读取 bool setInputImage(string filename) { image = cv::imread(filename); if (!image.data) return false; else return true; } //返回当前的输入图像 const cv::Mat getInputImage() const { return image; } //开始处理图像 void process() { result = cdetect->process(image); } //获取最近一次处理的结果 const cv::Mat getLastResult() const { return result; } //删除当前控制器创建的处理对象 ~ColorDetectController() { delete cdetect; } };
在3_2模块间通信.h 添加头文件 #include "colordetector.h"
在3_2模块间通信Dlg.h 添加公有成员 ColorDetectController controller;
3. 右击“Button1”,选择属性,将”Caption“属性改为”打开图像“,ID 属性改为 OpenImg。双击按钮添加代码段:
CFileDialog dlg(TRUE, _T("*.bmp"), NULL, OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY, _T("image file(*.bmp;*,jpg)|*.bmp;*.jpg|ALL Files(*.*)|*.*||"), NULL); dlg.m_ofn.lpstrTitle = _T("Open Image"); // if a filename has been selected if (dlg.DoModal() == IDOK) { // get the path of the selected filename CString strMfc = dlg.GetPathName(); std::string filename = CT2CA(strMfc.GetBuffer(0)); // set and display the input image controller.setInputImage(filename); cv::imshow("Input Image", controller.getInputImage()); }
右击“Button1”,选择属性,将”Caption“属性改为”处理图像“,ID 属性改为 ProcessImg。双击按钮添加代码段:
// target color is hard-coded here controller.setTargetColor(130, 190, 230); // process the input image and display result controller.process(); cv::imshow("Output Result", controller.getLastResult());