void TLD::detect(const cv::Mat& frame){
//cleaning
dbb.clear();
dconf.clear();
dt.bb.clear();
double t = (double)getTickCount();
Mat img(frame.rows,frame.cols,CV_8U);
integral(frame,iisum,iisqsum);
GaussianBlur(frame,img,Size(9,9),1.5);
int numtrees = classifier.getNumStructs();
float fern_th = classifier.getFernTh();
vector ferns(10);
float conf;
int a=0;
Mat patch;
for (int i=0;i
if (getVar(grid[i],iisum,iisqsum)>=var){
a++;
patch = img(grid[i]);
classifier.getFeatures(patch,grid[i].sidx,ferns);
conf = classifier.measure_forest(ferns);
// std::cout<<"conf****************************"<
tmp.conf[i]=conf;
tmp.patt[i]=ferns;
if (conf>numtrees*fern_th){
dt.bb.push_back(i);
}
}
else
tmp.conf[i]=0.0;
}
int detections = dt.bb.size();
printf("%d Bounding boxes passed the variance filter\n",a);
printf("%d Initial detection from Fern Classifier\n",detections);
if (detections>100){
nth_element(dt.bb.begin(),dt.bb.begin()+100,dt.bb.end(),CComparator(tmp.conf));
dt.bb.resize(100);
detections=100;
}
// for (int i=0;i
// drawBox(img,grid[dt.bb[i]]);
// }
// imshow("detections",img);
if (detections==0){
detected=false;
return;
}
printf("Fern detector made %d detections ",detections);
t=(double)getTickCount()-t;
printf("in %gms\n", t*1000/getTickFrequency());
// Initialize detection structure
dt.patt = vector >(detections,vector(10,0)); // Corresponding codes of the Ensemble Classifier
dt.conf1 = vector(detections); // Relative Similarity (for final nearest neighbour classifier)
dt.conf2 =vector(detections); // Conservative Similarity (for integration with tracker)
dt.isin = vector >(detections,vector(3,-1)); // Detected (isin=1) or rejected (isin=0) by nearest neighbour classifier
dt.patch = vector(detections,Mat(patch_size,patch_size,CV_32F));// Corresponding patches
int idx;
Scalar mean, stdev;
float nn_th = classifier.getNNTh();
for (int i=0;i
idx=dt.bb[i]; // Get the detected bounding box index
patch = frame(grid[idx]);
getPattern(patch,dt.patch[i],mean,stdev); // Get pattern within bounding box
classifier.NNConf(dt.patch[i],dt.isin[i],dt.conf1[i],dt.conf2[i]); // Evaluate nearest neighbour classifier
dt.patt[i]=tmp.patt[idx];
//printf("Testing feature %d, conf:%f isin:(%d|%d|%d)\n",i,dt.conf1[i],dt.isin[i][0],dt.isin[i][1],dt.isin[i][2]);
if (dt.conf1[i]>nn_th){ // idx = dt.conf1 > tld.model.thr_nn; % get all indexes that made it through the nearest neighbour
dbb.push_back(grid[idx]); // BB = dt.bb(:,idx); % bounding boxes
dconf.push_back(dt.conf2[i]); // Conf = dt.conf2(:,idx); % conservative confidences
}
} // end
if (dbb.size()>0){
printf("Found %d NN matches\n",(int)dbb.size());
detected=true;
}
else{
printf("No NN matches found.\n");
detected=false;
}
}
检测只要是分三步走:
第一步:
是历遍所有的gri
d,方差检测模块,利用积分图计算每个待检测窗口的方差,
找出(getVar(grid[i],iisum,iisqsum)>=var)大于阀值的,则目标要大于50%才能被认为进入第二步;
double TLD::getVar(const BoundingBox& box,const Mat& sum,const Mat& sqsum)的原理和opencv的求方差的原理是一样的
第二步:获得通过第一步符合条件的grid的特征值(classifier.getFeatures(patch,grid[i].sidx,ferns))
利用其特征值去获得后验概率值,如果后验概率值大于阀值,则存于dt.bb.push_back(i),认为有可能检测到目标;
但是,如果确认检测到还需要第三步;
在进入第三步之前,如果通过第一步和第二步的grid的个数大于100,还要进行筛选,选出值最大的100个值;
nth_element(dt.bb.begin(),dt.bb.begin()+100,dt.bb.end(),CComparator(tmp.conf));函数等同排序,
接着到第三步:
getPattern(patch,dt.patch[i],mean,stdev); // Get pattern within bounding box
classifier.NNConf(dt.patch[i],dt.isin[i],dt.conf1[i],dt.conf2[i]); // Eva
通过第二步的grid的经过(getPattern)函数处理后,接着求
出
图像片pattern到在线模型M的相关相似度和保守相似度,
//相关相似度大于阈值,则认为含有前景目标
if (dt.conf1[i]>nn_th){ // idx = dt.conf1 > tld.model.thr_nn; % get all indexes that made it through the nearest neighbour
dbb.push_back(grid[idx]); // BB = dt.bb(:,idx); % bounding boxes
dconf.push_back(dt.conf2[i]); // Conf = dt.conf2(:,idx); % conservative confidences
}
如果dbb.size()大于0
则认为检测到目标
初学者,个人自己理解有误,所以有不足的地方,敬请谅解,希望能得到大神的指点;