作者介绍:Satya Mallick,擅长领域为计算机视觉,机器学习,人工智能。
Linkdin:https://www.linkedin.com/in/satyamallick/zh-cn
在本教程中,我们将了解OpenCV 3.0中引入的OpenCV跟踪API。 我们将学习如何以及何时使用OpenCV 3.2中提供的6种不同的跟踪器- BOOSTING,MIL,KCF,TLD,MEDIANFLOW和GOTURN。 我们还将学习现代跟踪算法背后的基本理论。
简单地说,在视频的连续帧中定位对象被称为跟踪。
定义听起来很直接,但在计算机视觉和机器学习中,跟踪是一个非常宽泛的术语,涵盖概念上类似但技术上不同的理念。 例如,通常在对象跟踪下研究所有以下不同但相关的理念:
1.密集光流:这些算法有助于估计视频帧中每个像素的运动矢量。
2.稀疏光流:这些算法跟踪图像中几个特征点的位置,如Kanade-Lucas-Tomashi(KLT)特征跟踪器。
3.卡尔曼滤波:用于非常流行的基于先前运动信息来预测运动对象的位置的信号处理算法。 这种算法的早期应用之一是导弹指导! 正如这里所提到的,“引导阿波罗11月球模块下降到月球的车载计算机具有卡尔曼滤波器”。
4.MeanShift算法和CamShift定位:这是一个密度函数的最大值的算法。它们也用于跟踪。
5.单个对象跟踪器:在此类跟踪器中,第一帧使用矩形标记,以指示要跟踪的对象的位置。 然后使用跟踪算法在随后的帧中跟踪对象。 在大多数现实生活应用中,这些跟踪器与对象检测器结合使用。
6.多目标跟踪算法:在我们有一个快速目标探测器的情况下,有意义的是检测每个帧中的多个目标,然后运行轨迹找到算法,识别一个帧中的哪个矩形对应于下一个帧中的矩形。
如果你曾经使用过OpenCV的脸部检测,你知道它是实时工作,你可以很容易地检测到每一帧的脸。 那么,为什么需要跟踪在第一个地方? 让我们来探索你可能要跟踪的视频中的对象的不同原因,而不仅仅是重复检测。
1.跟踪速度比检测快:通常跟踪算法比检测算法快。原因很简单。当你跟踪在上一帧中检测到的对象时,你会非常了解对象的外观。你也知道在前一帧中的位置和它的运动的方向和速度。因此,在下一帧中,您可以使用所有这些信息来预测下一帧中对象的位置,并对对象的预期位置进行小型搜索,以准确定位对象。良好的跟踪算法将使用其关于对象的所有信息直到那一点,而检测算法总是从头开始。因此,在设计有效系统时,通常在每n帧上运行对象检测,而在其间的n-1帧中采用跟踪算法。为什么我们不是简单地检测第一帧中的对象并跟踪?实际上,跟踪从附加信息中获益,但是当它们在一个障碍物后面延长一段时间或者它们移动得如此之快以致跟踪算法不能赶上时,也可能失去对物体的跟踪。跟踪算法累积误差也是常见的,并且跟踪对象的边界框慢慢地偏离它跟踪的对象。为了解决跟踪算法中的这些问题,检测算法每隔一段时间运行一次。在对象的大量示例上训练检测算法。因此,它们对对象的一般类有更多的了解。另一方面,跟踪算法更多地了解它们正在跟踪的类的特定实例。
2.当检测失败时跟踪可以起到帮助作用:如果你正在一个视频上运行一个面部检测器,人的面部被一个对象遮挡,面部检测器很可能失败。 另一方面,良好的跟踪算法将处理某种程度的遮挡。
3.跟踪保留身份:对象检测的输出是包含对象的矩形数组。 但是,没有标识附加到对象。 例如,检测红点的检测器将输出与其在帧中检测到的所有点相对应的矩形。 在下一帧中,它将输出另一个矩形数组。 在第一帧中,特定点可以由矩阵在阵列中的位置10处表示,并且在第二帧中,其可以在位置17.当在帧上使用检测时,我们不知道哪个矩形对应于哪个对象。 另一方面,跟踪提供了一种方式来连接点。
OpenCV 3提供了一个新的跟踪API,包含许多单个对象跟踪算法的实现。 OpenCV 3.2 - BOOSTING,MIL,KCF,TLD,MEDIANFLOW和GOTURN有6种不同的跟踪器。
注意:OpenCV 3.1具有这5个跟踪器的实现--BOOSTING,MIL,KCF,TLD,MEDIANFLOW。 OpenCV 3.0具有以下4个跟踪器的实现:BOOSTING,MIL,TLD,MEDIANFLOW。
在我们提供算法的简要描述之前,让我们看看设置和用法。 在下面的注释代码中,我们首先通过选择跟踪器类型(BOOSTING,MIL,KCF,TLD,MEDIANFLOW或GOTURN)设置跟踪器。 然后我们打开一个视频,抓住一个框架。 我们定义一个包含第一帧对象的边界框,并用第一个框架和边界框初始化跟踪器。 最后,我们从视频中读取帧,并且只是在循环中更新跟踪器以获得当前帧的新的边界框。 随后显示结果。
在本节中,我们将挖掘一些不同的跟踪算法。我们的目标不是对每一个跟踪器有深刻的理论理解,而是从实际的角度来理解它们。
首先先解释一下跟踪的一些基本原理。在跟踪中,我们的目标是在当前帧中找到一个对象,因为我们已经在所有(或几乎所有)先前帧中成功跟踪了对象。
由于我们已经跟踪对象直到当前帧,我们知道它是如何移动的。 换句话说,我们知道运动模型的参数。 运动模型指你知道的对象在之前的帧中的位置和速度(速度+运动方向)。 如果你对对象没有其他了解,你可以根据当前的运动模型预测新位置,并且你将非常接近对象的新位置。
但是我们有更多关于对象运动的信息。 我们知道对象在每个先前帧中的外观。 换句话说,我们可以构建一个外观模型来编码对象的外观。 该外观模型可以用于在由运动模型预测的位置的小邻域中搜索,以更精确地预测对象的位置。
运动模型预测对象的大致位置。 外观模型微调这个估计以基于外观提供更准确的估计。
如果对象很简单,没有改变它的外观很多,我们可以使用一个简单的模板作为外观模型,并寻找那个模板。 然而,现实生活不是那么简单。 对象的外观可能会发生巨大变化。 为了解决这个问题,在许多现代跟踪器中,该外观模型是以在线方式训练的分类器。
分类器的工作是将图像的矩形区域分类为对象或背景。 分类器接受图像补丁作为输入,并返回0和1之间的分数,以指示图像补丁包含对象的概率。 当绝对确定图像补丁是背景时,分数为0,当绝对确定补丁是对象时,分数为1。
在机器学习中,我们使用“在线”这个词来指代在运行时在运行中训练的算法。 离线分类器可能需要数千个示例来训练分类器,但是在运行时通常使用非常少的示例训练在线分类器。
分类器通过馈送正(对象)和负(背景)示例来训练。 如果你想建立一个分类器来检测猫,你训练它与成千上万包含猫的图像和数千不包含猫的图像。 这样分类器学习区分什么是猫和什么不是猫。 你可以在这里了解有关图像分类的更多信息。 在建立在线分类器时,我们没有成千上万的正和负的例子。
让我们来看看不同的跟踪算法如何处理这个在线训练问题。
此跟踪器基于AdaBoost的在线版本 - 基于HAAR级联的面部检测器在内部使用的算法。 这个分类器需要在运行时用对象的正和负例子训练。 由用户提供的初始边界框(或由另一个对象检测算法)作为对象的正例,并且边界框外部的许多图像补片被当作背景。 给定新帧,对先前位置的邻域中的每个像素运行分类器,并记录分类器的得分。 对象的新位置是得分最大的位置。 所以现在我们有一个更积极的例子为分类器。 随着更多的帧进入,分类器用该附加数据更新。
优点:无。 这个算法是十年前并且可以运用,但我找不到一个很好的理由使用它,特别是当其他高级跟踪器(MIL,KCF)基于类似的原理可用。
缺点:跟踪性能平庸。
此跟踪器在概念上类似于上述的BOOSTING跟踪器。 最大的区别在于,代替仅考虑对象的当前位置作为积极示例,它在当前位置周围的小邻域中查找以生成若干潜在的正例子。 你可能认为这是一个坏主意,因为在大多数这些“积极”的例子中,对象不是中心。
在MIL中,你没有指定正和负例子,但是有正和负“包”。 正包中的图像集合并不都是积极的例子。 相反,只有一个图像在积极的包里需要一个积极的例子。在我们的示例中,正包包含以对象的当前位置为中心的补丁,以及在其周围的小邻域中的补丁。 即使被跟踪对象的当前位置不准确,当来自当前位置的邻域的样本被放入正包中时,很有可能这个包包含至少一个图像,其中对象被良好地置于居中。
优点:性能相当不错。 它不像BOOSTING跟踪器那样漂移,它在部分遮挡下合理地工作。如果你使用OpenCV 3.0,这可能是你可用的最好的跟踪。 但是如果你使用更高版本,考虑KCF。
缺点:跟踪失败报告不可靠。不能从完全闭塞恢复。
KFC代表内核化相关滤波器。 这个跟踪器建立在前两个跟踪器提出的想法。 该跟踪器利用了这样的事实,即在MIL跟踪器中使用的多个正样本具有大的重叠区域。 这种重叠的数据导致一些良好的数学特性,利用这个跟踪器,使跟踪更快,同时更准确。
优点:准确度和速度都比MIL更好,它报告跟踪失败比BOOSTING和MIL更好。 如果您使用OpenCV 3.1和更高版本,我建议对于大多数应用程序使用这个。
缺点:不能从完全闭塞恢复。 未在OpenCV 3.0中实现。
Bug警告:在OpenCV 3.1(仅限Python)中有一个错误,因为返回了不正确的边界框。 参见错误报告。
TLD代表跟踪,学习和检测。 顾名思义,该跟踪器将长期跟踪任务分解为三个组件 - (短期)跟踪,学习和检测。 从作者的论文,“跟踪器跟踪对象从一帧到帧。 检测器定位到目前为止观察到的所有外观,并在必要时校正跟踪器。 学习估计检测器的错误并更新它以避免未来的这些错误。“这个跟踪器的输出往往会跳一下。 例如,如果你正在跟踪行人,并且场景中还有其他行人,则该跟踪器有时可以临时跟踪与您要跟踪的行人不同的行人。 在积极的一面,这条轨道似乎在更大的规模,运动和遮挡下跟踪物体。 如果你有一个视频序列,其中的对象隐藏在另一个对象后面,这个跟踪器可能是一个不错的选择。
优点:在多个帧的遮挡下工作最好。 此外,跟踪最佳的规模变化。
缺点:很多误报,使它几乎不可用。
在内部,该跟踪器在时间上向前和向后方向上跟踪对象,并且测量这两个轨迹之间的差异。 最小化该ForwardBackward错误使它们能够可靠地检测跟踪失败并在视频序列中选择可靠的轨迹。
在我的测试中,我发现这个跟踪器在运动是可预测和小规模的时候效果最好。 与其他跟踪器不同,即使跟踪明显失败,该跟踪器知道跟踪失败的时间。
优点:优秀的跟踪失败报告。 当运动是可预测的并且没有遮挡时工作得很好。
缺点:在大规模运动下失败。
在跟踪器类中的所有跟踪算法中,这是基于卷积神经网络(CNN)的唯一一种。 它也是唯一一个使用离线训练模型,因为它比其他跟踪器更快。 从OpenCV文档,我们知道它“对视点变化,照明变化和变形是强大的”。 但它不能很好地处理遮挡。
Bug警告:不幸的是,在写这篇文章的时候,在使用Goturn时有一个错误在OpenCV 3.2实现使程序崩溃。
数十款阿里云产品限时折扣中,赶紧点击领劵开始云上实践吧!
以上为译文
本文由北邮@爱可可-爱生活 老师推荐,阿里云云栖社区组织翻译。
文章原标题《Object Tracking using OpenCV (C++/Python)》,作者:Satya Mallick,译者:tiamo_zn
文章为简译,更为详细的内容,请查看原文