一个设计模式是一个可靠的,可重用的方案,用于解决软件设计中频繁出现的问题。策略设计模式的目标是将算法封装在类中。因此可以很容易的替换一个现有的算法,或者把几个算法组合起来进行更复杂的处理,都会更加容易。而且这种模式能够尽可能地将算法的复杂性隐藏在一个直观的编程接口之后,因而有利于算法的部署。
比方说,我们需要构建一个简单的算法,它可以鉴别图像中含有给定颜色的所有像素。该算法输入的是图像以及颜色,并返回表示含有指定颜色的像素的二值图像。该算法还要指定另外一个参数,用来表示对颜色偏差的容忍度算法的核心部分实现方法如下:
//得到迭代器 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; } //结束图像处理 } CV ::垫类型的变量图像表示输入图像,而导致表示的是二值输出图像。因此,第一步包括初始化所需的迭代器,之后的循环遍历很容易实现。每个迭代检查当前像素的颜色与目标颜色的距离,判断是否在minDist所定义的容忍度之内。如果判断为真,那么输出图像中的当前像素赋值为255(白色),否则赋值为0(黑色).getdistance方法用于。计算两个颜色之间的距离该方法的定义如下:
//计算与目标颜色的距离 int getDistance(const cv::Vec3b& color) const { return abs(color[0]-target[0])+abs(color[1]-target[1])+abs(color[2]-target[2]); };
下面是一个简单的主函数来运行这个颜色的检测算法:
int main() { //1.创建图像处理的对象 ColorDetector cdetect; //2.读取输入图像 cv::Mat image = imread("8.jpg"); if (!image.data) { cout << "picture read failure" << endl; return 0; } //设置输入参数 cdetect.setTargetColor(130, 190, 230); //图片的颜色 cv::namedWindow("result"); //处理并显示结果 cv::imshow("result", cdetect.process(image)); cv::waitKey(); return 0; }
程序代码如下:
#include<opencv2\core\core.hpp>
#include<opencv2\imgproc\imgproc.hpp>
#include<opencv2\highgui\highgui.hpp>
#include<iostream>
using namespace std;
using namespace cv;
class ColorDetector
{
public:
ColorDetector() :minDist(100)//空构造函数,创建类的实例,使他位于可用状态
{
target[0] = target[1] = target[2] = 0;//初始化默认参数
};
void setColorDistanceThreshold(int distance)//设置色彩距离阈值,阈值必须是正的,否则设为0
{
if (distance<0)
distance = 0;
minDist = distance;
};
int getColorDistanceThreshold() const//获取色彩距离阈值
{
return minDist;
};
void setTargetColor(unsigned char red,unsigned char green,unsigned char blue)//设置需要检测的颜色,三分量
{
target[0] = blue;
target[1] = green;
target[2] = red;
};
void setTargetColor(cv::Vec3b color)//设置需要检测的颜色的另一种方法,与上面作用一致,Vec3b直接定义为三分量
{
target = color;
};
cv::Vec3b getTargetColor() const//获取需要检测的颜色
{
return target;
};
//计算与目标颜色的距离
int getDistance(const cv::Vec3b& color) const
{
return abs(color[0] - target[0]) + abs(color[1] - target[1]) + abs(color[2] - target[2]);//累加分量差值的绝对值
};
cv::Mat process(const cv::Mat &image);//核心算法,在类外实现,这里的核心算法可以改
private:
int minDist;//最小可以接受距离
cv::Vec3b target;//目标色
cv::Mat result;//结果图
};
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 main()
{ //1.创建图像处理的对象
ColorDetector cdetect;
//2.读取输入图像
cv::Mat image = imread("8.jpg");
if (!image.data)
{
cout << "picture read failure" << endl;
return 0;
} //设置输入参数
cdetect.setTargetColor(130, 190, 230); //图片的颜色
cv::namedWindow("result"); //处理并显示结果
cv::imshow("result", cdetect.process(image));
cv::waitKey();
return 0;
}
原始图像:
运行结果:
转载:https://blog.csdn.net/weixin_39746114/article/details/81171694#commentBox