注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

BeyondEgo

Welcome to Winsolider's yard! 超越自我,谁与争锋?

 
 
 

日志

 
 
关于我

本博为记事、畅聊、交友博客,邀你共同探讨人生、探讨成长,广交天下有志之士!愿与有相同兴趣爱好的你,共同学习、一起成长、收获喜悦!

网易考拉推荐

TLD源码理解之TLD.cpp(三)  

2013-05-20 15:55:40|  分类: TLD算法 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

  1. //此函数根据传入的box1(目标边界框),在整帧图像中的全部窗口中寻找与该box1距离最小(即最相似,  
  2. //重叠度最大)的num_closest个窗口,然后把这些窗口 归入good_boxes容器(只是把网格数组的索引存入)  
  3. //同时,把重叠度小于0.2的,归入 bad_boxes 容器   
  4. void TLD::getOverlappingBoxes(const cv::Rect& box1,int num_closest){  
  5.   float max_overlap = 0;  
  6.   for (int i=0;i<grid.size();i++){  
  7.       if (grid[i].overlap > max_overlap) {  //找出重叠度最大的box  
  8.           max_overlap = grid[i].overlap;  
  9.           best_box = grid[i];         
  10.       }  
  11.       if (grid[i].overlap > 0.6){   //重叠度大于0.6的,归入 good_boxes  
  12.           good_boxes.push_back(i);  
  13.       }  
  14.       else if (grid[i].overlap < bad_overlap){  //重叠度小于0.2的,归入 bad_boxes  
  15.           bad_boxes.push_back(i);  
  16.       }  
  17.   }  
  18.   //Get the best num_closest (10) boxes and puts them in good_boxes  
  19.   if (good_boxes.size()>num_closest){  
  20.   //STL中的nth_element()方法找出一个数列中排名第n(下面为第num_closest)的那个数。这个函数运行后  
  21.   //在good_boxes[num_closest]前面num_closest个数都比他大,也就是找到最好的num_closest个box了  
  22.     std::nth_element(good_boxes.begin(), good_boxes.begin() + num_closest, good_boxes.end(), OComparator(grid));  
  23.     //重新压缩good_boxes为num_closest大小   
  24.     good_boxes.resize(num_closest);  
  25.   }  
  26.   //获取good_boxes 的 Hull壳,也就是窗口的边框  
  27.   getBBHull();  
  28. }  
  29.   
  30. //此函数获取good_boxes 的 Hull壳,也就是窗口(图像)的边框 bounding box  
  31. void TLD::getBBHull(){  
  32.   int x1=INT_MAX, x2=0;  //INT_MAX 最大的整形数  
  33.   int y1=INT_MAX, y2=0;  
  34.   int idx;  
  35.   for (int i=0;i<good_boxes.size();i++){  
  36.       idx= good_boxes[i];  
  37.       x1=min(grid[idx].x,x1);   //防止出现负数??  
  38.       y1=min(grid[idx].y,y1);  
  39.       x2=max(grid[idx].x + grid[idx].width,x2);  
  40.       y2=max(grid[idx].y + grid[idx].height,y2);  
  41.   }  
  42.   bbhull.x = x1;  
  43.   bbhull.y = y1;  
  44.   bbhull.width = x2-x1;  
  45.   bbhull.height = y2 -y1;  
  46. }   
  47. //如果两个box的重叠度小于0.5,返回false,否则返回true  
  48. bool bbcomp(const BoundingBox& b1,const BoundingBox& b2){  
  49.   TLD t;  
  50.     if (t.bbOverlap(b1,b2)<0.5)  
  51.       return false;  
  52.     else  
  53.       return true;  
  54. }  
  55.   
  56. int TLD::clusterBB(const vector<BoundingBox>& dbb,vector<int>& indexes){  
  57.   //FIXME: Conditional jump or move depends on uninitialised value(s)  
  58.   const int c = dbb.size();  
  59.   //1. Build proximity matrix   
  60.   Mat D(c,c,CV_32F);  
  61.   float d;  
  62.   for (int i=0;i<c;i++){  
  63.       for (int j=i+1;j<c;j++){  
  64.         d = 1-bbOverlap(dbb[i],dbb[j]);  
  65.         D.at<float>(i,j) = d;  
  66.         D.at<float>(j,i) = d;  
  67.       }  
  68.   }  
  69.   //2. Initialize disjoint clustering  
  70.  float L[c-1]; //Level  
  71.  int nodes[c-1][2];  
  72.  int belongs[c];  
  73.  int m=c;  
  74.  for (int i=0;i<c;i++){  
  75.     belongs[i]=i;  
  76.  }  
  77.  for (int it=0;it<c-1;it++){  
  78.  //3. Find nearest neighbor   
  79.      float min_d = 1;  
  80.      int node_a, node_b;  
  81.      for (int i=0;i<D.rows;i++){  
  82.          for (int j=i+1;j<D.cols;j++){  
  83.              if (D.at<float>(i,j)<min_d && belongs[i]!=belongs[j]){  
  84.                  min_d = D.at<float>(i,j);  
  85.                  node_a = i;  
  86.                  node_b = j;  
  87.              }  
  88.          }  
  89.      }  
  90.      if (min_d>0.5){  
  91.          int max_idx =0;  
  92.          bool visited;  
  93.          for (int j=0;j<c;j++){  
  94.              visited = false;  
  95.              for(int i=0;i<2*c-1;i++){  
  96.                  if (belongs[j]==i){  
  97.                      indexes[j]=max_idx;  
  98.                      visited = true;  
  99.                  }  
  100.              }  
  101.              if (visited)  
  102.                max_idx++;  
  103.          }  
  104.          return max_idx;  
  105.      }  
  106.   
  107.  //4. Merge clusters and assign level  
  108.      L[m]=min_d;  
  109.      nodes[it][0] = belongs[node_a];  
  110.      nodes[it][1] = belongs[node_b];  
  111.      for (int k=0;k<c;k++){  
  112.          if (belongs[k]==belongs[node_a] || belongs[k]==belongs[node_b])  
  113.            belongs[k]=m;  
  114.      }  
  115.      m++;  
  116.  }  
  117.  return 1;  
  118.   
  119. }   
  120. //对检测器检测到的目标bounding box进行聚类   
  121. //聚类(Cluster)分析是由若干模式(Pattern)组成的,通常,模式是一个度量(Measurement)的向量,或者是多维空间中的  
  122. //一个点。聚类分析以相似性为基础,在一个聚类中的模式之间比不在同一聚类中的模式之间具有更多的相似性。  
  123. void TLD::clusterConf(const vector<BoundingBox>& dbb,const vector<float>& dconf,vector<BoundingBox>& cbb,vector<float>& cconf){  
  124.   int numbb =dbb.size();  
  125.   vector<int> T;  
  126.   float space_thr = 0.5;  
  127.   int c=1;    //记录 聚类的类个数  
  128.   switch (numbb){  //检测到的含有目标的bounding box个数  
  129.   case 1:  
  130.     cbb=vector<BoundingBox>(1,dbb[0]);  //如果只检测到一个,那么这个就是检测器检测到的目标  
  131.     cconf=vector<float>(1,dconf[0]);  
  132.     return;  
  133.     break;  
  134.   case 2:  
  135.     T =vector<int>(2,0);  
  136.     //此函数计算两个bounding box 的重叠度  
  137.     if (1 - bbOverlap(dbb[0],dbb[1]) > space_thr){  //如果只检测到两个box,但他们的重叠度小于0.5  
  138.       T[1]=1;  
  139.       c=2;  //重叠度小于0.5的box,属于不同的类   
  140.     }  
  141.     break;  
  142.   default:  //检测到的box数目大于2个,则筛选出重叠度大于0.5的  
  143.     T = vector<int>(numbb, 0);  
  144.     //stable_partition()重新排列元素,使得满足指定条件的元素排在不满足条件的元素前面。它维持着两组元素的顺序关系。  
  145.     //STL partition就是把一个区间中的元素按照某个条件分成两类。返回第二类子集的起点  
  146.     //bbcomp()函数判断两个box的重叠度小于0.5,返回false,否则返回true (分界点是重叠度:0.5)  
  147.     //partition() 将dbb划分为两个子集,将满足两个box的重叠度小于0.5的元素移动到序列的前面,为一个子集,重叠度大于0.5的,  
  148.     //放在序列后面,为第二个子集,但两个子集的大小不知道,返回第二类子集的起点  
  149.     c = partition(dbb, T, (*bbcomp));   //重叠度小于0.5的box,属于不同的类,所以c是不同的类别个数  
  150.     //c = clusterBB(dbb,T);   
  151.     break;  
  152.   }  
  153.   cconf=vector<float>(c);   
  154.   cbb=vector<BoundingBox>(c);  
  155.   printf("Cluster indexes: ");  
  156.   BoundingBox bx;  
  157.   for (int i=0;i<c;i++){   //类别个数  
  158.       float cnf=0;  
  159.       int N=0,mx=0,my=0,mw=0,mh=0;  
  160.       for (int j=0;j<T.size();j++){  //检测到的bounding box个数  
  161.           if (T[j]==i){   //将聚类为同一个类别的box的坐标和大小进行累加  
  162.               printf("%d ",i);  
  163.               cnf=cnf+dconf[j];  
  164.               mx=mx+dbb[j].x;  
  165.               my=my+dbb[j].y;  
  166.               mw=mw+dbb[j].width;  
  167.               mh=mh+dbb[j].height;  
  168.               N++;  
  169.           }  
  170.       }  
  171.       if (N>0){   //然后求该类的box的坐标和大小的平均值,将平均值作为该类的box的代表  
  172.           cconf[i]=cnf/N;  
  173.           bx.x=cvRound(mx/N);  
  174.           bx.y=cvRound(my/N);  
  175.           bx.width=cvRound(mw/N);  
  176.           bx.height=cvRound(mh/N);  
  177.           cbb[i]=bx;  //返回的是聚类,每一个类都有一个代表的bounding box  
  178.       }  
  179.   }  
  180.   printf("\n");  
  评论这张
 
阅读(738)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017