您的位置:首页 > 运维架构

OpenCV之彩色直方图反向投影(图像相似性检测)

2013-07-12 15:08 543 查看
        前面已经介绍了如何使用灰度直方图进行图像相似性检测的方法,但从测试结果来看结果并不令人满意,相关实现和测试结果请见另一篇Blog :http://blog.csdn.net/forthcriminson/article/details/8543781

       现在我们考虑利用图像的色彩信息来对其进行优化,简单的理解就是只有在图像3个通道都具有一定相似性的位置,才认为两者是相似的,利用OpenCV实现时,使用的核心函数与之前一样。

       我在实现时首先定义了两个类colorHist和contentFinder,具体实现见下:

colorHist类

[cpp] view
plaincopy

class colorHist{  

private:  

    int histSize[3];  

    float hranges[2];  

    const float * ranges[3];  

    int channels[3];  

    int dims;  

public:  

    colorHist(){  

        histSize[0]=256;  

        histSize[1]=256;  

        histSize[2]=256;  

        channels[0]=0;  

        channels[1]=1;  

        channels[2]=2;  

        hranges[0] = 0;  

        hranges[1] = 256;  

        ranges[0]=hranges;  

        ranges[1]=hranges;  

        ranges[2]=hranges;  

        dims=3 ;  

    }  

    Mat getColorHist(Mat image){  

        Mat result;  

        calcHist(&image,1,channels,Mat(),result,dims,histSize,ranges,true,false);  

        return result;  

    }  

  

};  

contentFinder类

[cpp] view
plaincopy

class contentFinder{  

private:  

    float hranges[2];  

    const float* ranges[3];  

    float th;  

    Mat  histogram;  

    int channels[3];  

    int dim;  

public:   

    contentFinder()  {  

        ranges[0]= hranges;   

        ranges[1]= hranges;  

        ranges[2]= hranges;  

        hranges[0] = 0;  

        hranges[1] = 256;  

        channels[0]=0;  

        channels[1]=1;  

        channels[2]=2;  

        dim = 3;  

        th = -1.0f;  

    }  

    void setThreshold(float t) {  

        th= t;  

    }  

    float getThreshold() {  

        return th;  

    }  

    void setHistogram(Mat h) {  

        histogram= h;  

        normalize(histogram,histogram,1.0);  

    }  

      

    Mat find(const Mat &image) {  

        Mat result;  

        for (int i=0; i<dim; i++)  

            this->channels[i]= channels[i];  

        calcBackProject(&image, 1, channels, histogram,result, ranges, 255.0,true);  

        if (th>0.0)  

            threshold(result, result,255*th, 255, THRESH_BINARY);  

        return result;  

    }  

  

};  

主程序为:

[cpp] view
plaincopy

#include "colorHist.h"  

#include "iostream"  

using namespace cv;  

using namespace std;  

  

int _tmain(int argc, _TCHAR* argv[])  

{     

    String imageName ="D:\\1.jpg";  

        Mat src =imread(imageName,1);  

    colorHist h;  

    int a=200;  

    int b=300;  

    int c=30;  

    int d=30;  

        Mat imageROI = src(Rect(a,b,c,d));  

    Mat hist = h.getColorHist(imageROI);  

    contentFinder finder;  

    finder.setHistogram(hist);  

    finder.setThreshold(0.05f);  

    Mat result= finder.find(src);  

    line(src,Point(a,b),Point(a,b+c),Scalar(0,0,255));  

    line(src,Point(a,b),Point(a+d,b),Scalar(0,0,255));  

    line(src,Point(a+d,b+c),Point(a,b+c),Scalar(0,0,255));  

    line(src,Point(a+d,b),Point(a+d,b+c),Scalar(0,0,255));  

    imshow("Source Image",src);  

    imshow("Color BackProject",result);  

    waitKey(0);  

    return 0;  

      

}  

运行结果为:





       从相似性检测的效果来看比前面使用的灰度直方图反响投影法要好得多,如果为了更加准确,去除图像中的那些孤立点,可以使用形态学运算中 的开运算来去除这些点,比较简单,这里就不讲代码粘贴上来了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  OpenCV 直方图