classifier.getFeatures(patch, grid[idx].sidx, fern);函数得到输入的patch的特征fern(13位的二进制代码);
pX.push_back(make_pair(fern, 1)); //positive ferns <features, labels=1>然后标记为正样本,存入pX(用于集合分类器的正样本)正样本库;
以上的操作会循环 num_warps * good_boxes.size()即20 * 10 次,这样,pEx就有了一个正样本,而pX有了200个正样本了;
4.7、meanStdDev(frame1(best_box), mean, stdev);
统计best_box的均值和标准差,var = pow(stdev.val[0],2) * 0.5;作为方差分类器的阈值。
4.8、generateNegativeData(frame1);
由于TLD仅跟踪一个目标,所以我们确定了目标框了,故除目标框外的其他图像都是负样本,无需仿射变换;具体实现如下:
由于之前重叠度小于0.2的,都归入 bad_boxes了,所以数量挺多,把方差大于var*0.5f的bad_boxes都加入负样本,同上面一样,需要classifier.getFeatures(patch, grid[idx].sidx, fern);和nX.push_back(make_pair(fern, 0));得到对应的fern特征和标签的nX负样本(用于集合分类器的负样本);
然后随机在上面的bad_boxes中取bad_patches(100个)个box,然后用 getPattern函数将frame图像bad_box区域的图像片归一化到15*15大小的patch,存在nEx(用于最近邻分类器的负样本)负样本中。
这样nEx和nX都有负样本了;(box的方差通过积分图像计算)
4.9、然后将nEx的一半作为训练集nEx,另一半作为测试集nExT;同样,nX也拆分为训练集nX和测试集nXT;
4.10、将负样本nX和正样本pX合并到ferns_data[]中,用于集合分类器的训练;
4.11、将上面得到的一个正样本pEx和nEx合并到nn_data[]中,用于最近邻分类器的训练;
4.12、用上面的样本训练集训练 集合分类器(森林) 和 最近邻分类器:
classifier.trainF(ferns_data, 2); //bootstrap = 2
对每一个样本ferns_data[i] ,如果样本是正样本标签,先用measure_forest函数返回该样本所有树的所有特征值对应的后验概率累加值,该累加值如果小于正样本阈值(0.6* nstructs,这就表示平均值需要大于0.6(0.6* nstructs / nstructs),0.6是程序初始化时定的集合分类器的阈值,为经验值,后面会用测试集来评估修改,找到最优),也就是输入的是正样本,却被分类成负样本了,出现了分类错误,所以就把该样本添加到正样本库,同时用update函数更新后验概率。对于负样本,同样,如果出现负样本分类错误,就添加到负样本库。
classifier.trainNN(nn_data);
对每一个样本nn_data,如果标签是正样本,通过NNConf(nn_examples[i], isin, conf, dummy);计算输入图像片与在线模型之间的相关相似度conf,如果相关相似度小于0.65 ,则认为其不含有前景目标,也就是分类错误了;这时候就把它加到正样本库。然后就通过pEx.push_back(nn_examples[i]);将该样本添加到pEx正样本库中;同样,如果出现负样本分类错误,就添加到负样本库。
4.13、用测试集在上面得到的 集合分类器(森林) 和 最近邻分类器中分类,评价并修改得到最好的分类器阈值。
classifier.evaluateTh(nXT, nExT);
对集合分类器,对每一个测试集nXT,所有基本分类器的后验概率的平均值如果大于thr_fern(0.6),则认为含有前景目标,然后取最大的平均值(大于thr_fern)作为该集合分类器的新的阈值。
对最近邻分类器,对每一个测试集nExT,最大相关相似度如果大于nn_fern(0.65),则认为含有前景目标,然后取最大的最大相关相似度(大于nn_fern)作为该最近邻分类器的新的阈值。
5、进入一个循环:读入新的一帧,然后转换为灰度图像,然后再处理每一帧processFrame;
6、processFrame(last_gray, current_gray, pts1, pts2, pbox, status, tl, bb_file);逐帧读入图片序列,进行处理。processFrame共包含四个模块(依次处理):跟踪模块、检测模块、综合模块和学习模块;
6.1、跟踪模块:track(img1, img2, points1, points2);
track函数完成前一帧img1的特征点points1到当前帧img2的特征点points2的跟踪预测;
6.1.1、具体实现过程如下:
(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%的特征点: