反向投影图
参考自: http://blog.163.com/thomaskjh@126/blog/static/370829982010112810358501/
理解反向投影图的一篇不错的文章=
图像的反向投影图是用输入图像的某一位置上像素值(多维或灰度)对应在直方图的一个bin上的值来代替该像素值,所以得到的反向投影图是单通的。用统计学术语,输出图像象素点的值是观测数组在某个分布(直方图)下的概率。
其中b(xi)表示在位置xi上像素对应的直方图第b(xi)个bin,直方图共m个bin,qu表示第u个bin的值。
还是以例子说明
(1)例如灰度图像如下
Image=
0 1 2 3
4 5 6 7
8 9 10 11
8 9 14 15
(2)该灰度图的直方图为(bin指定的区间为[0,3),[4,7),[8,11),[12,16))
Histogram=
4 4 6 2(3)反向投影图
Back_Projection=
4 4 4 4
4 4 4 4
6 6 6 6
6 6 2 2
例如位置(0,0)上的像素值为0,对应的bin为[0,3),所以反向直方图在该位置上的值这个bin的值4。
(测试代码在 OpenCV2.0+vs2008下面测试通过)
#include "highgui.h" #include "cv.h" #include "cxcore.h" #include "cvaux.h" #include "stdio.h" #pragma comment(lib, "highgui200.lib") #pragma comment(lib, "cv200.lib") #pragma comment(lib, "cxcore200.lib") #pragma comment(lib, "cvaux200.lib") int main() { uchar data[]={0,1,2,3,4,5,6,7,8,9,10,11,8,9,14,15}; CvMat mat =cvMat(4,4,CV_8UC1,data); IplImage g_img; cvGetImage(&mat,&g_img); //打印图像数据 printf("Image\n"); for(int i=0;i<g_img.height;i++) { uchar* ptr = (uchar*)(g_img.imageData+i*g_img.widthStep); for(int j=0;j<g_img.width;j++) printf("%d ",(int)ptr[j]); printf("\n"); } //计算图像直方图 IplImage* imgs[]={&g_img}; int g_bin=4; int size[]={g_bin}; float g_ranges[]={0,4,8,12,16}; float* ranges[]={g_ranges}; CvHistogram* hist = cvCreateHist(1,size,CV_HIST_ARRAY,ranges,0); cvCalcHist(imgs,hist); printf("Histogram\n"); for(int i=0;i<g_bin;i++) printf("%d ",(int)(*cvGetHistValue_1D(hist,i))); printf("\n"); //计算反向投影图 IplImage* back_project = cvCreateImage(cvGetSize(&g_img),g_img.depth,1); cvCalcBackProject(imgs,back_project,hist); printf("Back_projection\n"); for(int i=0;i<back_project->height;i++) { uchar* ptr = (uchar*)(back_project->imageData+i*back_project->widthStep); for(int j=0;j<back_project->width;j++) printf("%d ",ptr[j]); printf("\n"); } return 0; }