aihot  2017-05-02 16:16:53  OpenCV |   查看评论   
  •       }  
  •   }  
  • }  
  •   
  • //利用剩下的这不到一半的跟踪点输入来预测bounding box在当前帧的位置和大小  
  • void TLD::bbPredict(const vector<cv::Point2f>& points1,const vector<cv::Point2f>& points2,  
  •                     const BoundingBox& bb1,BoundingBox& bb2)    {  
  •   int npoints = (int)points1.size();  
  •   vector<float> xoff(npoints);  //位移  
  •   vector<float> yoff(npoints);  
  •   printf("tracked points : %d\n", npoints);  
  •   for (int i=0;i<npoints;i++){   //计算每个特征点在两帧之间的位移  
  •       xoff[i]=points2[i].x - points1[i].x;  
  •       yoff[i]=points2[i].y - points1[i].y;  
  •   }  
  •   float dx = median(xoff);   //计算位移的中值  
  •   float dy = median(yoff);  
  •   float s;  
  •   //计算bounding box尺度scale的变化:通过计算 当前特征点相互间的距离 与 先前(上一帧)特征点相互间的距离 的  
  •   //比值,以比值的中值作为尺度的变化因子  
  •   if (npoints>1){  
  •       vector<float> d;  
  •       d.reserve(npoints*(npoints-1)/2);  //等差数列求和:1+2+...+(npoints-1)  
  •       for (int i=0;i<npoints;i++){  
  •           for (int j=i+1;j<npoints;j++){  
  •           //计算 当前特征点相互间的距离 与 先前(上一帧)特征点相互间的距离 的比值(位移用绝对值)  
  •               d.push_back(norm(points2[i]-points2[j])/norm(points1[i]-points1[j]));  
  •           }  
  •       }  
  •       s = median(d);  
  •   }  
  •   else {  
  •       s = 1.0;  
  •   }  
  •   
  •   float s1 = 0.5*(s-1)*bb1.width;  
  •   float s2 = 0.5*(s-1)*bb1.height;  
  •   printf("s= %f s1= %f s2= %f \n", s, s1, s2);  
  •     
  •   //得到当前bounding box的位置与大小信息  
  •   //当前box的x坐标 = 前一帧box的x坐标 + 全部特征点位移的中值(可理解为box移动近似的位移) - 当前box宽的一半  
  •   bb2.x = round( bb1.x + dx - s1);  
  •   bb2.y = round( bb1.y + dy -s2);  
  •   bb2.width = round(bb1.width*s);  
  •   bb2.height = round(bb1.height*s);  
  •   printf("predicted bb: %d %d %d %d\n",bb2.x,bb2.y,bb2.br().x,bb2.br().y);  
  • }  
  •   
  • void TLD::detect(const cv::Mat& frame){  
  •   // 清理
  •   dbb.clear();  
  •   dconf.clear();  
  •   dt.bb.clear();  
  •   //GetTickCount返回从操作系统启动到现在所经过的时间  
  •   double t = (double)getTickCount();  
  •   Mat img(frame.rows, frame.cols, CV_8U);  
  •   integral(frame,iisum,iisqsum);   //计算frame的积分图   
  •   GaussianBlur(frame,img,Size(9,9),1.5);  //高斯模糊,去噪?  
  •   int numtrees = classifier.getNumStructs();  
  •   float fern_th = classifier.getFernTh(); //getFernTh()返回thr_fern; 集合分类器的分类阈值  
  •   vector <int> ferns(10);  
  •   float conf;  
  •   int a=0;  
  •   Mat patch;  
  •   //级联分类器模块一:方差检测模块,利用积分图计算每个待检测窗口的方差,方差大于var阈值(目标patch方差的50%)的,  
  •   //则认为其含有前景目标  
  •   for (int i=0; i<grid.size(); i++){  //FIXME: BottleNeck 瓶颈  
  •       if (getVar(grid[i],iisum,iisqsum) >= var){  //计算每一个扫描窗口的方差  
  •           a++;  
  •           //级联分类器模块二:集合分类器检测模块  
  •           patch = img(grid[i]);  
  •           classifier.getFeatures(patch,grid[i].sidx,ferns); //得到该patch特征(13位的二进制代码)  
  •           conf = classifier.measure_forest(ferns);  //计算该特征值对应的后验概率累加值  
  •           tmp.conf[i]=conf;   //Detector data中定义TempStruct tmp;   
  •           tmp.patt[i]=ferns;  
  •           //如果集合分类器的后验概率的平均值大于阈值fern_th(由训练得到),就认为含有前景目标  
  •           if (conf > numtrees*fern_th){    
  •               dt.bb.push_back(i);  //将通过以上两个检测模块的扫描窗口记录在detect structure中  
  •           }  
  •       }  
  •       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);  
  •     
  •   //如果通过以上两个检测模块的扫描窗口数大于100个,则只取后验概率大的前100个  
  •   if (detections>100){   //CComparator(tmp.conf)指定比较方式???  
  •       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<detections;i++){  
  • //        drawBox(img,grid[dt.bb[i]]);  
  • //    }  
  • //  imshow("detections",img);  
  •   if (detections==0){  
  •         detected=false;  
  •         return;  
  •       }  
  •   printf("Fern detector made %d detections ",detections);  
  •     
  •   //两次使用getTickCount(),然后再除以getTickFrequency(),计算出来的是以秒s为单位的时间(opencv 2.0 以前是ms)  
  •   t=(double)getTickCount()-t;    
  •   printf("in %gms\n", t*1000/getTickFrequency());  //打印以上代码运行使用的毫秒数  
  •     
  •   //  初始化检测结构
  •   dt.patt = vector<vector<int> >(detections,vector<int>(10,0));        //  合奏分类器的相应代码
  •   dt.conf1 = vector<float>(detections);                                
  •  

    除特别注明外,本站所有文章均为 赢咖4注册 原创,转载请注明出处来自TLD(Tracking-Learning-Detection)学习与源码理解之(六)下

    留言与评论(共有 0 条评论)
       
    验证码:
    [lianlun]1[/lianlun]