策略模式在图像处理算法上面的应用
策略设计模式的目标是将算法封装在类中。因此,可以更容易的替换一个现有的算法,或者组合使用多个算法以拥有更复杂的处理逻辑。此外,该模式将算法的复杂度隐藏在易用的编程接口背后,降低了算法的部署难度。比方说,我们构建一个简单的算法,他可以鉴别出图像中含有给定颜色的所有像素。该算法输入的是图像以及颜色,并返回表示含有指定颜色的像素的二值图像。该算法还需要指定对颜色偏差的容忍度。下面是算法的实现部分。
头文件
#ifndef COWISCOLORDETECTOR_H
#define COWISCOLORDETECTOR_H
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgcodecs.hpp>
using namespace cv;
class CowisColorDetector
{
public:
CowisColorDetector();
cv::Mat process(const cv::Mat& image);
void setColorDistanceThreshold(int distance);
int getColorDistanceThreshold(void)const;
void setTargetColor(unsigned char red, unsigned char green, unsigned char blue);
void setTargetColor(Vec3b color);
cv::Vec3b getTargetColor(void);
private:
int getDistance(const cv::Vec3b& color)const;
private:
int minDist;
cv::Mat result;
cv::Vec3b target;
};
#endif // COWISCOLORDETECTOR_H
实现文件
#include "cowiscolordetector.h"
CowisColorDetector::CowisColorDetector()
{
minDist = 100;
target[0] = target[1] = target[2] = 0;
}
Mat CowisColorDetector::process(const 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;
}
void CowisColorDetector::setColorDistanceThreshold(int distance)
{
if(distance < 0)
{
distance = 0;
}
minDist = distance;
}
int CowisColorDetector::getColorDistanceThreshold() const
{
return minDist;
}
void CowisColorDetector::setTargetColor(unsigned char red, unsigned char green, unsigned char blue)
{
target[2] = red;
target[1] = green;
target[0] = blue;
}
void CowisColorDetector::setTargetColor( Vec3b color)
{
target = color;
}
Vec3b CowisColorDetector::getTargetColor()
{
return target;
}
int CowisColorDetector::getDistance(const Vec3b &color) const
{
return static_cast<int>(cv::norm<int, 3>(cv::Vec3i(color[0] - target[0],
color[1] - target[1],
color[2] - target[2])));
}
最终的运行的结果如下。显而易见,这个算法相对简单。当算法愈发复杂时,策略模式才能发挥出真正的威力,这样的算法设计许多步骤,并且拥有多个参数。