OPENCV颜色检测——自定义类版本
OPENCV颜色检测——自定义类版本
程序是跟着教程一步一步的敲出来的,代码都是一样的,但是是分离的,因而将代码完成整合如下。
程序代码
#include <opencv2/opencv.hpp>
#include <iostream>
class ColorDetector{
private:
//允许的最小差距
int maxDist;
//目标颜色
cv::Vec3b target;
//存储二值影响结果的图像
cv::Mat result;
public:
//空的构造函数
//在此初始化默认参数
ColorDetector():maxDist(100),target(0,0,0){}
//另一种构造函数,使用目标颜色和颜色距离作为参数
ColorDetector(uchar blue,uchar green,uchar red,int maxDist):target(blue,green,red),maxDist(maxDist){}
//设置设置颜色差距的阈值
//阈值必须是整数否则为0
void setColorDistanceThreshold(int distance){
if(distance<0)
distance = 0;
maxDist = distance;
}
//获取颜色差距的阈值
int getColorDistanceThreshold() const { return maxDist; }
//设置需要检测的颜色
void setTargetColor(uchar blue,uchar green,uchar red){
//次序为BGR
target = cv::Vec3b(blue, green, red);
}
//设置需要检测的颜色
void setTargetColor(cv::Vec3b color) { target = color; }
//获取需要检测的颜色
cv::Vec3b getTargetColor() { return target; }
int getColorDistance(const cv::Vec3b&color1,const cv::Vec3b&color2)const{
//计算两个颜色之间的城区距离
return cv::abs(color1[0] - color2[0]) + cv::abs(color1[1] - color2[1]) + cv::abs(color1[2] - color2[2]);
//返回欧几里德距离
return static_cast<int>(cv::norm<int, 3>(cv::Vec3i(color1[0] - color2[0], color1[1] - color2[1], color1[2] - color2[2])));
}
//计算与目标颜色的差距
int getDistanceToTargetColor(const cv::Vec3b&color)const{
return getColorDistance(color, target);
}
//核心处理函数
cv::Mat process(cv::Mat &image){
//必要时重新分配二值映像
//与输入图像的尺寸相同,不过是单通道的
result.create(image.size(), 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(getDistanceToTargetColor(*it)<=maxDist)
*itout = 255;
else
*itout = 0;
}
return result;
}
};
int main(){
ColorDetector cdetect;
//读入图像
cv::Mat image = cv::imread("C:/Pictures/Photo/wallhaven-3zw579.jpg");
cv::imshow("image", image);
if(image.empty())
return 0;
cdetect.setTargetColor(226, 180, 130);
cv::namedWindow("result");
cv::Mat result = cdetect.process(image);
cv::imshow("result", result);
cv::waitKey(0);
return 0;
}