实现图像处理算法中采用策略“Strategy”模式+Qt中相对路径

来源:互联网 发布:js连接mysql数据库 编辑:程序博客网 时间:2024/06/05 16:56

最近刚刚开始看《设计模式》,刚好最近也在从头开始OpenCV2,里面有讲到在图像算法设计中采用策略模式,照着例子实现了这个小demo,一下子明白所谓的策略模式倒底是个什么东东,这里mark一下。

策略模式(Strategy),用原书中的定义是:定义一系列的算法,把他们一个个的封装起来,并且是他们可以相互替换(相互替换这点还没有完全体会到)。这样算法的变换便可以独立于使用它的对象。用我直白的话说就是,把对一个对象(Context)进行处理的各种算法,封装到另外一个对象(Strategy)里面,这样我们便可以专注于Strategy,而不用担心修改算法的同时会对Context造成影响,只要这个Strategy还没有对Context起作用,我们对Strategy的改动都不会影响到Context,在实现的过程中省了好多心。

下面是一个小demo:

具体到这个demo中Strategy的实现是将对Mat(图片)处理的函数统统封装到一个类中,这里讲类中成员函数的声明和实现写在了一起。

///////////////////////////////////////////////////////////由strategy思想构造一个类//类名:ColorDetector//主要目的:检测一幅图像中是否存在目标颜色/////////////////////////////////////////////////////////#ifndef STRATEGY#define STRATEGY#endif // STRATEGY#include<opencv2/opencv.hpp>//#include<opencv2/highgui/highgui.hpp>//#include<opencv2/core/mat.hpp>using namespace std;using namespace cv;class ColorDetector{public:    //空构造函数    ColorDetector():minDist(100){        //初始化默认参数        target[0]=target[1]=target[2]=0;    }public:    //设置色彩阈值,阈值必须大于等于0    void setColorDistanceThreshold(int distance){        if(distance<0)            distance=0;        minDist=distance;    }    //获取色彩阈值    int getColorDistanceThreshold() const{        return minDist;    }    //设置需要检测的颜色    void setTargetColor(unsigned char red,unsigned char green,unsigned blue)    {        //BGR的顺序        target[2]=red;        target[1]=green;        target[0]=blue;    }    //设置需要检测的颜色    void setTargetColor(Vec3b color){        target=color;    }    //获取要检测的色彩值    Vec3b getTargetColor() const{        return target;    }    //计算目标与颜色的距离    int getDistance(const Vec3b &color)const{        return abs(color[0]-target[0])+abs(color[1]-target[1])+abs(color[2]-target[2]);    }    //检测目标颜色,并输出检测生成的图像    Mat process(const Mat &image){        //按需从新分配二值图像与输入图像尺寸相同,        result.create(image.size(),CV_8U);        //得到迭代器        Mat_<Vec3b>::const_iterator it=image.begin<Vec3b>();        Mat_<Vec3b>::const_iterator itend=image.end<Vec3b>();        Mat_<uchar>::iterator itout=result.begin<uchar>();        //检测每个像素        for(;it!=itend;++it,++itout)        {            if(getDistance(*it)<minDist)                *itout=255;            else                *itout=0;        }        return result;    }private:    //最小可接受距离    int minDist;    //目标色    Vec3b target;    //结果图像    Mat result;};

封装好之后我们便能对调用它了,下面是调用Strategy类的实现:

#include <QCoreApplication>#include "strategy.h"#include<opencv2/opencv.hpp>#include<QString>#include<QDir>#include<QDebug>using namespace cv;using namespace std;int main(){    //创建图像处理对象    ColorDetector cdetector;    //Qt中当前路径显示    QDir dir;    QString pathname;    pathname = dir.currentPath();    qDebug()<<pathname;        //读入图像    Mat image=imread("./resource/images/lena.jpg");    //Mat image=imread(path.toStdString().data());    if(!image.data)        return -1;    //设置输入参数    cdetector.setTargetColor(130,190,230);    namedWindow("result");    //处理并显示结果    imshow("result",cdetector.process(image));    waitKey();    return 0;}
最后说一下Qt中相对路径的问题,相对路径是相对工程根目录而言的,表达的格式是:“./resource/images/lena.jpg”,即在工程的根目录下有一个resource文件夹,resource内部有一个images文件夹,images内部有这幅图像lena.jpg。一开始我是将这幅图像放在了最开始建立工程时的文件夹下,发现找不到图片,其实Qt在build的过程中会根据是否勾选shadow build这一选项创建一个新的执行文件的目录。


Shadow build是否勾选,构建目录是不一样的,将resource文件夹复制到构建目录下面。OK  运行成功!

0 0