从直方图曲线中选择最佳值范围

Abi*_*n K 7 python opencv image-processing histogram computer-vision

场景:

我试图跟踪两个不同的彩色物体.开始时,提示用户将第一个彩色对象(例如,可能是红色)保持在相机前面的特定位置(在屏幕上用矩形标记)并按任意键,然后我的程序获取该部分帧(ROI)并分析其中的颜色,找到要跟踪的颜色.同样对于第二个对象也.然后像往常一样,cv.inRange在HSV颜色平面中使用函数并跟踪对象.

做了什么:

我获取了要跟踪的对象的ROI,将其转换为HSV并检查了Hue直方图.我有两个案例如下:

在此输入图像描述 在此输入图像描述

(这里只有一个主要的中心峰值.但在某些情况下,我得到两个这样的峰值,一个是一个更大的峰值,周围有一些像素簇,第二个峰值,比第一个峰值小,但是周围有小簇的显着大小我现在没有它的样本图像.但它几乎看起来像下面(在油漆中创建))

在此输入图像描述

题 :

How can I get best range of hue values from these histograms?

我的意思是,最好的范围可能是ROI中大约80-90%的像素位于该范围内.

或者有没有比这更好的方法来跟踪不同颜色的物体?

Mát*_*ond 3

如果我理解正确的话,这里唯一需要的就是找到图中的最大值,其中最大值不一定是最高峰,而是密度最大的区域。

这是一个非常简单的不太科学但快速的 O(n) 方法。通过低通滤波器运行直方图。例如移动平均线。假设平均值的长度可以是 20。在这种情况下,新修改的直方图的第 10 个值将是:

mh10 = (h1 + h2 + ... + h20) / 20
Run Code Online (Sandbox Code Playgroud)

其中 h1、h2... 是直方图中的值。下一个值:

mh11 = (h2 + h3 + ... + h21) / 20
Run Code Online (Sandbox Code Playgroud)

使用之前计算的 mh10 可以更容易地计算它,方法是删除它的第一个组件并在末尾添加一个新组件:

mh11 = mh10 - h1/20 + h21/20
Run Code Online (Sandbox Code Playgroud)

您唯一的问题是如何处理直方图边缘的数字。您可以将移动平均线的长度缩短到可用长度,或者可以在已有的值之前和之后添加值。但无论哪种方式,你都无法在边缘处理峰值。

最后,当你有了这个修改后的直方图时,只需获取最大值即可。这是可行的,因为现在直方图中的每个值不仅包含其自身,还包含其邻居。

更复杂的方法是使用高斯曲线等对平均值进行加权。但这不再是线性的。它将是 O(k*n),其中 k 是平均值的长度,也是高斯的长度。