#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;
}