#include "stdafx.h"
#include<iostream>
#include<opencv2/core/core.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/highgui/highgui.hpp>
using namespace cv;
class ColorDetector
{
private:
//最小可接受距离
int minDist;
//目标色
cv::Vec3b target;
//结果图像
cv::Mat result;
//计算与目标颜色的距离
int getDistance(cv::Vec3b color)
{
return abs(color[0] - target[0]) + abs(color[1] - target[1]) + abs(color[2] - target[2]);
}
public:
//空构造函数
ColorDetector() :minDist(100)
{
//初始化默认参数
target[0] = target[1] = target[2] = 0;
}
void setColorDistanceThreshold(int distance);
int getColorDistanceThreshold() const;
void setTargetColor(unsigned char red, unsigned char green, unsigned char blue);
void setTargetColor(cv::Vec3b color);
cv::Vec3b getTargetColor() const;
cv::Mat ColorDetector::process(const cv::Mat &image);
};
//设置色彩距离阈值,阈值必须是正的,否则设为0
void ColorDetector::setColorDistanceThreshold(int distance)
{
if (distance < 0)
distance = 0;
minDist = distance;
}
//获取色彩距离阈值
int ColorDetector::getColorDistanceThreshold() const
{
return minDist;
}
//设置需检测的颜色
void ColorDetector::setTargetColor(unsigned char red, unsigned char green, unsigned char blue)
{
//BGR顺序
target[2] = red;
target[1] = green;
target[0] = blue;
}
//设置需检测的颜色
void ColorDetector::setTargetColor(cv::Vec3b color)
{
target = color;
}
//获取需检测的颜色
cv::Vec3b ColorDetector::getTargetColor() const
{
return target;
}
cv::Mat ColorDetector::process(const 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>();
for (; it != itend; ++it, ++itout)//处理每个像素
{
//计算离目标颜色的距离
if (getDistance(*it) < minDist)
{
*itout = 255;
}
else
{
*itout = 0;
}
}
return result;
}
int _tmain(int argc, _TCHAR* argv[])
{
//1.创建图像处理的对象
ColorDetector cdetect;
//2.读取输入图像
cv::Mat image = cv::imread("boldt.jpg");
if (!image.data)
{
return 0;
}
//3.设置输入参数
cdetect.setTargetColor(130, 190, 230);//蓝天的颜色
cv::namedWindow("result");
//4.处理并显示结果
cv::imshow("result", cdetect.process(image));
cv::waitKey();
return 0;
}