【第22节】直方图反投影
目标
本节我们将要学习直方图反向投影
原理
直方图反向投影是由Michael J. Swain和Dana H. Ballard在他们的文章"Indexing via color histograms"中提出。那它到底是什么呢?它可以用来做图像分割,或者在图像中找寻我们感兴趣的部分。简单来说,它会输出与输入图像(待搜索)同样大小的图像,其中的每一个像素值代表了输入图像上对应点属于目标对象的概率。用更简单的话来解释,输出图像中像素值越高(越白)的点就越可能代表我们要搜索的目标(在输入图像所在的位置)。这是一个直观的解释。直方图投影经常与camshift算法等一起使用。
我们应该怎样来实现这个算法呢?首先我们要为一张包含我们要查找目标的图像创建直方图(在我们的示例中,我们要查找的是蓝色圆圈,其他的都不要)。 .我们要查找的对象要尽量占满这张图像(换句话说,这张图像上最好是有且仅有我们要查找的对象)。最好使用颜色直方图,因为一个物体的颜色要比它的灰度能更好的被用来进行图像分割与对象识别。接着我们再把这个颜色直方图投影到输入图像中寻找我们的目标,也就是找到输入图像中的每一个像素点的像素值在直方图中对应的概率,这样我们就得到一个概率图像,最后设置适当的阈值对概率图像进行二值化,就这么简单。
1、Numpy中的算法
此处的算法与上边介绍的算法稍微不同。
首先,我们要创建两幅颜色直方图,目标图像的直方图('M')(待搜索),输入图像的直方图('I')。
计算比值:R=M/I。反向投影R,也就是根据R这个”调色板“创建一副新的图像,其中的每一个像素代表这个点就是目标的概率。例如B(x,y) =R[h(x,y),s(x,y)],其中h为点(x, y)处的hue值,s为点(x, y)处的saturation值。最后加入再一个条件 B (x,y) = min [B (x,y),1]。
现在使用一个圆盘算子做卷积,B = D × B,其中D为卷积核。
现在输出图像中灰度值最大的地方就是我们要查找的目标的位置了。如果我们要找的是一个区域,我们就可以使用一个阈值对图像进行二值化,这样就可以得到一个很好的结果了。
2、OpenCV中反向投影
OpenCV提供的函数CV2.calcBackProject() 可以用来做直方图反向投影。它的参数与函数CV2.calcHist的参数基本相同。其中的一个参数是我们要查找目标的直方图。同样再使用目标的直方图做反向投影之前我们应该先对其做归一化处理。返回的结果是-个概率图像,我们再使用一个圆盘形卷积核对其做卷操作,最后使用阈值进行二值化。下面就是代码和结果:
下面是我是用的一幅图像,我是用蓝色小球作为取样对象,在根据这个样本搜索图中所有的类似区域。
