OpenCV学习笔记(2):直方图的反向投影

直方图的反向投影
    现在说说直方图的反向投影,我觉得这是直方图中最难的部分,我看了跟cvCalcBackProjectPatch相关的读书章节、中文参考及英文帮助,还是不明白......而网上居然没有使用cvCalcBackProjectPatch的例程(当然本文写成之后就有例程了)。前天晚上在半梦半醒之间进入了冥想状态,突然开窍了,然而在试验的时候还是遇到了不少问题。
1.反向投影的作用是什么?
    反向投影用于在输入图像(通常较大)中查找特定图像(通常较小或者仅1个像素,以下将其称为模板图像)最匹配的点或者区域,也就是定位模板图像出现在输入图像的位置。
2.反向投影如何查找(工作)?
    查找的方式就是不断的在输入图像中切割跟模板图像大小一致的图像块,并用直方图对比的方式与模板图像进行比较。

假设我们有一张100x100的输入图像,有一张10x10的模板图像,查找的过程是这样的:
(1)从输入图像的左上角(0,0)开始,切割一块(0,0)至(10,10)的临时图像;
(2)生成临时图像的直方图;
(3)用临时图像的直方图和模板图像的直方图对比,对比结果记为c;
(4)直方图对比结果c,就是结果图像(0,0)处的像素值;
(5)切割输入图像从(0,1)至(10,11)的临时图像,对比直方图,并记录到结果图像;
(6)重复(1)~(5)步直到输入图像的右下角。

 

(本图片引用自http://www.opencv.org.cn)
3.反向投影的结果是什么?
    反向投影的结果包含了:以每个输入图像像素点为起点的直方图对比结果。可以把它看成是一个二维的浮点型数组,二维矩阵,或者单通道的浮点型图像。
4.特殊情况怎么样?
    如果输入图像和模板图像一样大,那么反向投影相当于直方图对比。如果输入图像比模板图像还小,直接罢工~~。
5.使用时有什么要注意的地方?
    需要注意的地方比较多,我们对照反向投影函数来说:
    void cvCalcBackProjectPatch(
        IplImage** image,   /*输入图像:是一个单通道图像数组,而非实际图像*/
        CvArr* dst,         /*输出结果:是一个单通道32位浮点图像,它的宽度为W-w+1,高度为H-h+1,这里的W和H是输入图像的宽度和高度,w和h是模板图像的宽度和高度*/
        CvSize patch_size,  /*模板图像的大小:宽度和高度*/
        CvHistogram* hist,  /*模板图像的直方图:直方图的维数和输入图像的个数相同,并且次序要一致;例如:输入图像包含色调和饱和度,那么直方图的第0维是色调,第1维是饱和度*/
        int method,         /*对比方式:跟直方图对比中的方式类似,可以是:CORREL(相关)、CHISQR(卡方)、INTERSECT(相交)、BHATTACHARYYA*/
        float factor        /*归一化因子,一般都设置成1,否则很可能会出错;中文、英文以及各路转载的文档都错了,这个参数的实际类型是double,而非float,我看了源代码才搞定这个地方*/
    );
    还有最需要注意的地方:这个函数的执行效率非常的低,在使用之前尤其需要注意图像的大小,直方图的维数,对比方式。如果说对比单个直方图对现在的电脑来说是清风拂面,那么反向投影是狂风海啸。对于1010x1010的RGB输入图像,10x10的模板图像,需要生成1百万次3维直方图,对比1百万次3维直方图。
直方图反向投影的示例如下:

计算直方图的反向投影   OpenCV学习笔记(2):直方图的反向投影_第1张图片

在左图(输入图像)中查找特定人脸(模板图像),结果如右图,中间亮白色的区域为最匹配区域 

 

 

 

转自:http://www.cnblogs.com/xrwang/archive/2010/02/04/HowToUseHistogram.html

你可能感兴趣的:(OpenCV学习笔记(2):直方图的反向投影)