OpenCV4入门教程085:图像直方图反向投影
索引地址:系列索引
反向投影可以用来做图像分割,寻找感兴趣区间。它会输出与输入图像大小相同的图像,每一个像素值代表了输入图像上对应点属于目标对象的概率,简言之,输出图像中像素值越高的点越可能代表想要查找的目标。直方图投影经常与camshift(追踪算法)算法一起使用。
算法实现的方法,首先要为包含我们感兴趣区域的图像建立直方图(样例要找一片草坪,其他的不要)。被查找的对象最好是占据整个图像(图像里全是草坪)。最好使用颜色直方图,物体的颜色信息比灰度图像更容易被分割和识别。再将颜色直方图投影到输入图像查找目标,也就是找到输入图像中每一个像素点的像素值在直方图中对应的概率,这样就得到一个概率图像,最后设置适当的阈值对概率图像进行二值化。
这个过程可以笼统的说与计算图像直方图相反,由图像计算直方图的过程比较容易理解,就是统计图像中像素分布的概率,而反向投影正好反过来,是通过直方图来形成图像,其步骤有点类似于直方图均衡化,只不过直方图均衡化是将图像中的每个像素值由一个地方迁移到另外一个地方,而反向投影是直接去直方图中的值,如某种像素值在直方图中的值越大,在进行反向投影操作时其对应的像素值越大即月亮,反过来,如果某灰度值所占面积越小,其反向投影后像素值就会更小。
举个简单的例子来帮助理解这段话的意思。例如灰度图像的像素值如下如下:
1 |
|
对图像进行直方图统计(bin指定的区间为[0,3),[4,7),[8,11),[12,16))如下所示:
1 |
|
也就是说在[0,3)这个区间的像素值有4个,其它含义相同
根据上述的直方图进行反向投影,得到反向投影图像像素值如下:
1 |
|
例如位置(0,0)上的像素值为0,对应的bin为[0,3),所以反向直方图在该位置上的值这个bin的值4,而在位置(3,3)上的像素为15,其在直方图中的统计为2,故其反向投影图像中的像素为2。
函数原型:
1 |
|
参数解释:
- const Mat* images:输入图像,图像深度必须位CV_8U,CV_16U或CV_32F中的一种,尺寸相同,每一幅图像都可以有任意的通道数
- int nimages:输入图像的数量
- const int* channels:用于计算反向投影的通道列表,通道数必须与直方图维度相匹配,第一个数组的通道是从0到image[0].channels()-1,第二个数组通道从图像image[0].channels()到image[0].channels()+image[1].channels()-1计数
- InputArray hist:输入的直方图,直方图的bin可以是密集(dense)或稀疏(sparse)
- OutputArray backProject:目标反向投影输出图像,是一个单通道图像,与原图像有相同的尺寸和深度
- const float ranges**:直方图中每个维度bin的取值范围
- double scale=1:可选输出反向投影的比例因子
- bool uniform=true:直方图是否均匀分布(uniform)的标识符,有默认值true
测试代码:
1 |
|
测试结果: