6.3、综合模块:TLD只跟踪单目标,所以综合模块综合跟踪器跟踪到的单个目标和检测器可能检测到的多个目标,然后只输出保守相似度最大的一个目标。具体实现过程如下:
(1)先通过重叠度对检测器检测到的目标boundingbox进行聚类,每个类的重叠度小于0.5:
clusterConf(dbb, dconf, cbb, cconf);/////dbb为前面检测模块经过3个检测器后的detectstructure
(2)再找到与跟踪器跟踪到的box距离比较远的类(检测器检测到的box),而且它的相关相似度比跟踪器的要大:记录满足上述条件,也就是可信度比较高的目标box的个数:
if (bbOverlap(tbb,cbb)<0.5 && cconf>tconf) confident_detections++;
(3)判断如果只有一个满足上述条件的box,那么就用这个目标box来重新初始化跟踪器(也就是用检测器的结果去纠正跟踪器):
if (confident_detections==1) bbnext=cbb[didx];
(4)如果满足上述条件的box不只一个,那么就找到检测器检测到的box与跟踪器预测到的box距离很近(重叠度大于0.7)的所以box,对其坐标和大小进行累加:
if(bbOverlap(tbb,dbb)>0.7) cx+= dbb.x;……
(5)对与跟踪器预测到的box距离很近的box和跟踪器本身预测到的box进行坐标与大小的平均作为最终的目标boundingbox,但是跟踪器的权值较大:
bbnext.x =cvRound((float)(10*tbb.x+cx)/(float)(10+close_detections));……
(6)另外,如果跟踪器没有跟踪到目标,但是检测器检测到了一些可能的目标box,那么同样对其进行聚类,但只是简单的将聚类的cbb[0]作为新的跟踪目标box(不比较相似度了??还是里面已经排好序了??),重新初始化跟踪器:
bbnext=cbb[0];
至此,综合模块结束。
下图还没有修改
6.4、学习模块learn(img2);
学习模块也分为如下四部分:
6.4.1、检查一致性:(1)归一化img(bb)对应的patch的size(放缩至patch_size= 15*15),存入pattern:
getPattern(img(bb), pattern, mean, stdev);
(2)计算输入图像片(跟踪器的目标box)与在线模型之间的相关相似度conf:
classifier.NNConf(pattern,isin,conf,dummy);
(3)如果相似度太小了或者如果方差太小了或者如果被被识别为负样本,那么就不训练了;
if(conf<0.5)……或if(pow(stdev.val[0], 2)< var)……或if(isin[2]==1)……
6.4.2、生成样本:先是集合分类器的样本:fern_examples:
(1)先计算所有的扫描窗口与目前的目标box的重叠度:
grid.overlap= bbOverlap(lastbox, grid);
(2)再根据传入的lastbox,在整帧图像中的全部窗口中寻找与该lastbox距离最小(即最相似,重叠度最大)的num_closest_update个窗口,然后把这些窗口归入good_boxes容器(只是把网格数组的索引存入)同时,把重叠度小于0.2的,归入bad_boxes容器:
getOverlappingBoxes(lastbox, num_closest_update);
(3)然后用仿射模型产生正样本(类似于第一帧的方法,但只产生10*10=100个):
generatePositiveData(img,num_warps_update);
(4)加入负样本,相似度大于1(因为是后验概率累加值),则加入
idx=bad_boxes;
if(tmp.conf[idx]>=1) fern_examples.push_back(make_pair(tmp.patt[idx],0));
然后是最近邻分类器的样本:nn_examples:
if(bbOverlap(lastbox,grid[idx]) < bad_overlap)
nn_examples.push_back(dt.patch);
6.4.3、分类器训练:classifier.trainF(fern_examples,2);
classifier.trainNN(nn_examples);
6.4.4、把正样本库(在线模型)包含的所有正样本显示在窗口上classifier.show();
至此,tld.processFrame函数结束。 |