MedianFlow中值流跟踪算法&源码

一、MedianFlow算法简介

该算法属于TLD跟踪算法中的Tracking部分。TLD算法可参考:Tracking-Learning-Detection原理分析。它基于LK光流跟踪算法,并使用FB(正向/反向评估点追踪质量的一种方法)、NCC交叉验证进行反馈。

二、正反向连续性(forward-backward consistency)

 作者假设一个“好”的追踪算法应该具有正反向连续性(forward-backward consistency),即无论是按照时间上的正序追踪还是反序追踪,产生的轨迹应该是一样的。作者根据这个性质规定了任意一个追踪器的FB误差(forward-backward error):从时间t的初始位置x(t)开始追踪产生时间t+p的位置x(t+p),再从位置x(t+p)反向追踪产生时间t的预测位置x`(t),初始位置和预测位置之间的欧氏距离就作为追踪器在t时间的FB误差。

                           MedianFlow中值流跟踪算法&源码_第1张图片

Median-Flow追踪算法采用的是Lucas-Kanade追踪器,也就是常说的光流法追踪器。这个追踪器的原理请参考:Lucas–Kanade(LK)光流算法详解。基本内容就是给定若干追踪点,追踪器会根据像素的运动情况确定这些追踪点在下一帧的位置。

三、追踪点的选择

        作者给出了一种依据FB误差绘制误差图(Error Map)筛选最佳追踪点的方法,但并不适用于实时追踪任务,就不详细介绍了。这里只介绍在TLD中确定追踪点的方法。

        首先在上一帧t的物体包围框里均匀地产生一些点,然后用Lucas-Kanade追踪器正向追踪这些点到t+1帧,再反向追踪到t帧,计算FB误差,筛选出FB误差最小的一半点作为最佳追踪点。最后根据这些点的坐标变化和距离的变化计算t+1帧包围框的位置和大小(平移的尺度取中值,缩放的尺度取中值。取中值的光流法,估计这也是名称Median-Flow的由来吧)。

                      MedianFlow中值流跟踪算法&源码_第2张图片

还可以用NCC(Normalized Cross Correlation,归一化互相关)和SSD(Sum-of-Squared Differences,差值平方和)作为筛选追踪点的衡量标准。作者的代码中是把FB误差和NCC结合起来的,所以筛选出的追踪点比原来一半还要少。

                    NCC:                ncc     

                    SSD:                                ssd

四、源代码中的MedianFlow算法主要流程详解

☆ 跟踪模块:track(img1,img2, points1, points2)

这个函数的输入是上一帧灰度图img1和当前帧灰度图img2,以及跟踪点的坐标points1和points2。它分以下几个步骤进行:

  •   bbPoints(points1,lastbox)    这个函数主要功能就是进行点的生成,在上一帧的跟踪区域lastbox中进行均匀采样,得到不超过10*10=100个点放到points1中(因为采样步长是用ceil进一法得到,所以每行或每列得到的点可能无法达到10个)。
  • 2   tracker.trackf2f(img1,img2,points1,points2)   这个函数输入是上一帧灰度图img1和当前帧灰度图img2,bbPoints()生成的点序列points1,输出是points2,主要功能是完成:跟踪、计算FB error和匹配相似度sim,然后剔除 匹配度小于匹配度中值的(sim_error[i] > median(sim_error)),再剔除跟踪误差大于误差中值的(FB_error[i] <= median(FB_error)), 也即把跟踪结果不好的特征点去掉,剩下的是不到50%的特征点,对应地留在points1和points2中。 
  • 跟踪的原理基于Forward-Backward Error的中值流跟踪方法,对于points1中的每个点,使用前向跟踪,即上一帧的点A(由于点A是在lastbox行生成的,所以确实是上一帧的点)在当前帧的跟踪结果为B,然后使用后向跟踪,即当前帧的点B反向跟踪得到上一帧的跟踪点C,这样就产生了前向和后向两条跟踪轨迹,理想的情况应该是两条轨迹重合,即A和C是重合的,所以计算A和C的距离FB_error,得到一个FB_error[]数组。之后调用normCrossCorrelation()计算A和B的similarity,这个similarity是以A和B为中心的,分别在上一帧和当前帧截取的10*10的区域调用matchTemplate()函数计算匹配度,将匹配度值赋给similarity,得到一个similarity[]数组。
  • 接下来调用filterPts(vector&points1,vector& points2)对所得到的点进行过滤,其中points1是所有点A组成的集合,points2是所有点B组成的集合。首先计算similarity[]数组中所有数的中值simmed,对于similarity超过simmed的点进行保留,其余的剔除,这样FB_error[]数组的规模也相应减小。之后计算这个减小规模后的FB_error[]数组的中值fbmed,对于FB_error小于fbmed的点进行保留,其余的剔除。
  • 3   bbPredict(points1,points2,lastbox,tbb)   这个函数输入中的point1和points2是前面用光流法跟踪并剔除跟踪效果不好的特征点而剩下的点集,lastbox是上一帧的跟踪结果,tbb是用于记录当前帧的跟踪结果。主要功能是利用剩下的这不到一半的跟踪点作为输入来预测bounding box在当前帧的位置和大小 并放到tbb中。 它先按x维度和y维度分别计算所有点在上一帧和当前帧的跟踪差距,并计算出这些差距的中值dx,dy。接下来计算points1中所有点两两之间的距离d1和points2中所有点两两之间的距离d1,将d2/d1都放到d中,计算所有的d的中值s,这个s就表征了进行光流跟踪之后特征点变化相对于上一帧位置的偏移比例,从而用s去乘以上一帧窗口的宽高度以得到当前帧跟踪结果窗口的宽高度;另外,跟踪窗口的左上角坐标也要更新,坐标的偏移不能只考虑位移的绝对值,还要考虑窗口本身宽高度,也即这个位移相对于窗口本身的比例,所以用0.5*(s-1)分别去乘以上一帧窗口的宽度和高度,得到偏移量s1和s2,再结合表征了上一帧和当前帧跟踪差距的dx和dy,得到新跟踪结果tbb(trackbounding box)的左上角坐标(lastbox.x+ dx -s1, lastbox.y + dy -s2)。
  •  对跟踪结果进行判断,如果fbmed超过10(固定经验值)、或者窗口坐标位于图像外,说明跟踪的结果不稳定,将跟踪结果丢弃,置tvalid和tracked为false并进入下一帧,否则继续进行下面的过程。
  • 5   估计置信度和有效性,调用getPattern()计算当前帧在跟踪结果区域的pattern,把pattern做为输入调用NNConf计算它与在线模型的保守相似度tconf,如果tconf>thr_nn_valid,则置tvalid为true,也即表示当前跟踪结果有效,否则tvalid仍为上一帧的值。

五、算法优点

可以跟踪目标框的尺寸变化。 对于前后帧的每一对点,都有一个比例,是当前点和前一阵点的距离比例。目标边界框的尺寸变化被定义为这些比例的中值。

六、MedianFlow代码 & 程序示例

以下为某个TLD开源代码MedianFlow部分经过我的修改后,改造成一个运行程序示例,程序实现细节与第4部分基本相同,但是函数名不一定一致。

MedianFlow代码 & 程序示例

你可能感兴趣的:(图像处理)