OpenCV  4.10.0
开源计算机视觉库
正在加载...
正在搜索...
没有匹配项
均值漂移和CamShift

上一教程: 如何使用背景减除方法
下一教程: 光流

目标

在本章中,

  • 我们将学习均值漂移和CamShift算法,用于在视频中跟踪物体。

均值漂移

均值漂移背后的直觉很简单。假设你有一组点。(它可以是像直方图反投影这样的像素分布)。给你一个小的窗口(可能是一个圆形),你需要将这个窗口移动到像素密度最大(或点数最多)的区域。下图简单地展示了这个过程。

图像

初始窗口显示为蓝色圆圈,名为“C1”。其原始中心用蓝色矩形标记,名为“C1_o”。但是,如果你找到该窗口内点的质心,你将得到点“C1_r”(用小蓝色圆圈标记),它就是窗口的实际质心。显然它们并不匹配。因此,将你的窗口移动,使得新窗口的圆圈与之前的质心匹配。再次找到新的质心。很可能,它不会匹配。所以再次移动它,并继续迭代,直到窗口的中心及其质心落在同一个位置(或在小的期望误差范围内)。因此,你最终得到的是一个具有最大像素分布的窗口。它用绿色圆圈标记,名为“C2”。如你在图中看到的,它包含最多的点。下面的静态图像演示了整个过程

图像

因此,我们通常传递直方图反投影图像和初始目标位置。当物体移动时,显然移动会反映在直方图反投影图像中。因此,均值漂移算法将我们的窗口移动到具有最大密度的新的位置。

OpenCV 中的均值漂移

要在 OpenCV 中使用均值漂移,首先我们需要设置目标,找到它的直方图,以便我们可以将目标反投影到每一帧上,用于计算均值漂移。我们还需要提供窗口的初始位置。对于直方图,这里只考虑色调。此外,为了避免由于弱光造成的错误值,使用 cv.inRange() 函数来丢弃弱光值。

我在视频中使用的三帧如下图所示

图像

连续自适应均值漂移

你仔细观察最后一个结果了吗?存在一个问题。无论汽车距离摄像头很远还是很近,我们的窗口始终保持相同的大小。这不好。我们需要根据目标的大小和旋转来调整窗口的大小。再次,解决方案来自“OpenCV Labs”,它被称为 CAMshift(连续自适应均值漂移),由 Gary Bradsky 在 1998 年的论文“用于感知用户界面的计算机视觉人脸跟踪”中发表 [39]

它首先应用均值漂移算法。均值漂移算法收敛后,它会更新窗口的大小,\(s = 2 \times \sqrt{\frac{M_{00}}{256}}\)。它还会计算最适合它的椭圆的方向。它再次使用新的缩放搜索窗口和之前的窗口位置应用均值漂移算法。该过程会持续进行,直到满足所需的精度为止。

图像

OpenCV 中的连续自适应均值漂移

它类似于均值漂移算法,但会返回一个旋转的矩形(即我们的结果)和框参数(用作下一迭代中的搜索窗口)。请查看以下代码

结果的三帧如下图所示

图像

其他资源

  1. 维基百科法语页面介绍了 连续自适应均值漂移。 (两个动画来自该页面)
  2. Bradski, G.R., "Real time face and object tracking as a component of a perceptual user interface," Applications of Computer Vision, 1998. WACV '98. Proceedings., Fourth IEEE Workshop on , vol., no., pp.214,219, 19-21 Oct 1998

练习

  1. OpenCV 附带一个 Python 示例,用于演示连续自适应均值漂移算法的交互式演示。使用它,修改它,理解它。