1. 程式人生 > >基於VS2013 MFC的OPENCV3.1環境構建及測試

基於VS2013 MFC的OPENCV3.1環境構建及測試

frame 向導 tla else 通知 -c .cpp null erp

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環境構建及測試