策略模式在图像处理算法上面的应用

    策略设计模式的目标是将算法封装在类中。因此,可以更容易的替换一个现有的算法,或者组合使用多个算法以拥有更复杂的处理逻辑。此外,该模式将算法的复杂度隐藏在易用的编程接口背后,降低了算法的部署难度。比方说,我们构建一个简单的算法,他可以鉴别出图像中含有给定颜色的所有像素。该算法输入的是图像以及颜色,并返回表示含有指定颜色的像素的二值图像。该算法还需要指定对颜色偏差的容忍度。下面是算法的实现部分。

    头文件

#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])));

}

最终的运行的结果如下。显而易见,这个算法相对简单。当算法愈发复杂时,策略模式才能发挥出真正的威力,这样的算法设计许多步骤,并且拥有多个参数。

策略模式在图像处理算法上面的应用