else{
printf("%d close detections were found\n",close_detections);
}
}
}
}
else{ // 如果没有跟踪
printf("Not tracking..\n");
lastboxfound = false;
lastvalid = false;
//如果跟踪器没有跟踪到目标,但是检测器检测到了一些可能的目标box,那么同样对其进行聚类,但只是简单的
//将聚类的cbb[0]作为新的跟踪目标box(不比较相似度了??还是里面已经排好序了??),重新初始化跟踪器
if(detected){ // 并定义检测器
clusterConf(dbb,dconf,cbb,cconf); // 群集检测
printf("Found %d clusters\n",(int)cbb.size());
if (cconf.size()==1){
bbnext=cbb[0];
lastconf=cconf[0];
printf("Confident detection..reinitializing tracker\n");
lastboxfound = true;
}
}
}
lastbox=bbnext;
if (lastboxfound)
fprintf(bb_file,"%d,%d,%d,%d,%f\n",lastbox.x,lastbox.y,lastbox.br().x,lastbox.br().y,lastconf);
else
fprintf(bb_file,"NaN,NaN,NaN,NaN,NaN\n");
///learn 学习模块
if (lastvalid && tl)
learn(img2);
}
/*Inputs:
* -current frame(img2), last frame(img1), last Bbox(bbox_f[0]).
*Outputs:
*- Confidence(tconf), Predicted bounding box(tbb), Validity(tvalid), points2 (for display purposes only)
*/
void TLD::track(const Mat& img1, const Mat& img2, vector<Point2f>& points1, vector<Point2f>& points2){
//Generate points
//网格均匀撒点(均匀采样),在lastbox中共产生最多10*10=100个特征点,存于points1
bbPoints(points1, lastbox);
if (points1.size()<1){
printf("BB= %d %d %d %d, Points not generated\n",lastbox.x,lastbox.y,lastbox.width,lastbox.height);
tvalid=false;
tracked=false;
return;
}
vector<Point2f> points = points1;
//Frame-to-frame tracking with forward-backward error cheking
//trackf2f函数完成:跟踪、计算FB error和匹配相似度sim,然后筛选出 FB_error[i] <= median(FB_error) 和
//sim_error[i] > median(sim_error) 的特征点(跟踪结果不好的特征点),剩下的是不到50%的特征点
tracked = tracker.trackf2f(img1, img2, points, points2);
if (tracked){
// 边界框预测
//利用剩下的这不到一半的跟踪点输入来预测bounding box在当前帧的位置和大小 tbb
bbPredict(points, points2, lastbox, tbb);
//跟踪失败检测:如果FB error的中值大于10个像素(经验值),或者预测到的当前box的位置移出图像,则
//认为跟踪错误,此时不返回bounding box;Rect::br()返回的是右下角的坐标
//getFB()返回的是FB error的中值
if (tracker.getFB()>10 || tbb.x>img2.cols || tbb.y>img2.rows || tbb.br().x < 1 || tbb.br().y <1){
tvalid =false; // 太不稳定的预测或边界框出图像
tracked = false;
printf("Too unstable predictions FB error=%f\n", tracker.getFB());
return;
}
// 估计信心和有效性
//评估跟踪确信度和有效性
Mat pattern;
Scalar mean, stdev;
BoundingBox bb;
bb.x = max(tbb.x,0);
bb.y = max(tbb.y,0);
bb.width = min(min(img2.cols-tbb.x,tbb.width), min(tbb.width, tbb.br().x));
bb.height = min(min(img2.rows-tbb.y,tbb.height),min(tbb.height,tbb.br().y));
//归一化img2(bb)对应的patch的size(放缩至patch_size = 15*15),存入pattern
getPattern(img2(bb),pattern,mean,stdev);
vector<int> isin;
float dummy;
//计算图像片pattern到在线模型M的保守相似度
classifier.NNConf(pattern,isin,dummy,tconf); //Conservative Similarity
tvalid = lastvalid;
//保守相似度大于阈值,则评估跟踪有效
if (tconf>classifier.thr_nn_valid){
tvalid =true;
}
}
else
printf("No points tracked\n");
}
//网格均匀撒点,box共10*10=100个特征点
void TLD::bbPoints(vector<cv::Point2f>& points, const BoundingBox& bb){
int max_pts=10;
int margin_h=0; //采样边界
int margin_v=0;
//网格均匀撒点
int stepx = ceil((bb.width-2*margin_h)/max_pts); //ceil返回大于或者等于指定表达式的最小整数
int stepy = ceil((bb.height-2*margin_v)/max_pts);
//网格均匀撒点,box共10*10=100个特征点
for (int y=bb.y+margin_v; y<bb.y+bb.height-margin_v; y+=stepy){
for (int x=bb.x+margin_h;x<bb.x+bb.width-margin_h;x+=stepx){
points.push_back(Point2f(x,y));