集合分类器(随机森林)共有10颗树(基本分类器),每棵树13个判断节点,每个判断节点经比较得到一个二进制位0或者1,这样每棵树就对应得到一个13位的二进制码x(叶子),这个二进制码x对应于一个后验概率P(y|x)。那么整一个集合分类器(共10个基本分类器)就有10个后验概率了,将10个后验概率进行平均,如果大于阈值(一开始设经验值0.65,后面再训练优化)的话,就认为该图像片含有前景目标;具体过程如下:
(1)先得到该patch的特征值(13位的二进制代码):
classifier.getFeatures(patch,grid[i].sidx,ferns);
(2)再计算该特征值对应的后验概率累加值:
conf = classifier.measure_forest(ferns);
(3)若集合分类器的后验概率的平均值大于阈值fern_th(由训练得到),就认为含有前景目标:
if (conf > numtrees * fern_th) dt.bb.push_back(i);
(4)将通过以上两个检测模块的扫描窗口记录在detect structure中;
(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[i];
getPattern(patch,dt.patch[i],mean,stdev);
(2)计算图像片pattern到在线模型M的相关相似度和保守相似度:
classifier.NNConf(dt.patch[i],dt.isin[i],dt.conf1[i],dt.conf2[i]);
(3)相关相似度大于阈值,则认为含有前景目标:
if (dt.conf1[i]>nn_th) dbb.push_back(grid[idx]);
到目前为止,检测器检测完成,全部通过三个检测模块的扫描窗口存在dbb中;
6.3、综合模块:
TLD只跟踪单目标,所以综合模块综合跟踪器跟踪到的单个目标和检测器可能检测到的多个目标,然后只输出保守相似度最大的一个目标。具体实现过程如下:
(1)先通过 重叠度 对检测器检测到的目标bounding box进行聚类,每个类的重叠度小于0.5:
clusterConf(dbb, dconf, cbb, cconf);
(2)再找到与跟踪器跟踪到的box距离比较远的类(检测器检测到的box),而且它的相关相似度比跟踪器的要大:记录满足上述条件,也就是可信度比较高的目标box的个数:
if (bbOverlap(tbb, cbb[i])<0.5 && cconf[i]>tconf) confident_detections++;
(3)判断如果只有一个满足上述条件的box,那么就用这个目标box来重新初始化跟踪器(也就是用检测器的结果去纠正跟踪器):
if (confident_detections==1) bbnext=cbb[didx];
(4)如果满足上述条件的box不只一个,那么就找到检测器检测到的box与跟踪器预测到的box距离很近(重叠度大于0.7)的所以box,对其坐标和大小进行累加:
if(bbOverlap(tbb,dbb[i])>0.7) cx += dbb[i].x;……
(5)对与跟踪器预测到的box距离很近的box 和 跟踪器本身预测到的box 进行坐标与大小的平均作为最终的目标bounding box,但是跟踪器的权值较大:
bbnext.x = cvRound((float)(10*tbb.x+cx)/(float)(10+close_detections));……
(6)另外,如果跟踪器没有跟踪到目标,但是检测器检测到了一些可能的目标box,那么同样对其进行聚类,但只是简单的将聚类的cbb[0]作为新的跟踪目标box(不比较相似度了??还是里面已经排好序了??),重新初始化跟踪器:
bbnext=cbb[0];
至此,综合模块结束。
6.4、学习模块:learn(img2);