6.1.2、TLD跟踪模块的实现原理和trackf2f函数的实现:
TLD跟踪模块的实现是利用了MediaFlow中值光流跟踪和跟踪错误检测算法的结合。中值流跟踪方法是基于Forward-BackwardError和NNC的。原理很简单:从t时刻的图像的A点,跟踪到t+1时刻的图像B点;然后倒回来,从t+1时刻的图像的B点往回跟踪,假如跟踪到t时刻的图像的C点,这样就产生了前向和后向两个轨迹,比较t时刻中 A点和C点的距离,如果距离小于一个阈值,那么就认为前向跟踪是正确的;这个距离就是FB_error;
boolLKTracker::trackf2f(const Mat& img1, const Mat& img2,vector<oint2f> &points1, vector<cv:oint2f> &points2)
函数实现过程如下:
(1)先利用金字塔LK光流法跟踪预测前向轨迹:
calcOpticalFlowPyrLK( img1,img2, points1, points2, status, similarity,window_size, level, term_criteria, lambda, 0);
(2)再往回跟踪,产生后向轨迹:
calcOpticalFlowPyrLK( img2,img1, points2, pointsFB, FB_status,FB_error,window_size, level, term_criteria, lambda, 0);
(3)然后计算 FB-error:前向与后向轨迹的误差:
for( int i= 0; i<points1.size(); ++i )
FB_error = norm(pointsFB-points1);
(4)再从前一帧和当前帧图像中(以每个特征点为中心)使用亚象素精度提取10x10象素矩形(使用函数getRectSubPix得到),匹配前一帧和当前帧中提取的10x10象素矩形,得到匹配后的映射图像(调用matchTemplate),得到每一个点的NCC相关系数(也就是相似度大小)。
normCrossCorrelation(img1,img2, points1, points2);//用MatchTemplate进行的计算
(5)然后筛选出 FB_error <=median(FB_error)和sim_error > median(sim_error)的特征点(舍弃跟踪结果不好的特征点),剩下的是不到50%的特征点;
filterPts(points1,points2);
6.2、检测模块detect(img2);
TLD的检测分类器有三部分:方差分类器模块、集合分类器模块和最近邻分类器模块;这三个分类器是级联的。当前帧img2的每一个扫描窗口依次通过上面三个分类器,全部通过才被认为含有前景目标。具体实现过程如下:
先计算img2的积分图,为了更快的计算方差:
integral(frame,iisum,iisqsum);
然后用高斯模糊,去噪:
GaussianBlur(frame,img,Size(9,9),1.5);
下一步就进入了方差检测模块:
6.2.1、方差分类器模块:getVar(grid,iisum,iisqsum) >= var利用积分图计算每个待检测窗口的方差,方差大于var阈值(目标(best_box)patch方差的50%)的,则认为其含有前景目标,通过该模块的进入集合分类器模块:
6.2.2、集合分类器模块:集合分类器(随机森林)共有10颗树(基本分类器),每棵树13个判断节点,每个判断节点经比较得到一个二进制位0或者1,这样每棵树就对应得到一个13位的二进制码x(叶子),这个二进制码x对应于一个后验概率P(y|x)。那么整一个集合分类器(共10个基本分类器)就有10个后验概率了,将10个后验概率进行平均,如果大于阈值(一开始设经验值0.65,后面再训练优化)的话,就认为该图像片含有前景目标;具体过程如下:
(1)先得到该patch的特征值(13位的二进制代码):
classifier.getFeatures(patch,grid.sidx,ferns);
(2)再计算该特征值对应的后验概率累加值:
conf =classifier.measure_forest(ferns);
(3)若集合分类器的后验概率的平均值大于阈值fern_th(由训练得到),就认为含有前景目标:
if (conf> numtrees * fern_th) dt.bb.push_back(i);
(4)将通过以上两个检测模块的扫描窗口记录在detectstructure dt中;
(5)如果顺利通过以上两个检测模块的扫描窗口数大于100个,则只取后验概率大的前100个;
nth_element(dt.bb.begin(),dt.bb.begin()+100, dt.bb.end(),
CComparator(tmp.conf));
进入最近邻分类器:
6.2.3、最近邻分类器模块(1)先归一化patch的size(放缩至patch_size= 15*15),存入dt.patch;
getPattern(patch,dt.patch,mean,stdev);
(2)计算图像片pattern到在线模型M的相关相似度和保守相似度:
classifier.NNConf(dt.patch,dt.isin,dt.conf1,dt.conf2);
(3)相关相似度大于阈值,则认为含有前景目标:
if(dt.conf1>nn_th) dbb.push_back(grid[idx]);
到目前为止,检测器检测完成,全部通过三个检测模块的扫描窗口存在dbb中; |