Tracker——跟踪器
TLD的跟踪模块使用的算法是基于Median Flow tracker(中值流跟踪)的,在这个基础上增加了失败检测。中值流跟踪方法利用目标框(Bounding box)来表示被跟踪的目标,并在连续的相邻视频帧之间估计目标的运动。具体的流程如下:
1.先在lastbox中均匀采样10*10=100个特征点(网格均匀撒点),存于points1:
bbPoints(points1, lastbox);
2.利用金字塔LK光流法跟踪这些特征点,并预测当前帧的特征点。计算FB error和匹配相似度sim,然后筛选出 FB_error[i] <= median(FB_error) 和 sim_error[i] > median(sim_error) 的特征点(舍弃跟踪结果不好的特征点),剩下的是不到50%的特征点:
tracker.trackf2f(img1, img2, points, points2);
这个函数的具体实现如下:
//先利用金字塔LK光流法跟踪预测前向轨迹
calcOpticalFlowPyrLK( img1,img2, points1, points2, status, similarity, window_size, level, term_criteria, lambda, 0);
//再往回跟踪,产生后向轨迹
calcOpticalFlowPyrLK( img2,img1, points2, pointsFB, FB_status,FB_error, window_size, level, term_criteria, lambda, 0);
//然后计算 FB-error:前向与 后向 轨迹的误差
for( int i= 0; i<points1.size(); ++i )
FB_error[i] = norm(pointsFB[i]-points1[i]);
//再从前一帧和当前帧图像中(以每个特征点为中心)使用亚象素精度提取10x10象素矩形(使用函数getRectSubPix得到),匹配前一帧和当前帧中提取的10x10象素矩形,得到匹配后的映射图像(调用matchTemplate),得到每一个点的NCC相关系数(也就是相似度大小)。
normCrossCorrelation(img1, img2, points1, points2);
//然后筛选出 FB_error[i] <= median(FB_error) 和 sim_error[i] > median(sim_error)的特征点(舍弃跟踪结果不好的特征点),剩下的是不到50%的特征点
filterPts(points1, points2);
3.利用剩下的这不到一半的跟踪点输入来预测bounding box在当前帧的位置和大小:
bbPredict(points, points2, lastbox, tbb);
4.跟踪失败检测:如果FB error的中值大于10个像素(经验值),或者预测到的当前box的位置移出图像,则认为跟踪错误,此时不返回bounding box:
if (tracker.getFB()>10 || tbb.x>img2.cols || tbb.y>img2.rows || tbb.br().x < 1 || tbb.br().y <1)
5.归一化img2(bb)对应的patch的size(放缩至patch_size = 15*15),存入pattern:
getPattern(img2(bb),pattern,mean,stdev);
6.计算图像片pattern到在线模型M的保守相似度:
classifier.NNConf(pattern,isin,dummy,tconf);
7.如果保守相似度大于阈值,则评估本次跟踪有效,否则跟踪无效:
if (tconf>classifier.thr_nn_valid) tvalid =true;
至此,TLD中跟踪模块的工作完成。