本节对应OpenCV.2.Computer.Vision.Application.Programming.Cookbook
-----第3章ProcessingImages with Classes 中的Using a Controller to communicate with processing modules的部分。
本节把书中的提要详细化,给自已备份的同时也希望给别人一点启发。
开始
一、打开VS2010,建立项目
二、下一步后,原来的“使用Unicode库”勾去掉。
三、完成后,出现编辑界面
四、编辑对话框,设计成如下界面。
五、点开“解决方案资源管理器”,添加头文件colordetector.h
#if !definedCOLORDETECT
#define COLORDETECT
#include<opencv2/core/core.hpp>
class ColorDetector
{
private:
//minimumacceptable distance
int minDist;
//target color
cv::Vec3b target;
//imagecontaining resulting binary map
cv::Mat result;
//inlineprivate member function
//Computes thedistance from target color.
int getDistance(const cv::Vec3b& color)const;
public:
//empty constructor
ColorDetector():minDist(100)
{
//default parameter initialization here
target[0] = target[1] = target[2]= 0;
}
//Getters andsetters
//Sets thecolor distance threshold
//Thresholdmust be positive,otherwise distance threshold is set to 0.
void setColorDistanceThreshold(int distance);
//Gets thecolor distance threshold
int getColorDistanceThreshold()const;
// Sets thecolor to be detected
void setTargetColor(unsignedchar red,unsignedchar green,unsignedchar blue);
// Sets thecolor to be detected
void setTargetColor(cv::Vec3b color);
// Gets thecolor to be detected
cv::Vec3b getTargetColor() const;
// Processesthe image. Returns a 1-channel binary image.
cv::Mat proecess(constcv::Mat &image);
};
#endif
六、添加源文件colordetector.cpp
#include "StdAfx.h"
#include"colordetector.h"
int ColorDetector::getDistance(constcv::Vec3b& color)const
{
return abs(color[0]-target[0])+abs(color[1]-target[1])+abs(color[2]-target[2]);
}
void ColorDetector::setColorDistanceThreshold(int distance)
{
if (distance < 0 )
{
distance = 0;
}
minDist = distance;
}
int ColorDetector::getColorDistanceThreshold()const
{
returnminDist;
}
void ColorDetector::setTargetColor(unsignedchar red, unsignedchar green,unsignedchar blue)
{
target[2] = red;
target[1] = green;
target[0] = blue;
}
void ColorDetector::setTargetColor(cv::Vec3b color)
{
target = color;
}
cv::Vec3bColorDetector::getTargetColor() const
{
return target;
}
cv::MatColorDetector::proecess(const cv::Mat&image)
{
// re-allocatebinary map if necessary
// same size asinput image,but 1-channel
result.create(image.rows,image.cols,CV_8U);
// get theiterators
cv::Mat_<cv::Vec3b>::const_iteratorit = image.begin<cv::Vec3b>();
cv::Mat_<cv::Vec3b>::const_iteratoritend = image.end<cv::Vec3b>();
cv::Mat_<uchar>::iterator itout =result.begin<uchar>();
// for eachpixel
for ( ;it != itend; ++it, ++itout )
{
//process each pixel ------------------------
//compute distance from target color
if( getDistance(*it) < minDist )
{
*itout = 255;
}
else
{
*itout = 0;
}
//end ofpixel processing
}
return result;
}
七、同理添加colorDetectController.h和colorDetectController.cpp
//colorDetectController.h
#if !definedCD_CNTRLLR
#define CD_CNTRLLR
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include"colordetector.h"
class ColorDetectController
{
private:
static ColorDetectController *singleton; // pointer to the singleton
ColorDetector *cdetect;
// The image tobe processed
cv::Mat image;
cv::Mat result;
public:
ColorDetectController();
// Sets thecolor distance threshold
void setColorDistanceThreshold(int distance);
// Gets thecolor distance threshold
int getColorDistanceThreshold()const;
// Sets thecolor to be detected
void setTargetColor(unsignedchar red,unsignedchar green,unsignedchar blue);
// Gets thecolor to be detected
void getTargetColor(unsignedchar &red,unsignedchar &green,unsignedchar &blue)const;
// Sets theinput image. Reads it from file
bool setInputImage(std::string filename);
// Returns thecurrent input image.
const cv::Mat getInputImage()const;
// Performsimage processing
void process();
// Returns theimage result from the latest processing
const cv::MatgetLastResult()const;
// Deletes allprocessor objects created by the controller
~ColorDetectController();
// Singletonstatic members
static ColorDetectController *getInstance()
{
if (singleton == 0)
singleton= new ColorDetectController;
return singleton;
}
// Releases thesingleton instance of this controller.
static void destroy();
};
#endif
//colorDetectController.cpp
#include "StdAfx.h"
#include"colorDetectController.h"
ColorDetectController*ColorDetectController::singleton = 0;
ColorDetectController::ColorDetectController()
{
// privateconstructor
// setting upthe application
cdetect = new ColorDetector();
}
void ColorDetectController::setColorDistanceThreshold(intdistance)
{
cdetect->setColorDistanceThreshold(distance);
}
int ColorDetectController::getColorDistanceThreshold()const
{
return cdetect->getColorDistanceThreshold();
}
void ColorDetectController::setTargetColor(unsignedchar red, unsignedchar green, unsignedchar blue)
{
cdetect->setTargetColor(red,green,blue);
}
void ColorDetectController::getTargetColor(unsignedchar&red, unsignedchar&green, unsignedchar&blue) const
{
cv::Vec3b color =cdetect->getTargetColor();
red = color[2];
green = color[1];
blue = color[0];
}
bool ColorDetectController::setInputImage(std::stringfilename)
{
image = cv::imread(filename);
if (!image.data )
returnfalse;
else
returntrue;
}
const cv::Mat ColorDetectController::getInputImage()const
{
return image;
}
void ColorDetectController::process()
{
result = cdetect->proecess(image);
}
const cv::Mat ColorDetectController::getLastResult()const
{
return result;
}
ColorDetectController::~ColorDetectController()
{
delete cdetect;
}
void ColorDetectController::destroy()
{
if (singleton != 0 )
{
delete singleton;
singleton = 0;
}
}
八,双击ColourDetectorDlg.h,出现编辑界面,导入头文件colorDetectController.h和定义变量colordetect
九、添加“OpenImage”按钮和“Process”按钮的事件处理程序
十、分别添加代码
void CColourDetectorDlg::OnBnClickedOpenButton()
{
// TODO: 在此添加控件通知处理程序代码
CFileDialog dlg(TRUE,_T("*.bmp"),NULL,OFN_FILEMUSTEXIST |OFN_PATHMUSTEXIST | OFN_HIDEREADONLY,_T("imagefile(*.bmp; *.jpg)|*.bmp; *.jpg|All Files(*.*)|*.*||"),NULL);
dlg.m_ofn.lpstrTitle = _T("Open Image");
// if a filename has been selected
if ( IDOK== dlg.DoModal() )
{
std::string filename = dlg.GetPathName();
// setand display the input image
colordetect.setInputImage(filename);
cv::imshow("Input Image",colordetect.getInputImage());
}
}
void CColourDetectorDlg::OnBnClickedProcessButton()
{
// TODO: 在此添加控件通知处理程序代码
// target coloris hard-coded here
colordetect.setTargetColor(130,190,230);
// process theinput image and display result
colordetect.process();
cv::imshow("OutputResult",colordetect.getLastResult());
}
十一、编译,出现
单击 “Open Image”,出现
选择所要图片
单击“Process”,出现
十二、原文界面还有一个不足。就是直接点击“Process”按钮后会出现内存错误提示,是因为没打开原图之前是无法处理图片的。
1、单击“Process”按钮,弹出“属性”框,把“Disabled”改成“True”
2、双击“ColourDetectorDlg.cpp”,在“Open Image”按钮的处理事件中添加
// IDC_PROCESS_BUTTON为“Process”按钮的ID
GetDlgItem(IDC_PROCESS_BUTTON)->EnableWindow(true);