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

来源:互联网 发布:淘宝竹月阁 编辑:程序博客网 时间:2024/04/30 01:33
转自:http://blog.csdn.net/forthcriminson/article/details/8543781
直方图方向投影基本原理:

现有两张图像,均为灰度图像,其中一张图像尺寸大于等于另一张,其中尺寸较大的图像作为查询图像,另一张为模板图像,直方图反向投影变换的基本原理是:

(1)从尺寸较大的图像的左上角(0,0)开始,切割一块与较小图像尺寸一致的临时图像;
(2)计算临时图像的直方图;
(3)用临时图像的直方图和尺寸较小的图像的直方图对比,对比结果记为c;
(4)直方图对比结果c,就是结果图像(0,0)处的像素值;
(5)逐个像素移动进行图像切割,对比直方图,并记录直方图对比结果;
(6)重复(1)~(5)步直到输入图像的右下角。
需要注意的地方:

(1) 需要在代码实现中加入对图像尺寸大小的判断,如果模版图像尺寸小于查找图像,则程序正常执行,如果等于,这相当于进行直方图比较,如果大于,则应该提示程序无法正常执行

(2)此算法执行效率较低,在使用之前尤其需要注意图像的大小,直方图的维数,对比方式,在计算之前可以考虑对图像进行ColorReduce。

代码如下:

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
using namespace cv;
using namespace std;
int _tmain(int argc, _TCHAR* argv[])

String imageName ="D:\\1.jpg";
Mat src = imread(imageName,1);
Mat src1 = imread(imageName,0);
Hist1D h;
Mat result;
//参考图像左上角顶点坐标
int a=200;
int b=300;
//参考图像宽度、高度
int c=30;
int d=30;
//选择区域参考图像
Mat imageROI = src1(Rect(a,b,c,d));

//在原始图像上绘制所选择的参考图像,方便进行算法执行效果对比 
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));
float hrange[]={0,256};
const float *ranges ={hrange};
int channles = 0;
calcHist(&image,1,channels,Mat(),hist,1,256,&ranges,true,false);

normalize(hist,hist,1.0);

calcBackProject(&src1,1,0,hist,result,&ranges,255,true);
threshold(result,result,255*0.05,255,THRESH_BINARY);
imshow("Source Image",src);
imshow(" BackProject",result1);
waitKey(0);
return 0; 
}

运行结果为:

可以看出其相似性检测效果很差,这主要是由于没有利用上图像的颜色信息,后续将会考虑对其进行改进。