1. 程式人生 > 程式設計 >淺談OpenCV中的新函式connectedComponentsWithStats用法

淺談OpenCV中的新函式connectedComponentsWithStats用法

主要內容:對比新舊函式,用於過濾原始影象中輪廓分析後較小的區域,留下較大區域。

關鍵字:connectedComponentsWithStats

在以前,常用的方法是”是先呼叫 cv::findContours() 函式(傳入cv::RETR_CCOMP 標誌),隨後在得到的連通區域上迴圈呼叫 cv::drawContours() “

比如,我在GOCVHelper中這樣進行了實現

//尋找最大的輪廓
 VP FindBigestContour(Mat src){ 
  int imax = 0; //代表最大輪廓的序號
  int imaxcontour = -1; //代表最大輪廓的大小
  std::vector<std::vector<Point>>contours; 
  findContours(src,contours,CV_RETR_LIST,CV_CHAIN_APPROX_SIMPLE);
  for (int i=0;i<contours.size();i++){
   int itmp = contourArea(contours[i]);//這裡採用的是輪廓大小
   if (imaxcontour < itmp ){
    imax = i;
    imaxcontour = itmp;
   }
  }
  return contours[imax];
 }
 //尋找並繪製出彩色聯通區域
 vector<VP> connection2(Mat src,Mat& draw){ 
  draw = Mat::zeros(src.rows,src.cols,CV_8UC3);
  vector<VP>contours; 
  findContours(src.clone(),CV_CHAIN_APPROX_SIMPLE);
  //由於給大的區域著色會覆蓋小的區域,所以首先進行排序操作
  //氣泡排序,由小到大排序
  VP vptmp;
  for(int i=1;i<contours.size();i++){
   for(int j=contours.size()-1;j>=i;j--){
    if (contourArea(contours[j]) < contourArea(contours[j-1]))
    {
     vptmp = contours[j-1];
     contours[j-1] = contours[j];
     contours[j] = vptmp;
    }
   }
  }

在OpenCV3中有了新的專門的函式 cv::connectedComponents() 和函式 cv::connectedComponentsWithStats()

定義:

int cv::connectedComponents (
 cv::InputArrayn image,// input 8-bit single-channel (binary)
 cv::OutputArray labels,// output label map
 int    connectivity = 8,// 4- or 8-connected components
 int    ltype  = CV_32S // Output label type (CV_32S or CV_16U)
 );
int cv::connectedComponentsWithStats (
 cv::InputArrayn image,// output label map
 cv::OutputArray stats,// Nx5 matrix (CV_32S) of statistics:
               // [x0,y0,width0,height0,area0;
               // ... ; x(N-1),y(N-1),width(N-1),// height(N-1),area(N-1)]
 cv::OutputArray centroids,// Nx2 CV_64F matrix of centroids:
               // [ cx0,cy0; ... ; cx(N-1),cy(N-1)]
 int    connectivity = 8,// 4- or 8-connected components
 int    ltype  = CV_32S // Output label type (CV_32S or CV_16U)
 );

其中,新出現的引數

stats:長這樣

淺談OpenCV中的新函式connectedComponentsWithStats用法

分別對應各個輪廓的x,y,width,height和麵積。注意0的區域標識的是background

而centroids則對應的是中心點

而label則對應於表示是當前畫素是第幾個輪廓

例子:

對於影象

淺談OpenCV中的新函式connectedComponentsWithStats用法

Mat img = cv::imread( "e:/sandbox/rect.png",0); 
 cv::Mat img_edge,labels,img_color,stats,centroids;
 cv::threshold(img,img_edge,128,255,cv::THRESH_BINARY);
 bitwise_not(img_edge,img_edge);
 cv::imshow("Image after threshold",img_edge);
 int i,nccomps = cv::connectedComponentsWithStats (
  img_edge,centroids
  );
 cout << "Total Connected Components Detected: " << nccomps << endl;
 vector<cv::Vec3b> colors(nccomps+1);
 colors[0] = Vec3b(0,0); // background pixels remain black.
 for( i = 1; i < nccomps; i++ ) {
  colors[i] = Vec3b(rand()%256,rand()%256,rand()%256);
  if( stats.at<int>(i,cv::CC_STAT_AREA) < 200 )
   colors[i] = Vec3b(0,0); // small regions are painted with black too.
 }
 img_color = Mat::zeros(img.size(),CV_8UC3);
 for( int y = 0; y < img_color.rows; y++ )
  for( int x = 0; x < img_color.cols; x++ )
  {
   int label = labels.at<int>(y,x);
   CV_Assert(0 <= label && label <= nccomps);
   img_color.at<cv::Vec3b>(y,x) = colors[label];
  }
 cv::imshow("Labeled map",img_color);
 cv::waitKey();

注意:

1、對於OpenCV來說,白色代表有資料,黑色代表沒有資料,所以影象輸入之前要轉換成”黑底白圖“

2、看labels 和 stats,其中第1 2 6 個的面積小於200

淺談OpenCV中的新函式connectedComponentsWithStats用法

而labels中

淺談OpenCV中的新函式connectedComponentsWithStats用法

完全對的上號,結果為

淺談OpenCV中的新函式connectedComponentsWithStats用法

以上這篇淺談OpenCV中的新函式connectedComponentsWithStats用法就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。