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. 運作結果
轉載于:https://www.cnblogs.com/yunfung/p/6852996.html