基于VS2013 MFC的OPENCV3.1环境构建及测试

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于VS2013 MFC的OPENCV3.1环境构建及测试相关的知识,希望对你有一定的参考价值。

1.    创建OPENCV工程

    1)打开VS2013,点击新建项目->MFC应用程序,并选择保存名称及路径,如下图,

    技术分享  

    2)  点击确定进入MFC应用程序向导,设置如下,

    技术分享

    技术分享

    技术分享  

    3)  配置OPENCV,具体可参考http://www.cnblogs.com/yunfung/p/6756367.html

2.    MFC 界面设计

    在资源视图中,双击IDD_TESTOPENCV_MFC_DIALOG,在显示的窗口中,添加两个按钮(通过工具箱中的对话框编辑器),并适当修改(单击相应对话框部件,在属性窗口中,调整Caption的显示值及ID值;如Open Image 的ID值为ID_OPEN,Process 的ID值为ID_PROCESS)及调整布局,如下图

    技术分享

3.    完善工程

    1)  分别将相应工程文件colordetector.h、colordetector.cpp、colorDetectController.h添加到工程。注意在源文件首行添加#include "stdafx.h"定义 

    colordetector.h

技术分享
 1 #if !defined COLORDETECT
 2 #define COLORDETECT
 3 
 4 #include <opencv2/core/core.hpp>
 5 #include <opencv2/imgproc/imgproc.hpp>
 6 
 7 class ColorDetector {
 8   private:
 9       int maxDist;        // minimum acceptable distance
10       cv::Vec3b target;   // target color 
11       cv::Mat result;     // image containing resulting binary map
12   public:
13       
14       ColorDetector() : maxDist(20), target(0,0,0){}   
15 
16 
17       // Computes the distance from target color.
18       int getDistanceToTargetColor(const cv::Vec3b& color) const;      //  no{ }
19       int getColorDistance(const cv::Vec3b& color1, const cv::Vec3b& color2) const;
20 
21       // Processes the image. Returns a 1-channel binary image.
22       cv::Mat process(const cv::Mat &image);
23   
24 
25       void setColorDistanceThreshold(int distance);
26       // Gets the color distance threshold
27       int getColorDistanceThreshold() const;
28         
29       // Sets the color to be detected
30       void setTargetColor(uchar blue, uchar green, uchar red);
31       // Sets the color to be detected
32       void setTargetColor(cv::Vec3b color);
33       
34       // Gets the color to be detected
35       cv::Vec3b getTargetColor() const; 
36 };  // semicolons need
37 
38 #endif
View Code  

    colordetector.cpp

技术分享
 1 #include "stdafx.h"
 2 // Classes split .h & .cpp
 3 #include "colordetector.h"
 4 #include <vector>
 5 
 6 
 7 int ColorDetector::getDistanceToTargetColor(const cv::Vec3b& color) const{
 8     return getColorDistance(color, target);  
 9 }
10 
11 int ColorDetector::getColorDistance(const cv::Vec3b& color1, const cv::Vec3b& color2) const{
12     return abs(color1[0] - color2[0]) + abs(color1[1] - color2[1]) + abs(color1[2] - color2[2]);
13 }
14 
15 void ColorDetector::setColorDistanceThreshold(int distance){
16     if (distance < 0)
17     distance = 0;
18     maxDist = distance;
19 }
20 
21 
22 int ColorDetector::getColorDistanceThreshold() const { 
23     return maxDist;
24 }
25 
26 void  ColorDetector::setTargetColor(uchar blue, uchar green, uchar red) { 
27     target = cv::Vec3b(blue, green, red); 
28 }
29 
30 void  ColorDetector::setTargetColor(cv::Vec3b color) { 
31     target = color; 
32 }
33 
34 cv::Vec3b ColorDetector::getTargetColor() const { 
35     return target;
36 }
37 
38 cv::Mat ColorDetector::process(const cv::Mat &image) {
39       // re-allocate binary map if necessary same size as input image, but 1-channel
40       result.create(image.size(),CV_8U);
41       // get the iterators
42       cv::Mat_<cv::Vec3b>::const_iterator it= image.begin<cv::Vec3b>();
43       cv::Mat_<cv::Vec3b>::const_iterator itend= image.end<cv::Vec3b>();
44       cv::Mat_<uchar>::iterator itout= result.begin<uchar>();
45       for ( ; it!= itend; ++it, ++itout) 
46       { 
47           // compute distance from target color
48           if (getDistanceToTargetColor(*it) < maxDist) {
49               *itout= 255;
50           } 
51           else {
52               *itout= 0;
53           }
54       }
55       return result;
56 }
View Code   

    colorDetectController.h   

技术分享
 1 #if !defined CD_CNTRLLR
 2 #define CD_CNTRLLR
 3 
 4 #include <opencv2/highgui/highgui.hpp>
 5 #include "colordetector.h"
 6 
 7 class ColorDetectController {
 8 
 9 private:
10     //create the classes required to execute the application
11     ColorDetector *cdetect;      
12     //need two member variables in order to hold a reference to the input and output results
13     cv::Mat image;            
14     cv::Mat result;            
15 public:
16     ColorDetectController() { 
17         //use a dynamic allocation for our class  setting up the application 
18         cdetect = new ColorDetector();
19     }
20 
21     void setColorDistanceThreshold(int distance) {
22         cdetect->setColorDistanceThreshold(distance);
23     }
24 
25     int getColorDistanceThreshold() const {
26         return cdetect->getColorDistanceThreshold();
27     }
28 
29     void setTargetColor(unsigned char red, unsigned char green, unsigned char blue) {
30         cdetect->setTargetColor(blue, green, red);
31     }
32 
33     void getTargetColour(unsigned char &red, unsigned char &green, unsigned char &blue) const {
34         cv::Vec3b colour = cdetect->getTargetColor();
35         red = colour[2];
36         green = colour[1];
37         blue = colour[0];
38     }
39 
40     bool setInputImage(std::string filename) {    
41         image = cv::imread(filename);
42         return !image.empty();
43     }
44 
45     const cv::Mat getInputImage() const {
46         return image;
47     }
48 
49     void process() {
50         result = cdetect->process(image);    
51     }
52 
53     const cv::Mat getLastResult() const {
54         return result;    
55     }
56 
57     // Deletes all processor objects created by the controller.
58     ~ColorDetectController() {    
59         delete cdetect;
60     }
61 };
62 
63 #endif
View Code

    2)  在TestOpencv_MFCDlg.h中添加OPENCV相应的头文件,并创建一个ColorDetectController类对象,如下图

     技术分享         

    3)  在布局窗口中双击相应的部件,会将相应的代码自动添加到工程中(TestOpencv_MFCDlg.h、TestOpencv_MFCDlg.cpp),如下图

    技术分享          技术分享

    4)  填充相应CTestOpencv_MFCDlg::OnBnClickedOpen()、CTestOpencv_MFCDlg::OnBnClickedProcess()相应代码,即可完善工程  

    TestOpencv_MFCDlg.h

技术分享
 1 #include <opencv2/core/core.hpp>
 2 #include <opencv2/highgui/highgui.hpp>
 3 #include <iostream>
 4 #include "colorDetectController.h"
 5 #include <stdio.h>
 6 
 7 
 8 // TestOpencv_MFCDlg.h : 头文件
 9 //
10 
11 #pragma once
12 
13 
14 // CTestOpencv_MFCDlg 对话框
15 class CTestOpencv_MFCDlg : public CDialogEx
16 {
17 // 构造
18 public:
19     CTestOpencv_MFCDlg(CWnd* pParent = NULL);    // 标准构造函数
20     
21     ColorDetectController controller;
22 // 对话框数据
23     enum { IDD = IDD_TESTOPENCV_MFC_DIALOG };
24 
25     protected:
26     virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
27 // 实现
28 protected:
29     HICON m_hIcon;
30 
31     // 生成的消息映射函数
32     virtual BOOL OnInitDialog();
33     afx_msg void OnPaint();
34     afx_msg HCURSOR OnQueryDragIcon();
35     DECLARE_MESSAGE_MAP()
36 public:
37     afx_msg void OnBnClickedOpen();
38     afx_msg void OnBnClickedProcess();
39     afx_msg void OnBnClickedOk();
40     afx_msg void OnBnClickedCancel();
41 };
View Code

    TestOpencv_MFCDlg.cpp

技术分享
  1 // TestOpencv_MFCDlg.cpp : 实现文件
  2 //
  3 
  4 #include "stdafx.h"
  5 #include "TestOpencv_MFC.h"
  6 #include "TestOpencv_MFCDlg.h"
  7 #include "afxdialogex.h"
  8 
  9 #ifdef _DEBUG
 10 #define new DEBUG_NEW
 11 #endif
 12 
 13 
 14 // CTestOpencv_MFCDlg 对话框
 15 
 16 
 17 
 18 CTestOpencv_MFCDlg::CTestOpencv_MFCDlg(CWnd* pParent /*=NULL*/)
 19     : CDialogEx(CTestOpencv_MFCDlg::IDD, pParent)
 20 {
 21     m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
 22 }
 23 
 24 void CTestOpencv_MFCDlg::DoDataExchange(CDataExchange* pDX)
 25 {
 26     CDialogEx::DoDataExchange(pDX);
 27 }
 28 
 29 BEGIN_MESSAGE_MAP(CTestOpencv_MFCDlg, CDialogEx)
 30     ON_WM_PAINT()
 31     ON_WM_QUERYDRAGICON()
 32 
 33     ON_BN_CLICKED(ID_OPEN, &CTestOpencv_MFCDlg::OnBnClickedOpen)
 34     ON_BN_CLICKED(ID_PROCESS, &CTestOpencv_MFCDlg::OnBnClickedProcess)
 35     ON_BN_CLICKED(IDOK, &CTestOpencv_MFCDlg::OnBnClickedOk)
 36     ON_BN_CLICKED(IDCANCEL, &CTestOpencv_MFCDlg::OnBnClickedCancel)
 37 END_MESSAGE_MAP()
 38 
 39 
 40 // CTestOpencv_MFCDlg 消息处理程序
 41 
 42 BOOL CTestOpencv_MFCDlg::OnInitDialog()
 43 {
 44     CDialogEx::OnInitDialog();
 45 
 46     // 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动
 47     //  执行此操作
 48     SetIcon(m_hIcon, TRUE);            // 设置大图标
 49     SetIcon(m_hIcon, FALSE);        // 设置小图标
 50 
 51     // TODO:  在此添加额外的初始化代码
 52 
 53     return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
 54 }
 55 
 56 // 如果向对话框添加最小化按钮,则需要下面的代码
 57 //  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序,
 58 //  这将由框架自动完成。
 59 
 60 void CTestOpencv_MFCDlg::OnPaint()
 61 {
 62     if (IsIconic())
 63     {
 64         CPaintDC dc(this); // 用于绘制的设备上下文
 65 
 66         SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
 67 
 68         // 使图标在工作区矩形中居中
 69         int cxIcon = GetSystemMetrics(SM_CXICON);
 70         int cyIcon = GetSystemMetrics(SM_CYICON);
 71         CRect rect;
 72         GetClientRect(&rect);
 73         int x = (rect.Width() - cxIcon + 1) / 2;
 74         int y = (rect.Height() - cyIcon + 1) / 2;
 75 
 76         // 绘制图标
 77         dc.DrawIcon(x, y, m_hIcon);
 78     }
 79     else
 80     {
 81         CDialogEx::OnPaint();
 82     }
 83 }
 84 
 85 //当用户拖动最小化窗口时系统调用此函数取得光标
 86 //显示。
 87 HCURSOR CTestOpencv_MFCDlg::OnQueryDragIcon()
 88 {
 89     return static_cast<HCURSOR>(m_hIcon);
 90 }
 91 
 92 
 93 
 94 void CTestOpencv_MFCDlg::OnBnClickedOpen()
 95 {
 96     // TODO: 在此添加控件通知处理程序代码
 97     CFileDialog dlg(TRUE, _T("*.bmp"), NULL, OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY,
 98                                 _T("imagefile(*.bmp; *.jpg)|*.bmp; *.jpg|All Files(*.*)|*.*||"), NULL);
 99     dlg.m_ofn.lpstrTitle = _T("Open Image");
100     // if  a filename has been selected
101     if (IDOK == dlg.DoModal())
102     {
103         
104         //std::string filename = dlg.GetPathName();
105         // Note CString  string
106 
107         CString strMfc = dlg.GetPathName();
108         std::string filename = CT2CA(strMfc.GetBuffer(0));
109         // set and display the input image
110         controller.setInputImage(filename);
111         cv::imshow("Input Image", controller.getInputImage());
112     }
113 
114 }
115 
116 
117 void CTestOpencv_MFCDlg::OnBnClickedProcess()
118 {
119     // TODO:  在此添加控件通知处理程序代码
120     // target color is hard-coded here
121     controller.setTargetColor(240, 0, 0);
122     // process the input image and display result
123     controller.process();
124     cv::imshow("Output Result", controller.getLastResult());
125 }
126 
127 
128 void CTestOpencv_MFCDlg::OnBnClickedOk()
129 {
130     // TODO:  在此添加控件通知处理程序代码
131     CDialogEx::OnOK();
132 }
133 
134 
135 void CTestOpencv_MFCDlg::OnBnClickedCancel()
136 {
137     // TODO:  在此添加控件通知处理程序代码
138     CDialogEx::OnCancel();
139 }
View Code 

4.    运行结果

    技术分享

 

 

 

 

 

以上是关于基于VS2013 MFC的OPENCV3.1环境构建及测试的主要内容,如果未能解决你的问题,请参考以下文章

2.VS2013和opencv3.1.0开发环境配置

OpenCV3.1.0+VS2015开发环境配置

1.VS2013和opencv3.1.0安装教程

vs2013配置opencv3.1

VS2013生成Release版本MFC程序在其他机器上运行

最简单DIY基于ESP32CAM的物联网相机系统⑥(用上位机VS2013 MFC实现WIFI图传)