关于直方图的反向投影,opencv中有两个函数cvCalcBackProject和cvCalcBackProjectPatch(),这两个函数的功能有点难以区别。简单点说:cvCalcBackProject是检测输入图像中的每个像素,然后查找该像素在直方图中的值,值越大,则输出图像中的对应像素灰度值就越大,即越亮,可以理解为输出图像是直方图中对应位置的值的大小。而直方图是由一幅模版图像计算得到的。可以把输出图像backproject理解为一个概率图。比如在模版图像中像素值BGR(0,0,255)的像素点很多,那么在求得的hist直方图中对应位置的值就越大(概率越大)。所以呢,如果对目标图使用backproject时,目标图中像素值等于BGR(0,0,255)的像素点的概率越大,表现为cvCalcBackProject得出结果中对应像素位置的灰度值大。可以看下面例子:
#include<cv.h>
#include<highgui.h>
#include<stdio.h>
int main(int argc,char *argv[])
{
cvNamedWindow("source");
cvNamedWindow("result");
IplImage *src = cvLoadImage(argv[1]);//用于查找的图像
IplImage *temp = cvLoadImage(argv[2]);//用于计算直方图的模版
IplImage * back_project = cvCreateImage(cvGetSize(src),8,1);//输出图像
IplImage *src_hsv = cvCreateImage(cvGetSize(src),8,3);
cvCvtColor(src,src_hsv,CV_BGR2HSV);
IplImage *src_h = cvCreateImage(cvGetSize(src),8,1);
IplImage *src_s = cvCreateImage(cvGetSize(src),8,1);
IplImage *src_v = cvCreateImage(cvGetSize(src),8,1);
cvSplit(src_hsv,src_h,src_s,src_v,NULL);
IplImage *src_plane[] = {src_h,src_s,src_v};
IplImage *temp_hsv = cvCreateImage(cvGetSize(temp),8,3);
cvCvtColor(temp,temp_hsv,CV_BGR2HSV);
IplImage *temp_h = cvCreateImage(cvGetSize(temp),8,1);
IplImage *temp_s = cvCreateImage(cvGetSize(temp),8,1);
IplImage *temp_v = cvCreateImage(cvGetSize(temp),8,1);
cvSplit(temp_hsv,temp_h,temp_s,temp_v,NULL);
IplImage *temp_plane[] = {temp_h,temp_s,temp_v};
int dims = 3;
int sizes[] = {30,32,32};
float h_range[] = {0,180};
float s_range[] = {0,255};
float v_range[] = {0,255};
float *ranges[] = {h_range,s_range,v_range};
CvHistogram * hist = cvCreateHist(dims,sizes,CV_HIST_ARRAY,ranges,1);
cvCalcHist(temp_plane,hist,0,NULL);
cvCalcBackProject(&src_plane,back_project,hist);
cvShowImage("source",src);
cvShowImage("result",back_project);
cvWaitKey(0);
return 0;
}
关于 cvCalcBackProjectPatch()见下篇博客分析。