多目标跟踪大致有两种方式:Option1是基于初始化帧跟踪,在视频第一帧选择你的目标,然后手它交给跟踪算法Trackingofgoalsachievement。这种方法基本上只能跟踪你在第一帧选择的目标。如果在后续帧中出现新的物体目标,算法将无法对其进行跟踪。这种方法的优点是相对较快。缺点很明显,不能跟踪新兴目标。Option2是基于目标检测跟踪,首先检测视频每一帧中所有感兴趣的目标对象,然后将它们与上一帧检测到的目标关联起来,从而达到跟踪效果。这种方法的优点是可以跟踪整个视频中随时出现的新目标。当然,这种方法需要你有很好的“目标检测”算法。本文主要介绍Option2的实现原理,即TrackingByDetecting的跟踪方式。本文没有源代码链接。“目标检测”算法的源码可以参考我之前的文章。至于“轨迹跟踪”算法的源码实现,就很简单了。看完这篇文章,相信大家都能写出来。Python实现大约少了200行。TrackingByDetecting的跟踪过程Step1:使用目标检测算法检测每一帧中感兴趣的目标,得到对应的(位置坐标,分类,可信度),假设检测到的目标个数为M;Step2:通过某种方式将Step1中的检测结果与上一帧的检测目标(假设上一帧的检测目标个数为N)一一关联起来。换句话说,就是在M*N对中找到最相似的对。对于Step2中的“someway”,实现目标关联的方法其实有很多种,比如常见的计算两帧中两个目标之间的欧式距离(平面内两点之间的直线距离),最短的distance认为是同一个目标,然后通过匈牙利算法找到最匹配的pair。当然你也可以加入其他的判断条件,比如我用来计算两个目标框(position和sizeboxes)交并比的IOU。值越接近1,表示目标相同。还有其他的,比如判断两个物体的外观是否相似,需要用到外观模型进行比较,可能耗时较长。在关联的过程中,会出现三种情况:1)检测到的目标在前一帧的N个目标中找到,说明已经正常跟踪;2)在上一帧的N个目标中,没有找到本次检测到的目标,说明这个目标在这一帧是新的,所以我们需要记录下来,以便下次跟踪关联;3)上一帧有目标,这一帧没有与之关联的目标,那么目标可能已经从视野中消失了,我们需要将其移除。(这里要注意可能性,因为有可能因为检测错误而没有在这一帧检测到目标)而同一个目标在前后两帧中移动的很远,那么这种跟踪方式就会有问题。如上图所示,实线框表示目标在第一帧的位置,虚线框表示目标在第二帧的位置。当目标运行速度较慢时,可以通过前面的跟踪方法准确关联(A,A')和(B,B')。但是当目标跑得很快(或者每隔一帧检测一次),在第二帧,A会移动到第一帧B的位置,B会移动到其他位置。这时候使用上面的关联方式就会得到错误的结果。那么如何才能更准确地追踪呢?基于轨迹预测的跟踪方法由于第二帧的位置与第一帧的位置进行比较关联会产生误差,那么我们可以想办法预测目标下一帧出现的位置比较,然后将其与预测位置进行比较,用于比较相关性。在这种情况下,只要预测足够准确,几乎不会因为上面提到的速度而出现误差。如上图所示,在进行比较关联之前,我们先预测下一帧A和B的位置,然后用实际检测到的位置与预测位置进行比较关联,可以完美解决上述问题问题。从理论上讲,无论目标速度有多快,都可以连接起来。那么问题来了,如何预测下一帧目标的位置呢?有很多方法。可以用卡尔曼滤波根据目标在前面几帧的轨迹来预测下一帧的位置,也可以用你拟合的函数来预测下一帧的位置。在实践中,我使用拟合函数来预测对象在下一帧中的位置。如上图,通过前6帧的位置,我可以拟合出一条(T->XY)曲线(注意图中不是直线),然后预测目标在T+1帧。具体实现很简单,Python中的numpy库中也有类似功能的方法。仍然存在的不足即使它如此完美,仍然存在不足。轨迹预测的前提是知道目标前几帧的轨迹信息,所以一开始无法预测目标的轨迹,或者预测不准确。所以在前几帧,我们还是要用原来的方法进行比较和关联。
