各位用户为了找寻关于浅谈OpenCV中的新函数connectedComponentsWithStats用法的资料费劲了很多周折。这里教程网为您整理了关于浅谈OpenCV中的新函数connectedComponentsWithStats用法的相关资料,仅供查阅,以下为您介绍关于浅谈OpenCV中的新函数connectedComponentsWithStats用法的详细内容

主要内容:对比新旧函数,用于过滤原始图像中轮廓分析后较小的区域,留下较大区域。

关键字:connectedComponentsWithStats

在以前,常用的方法是”是先调用 cv::findContours() 函数(传入cv::RETR_CCOMP 标志),随后在得到的连通区域上循环调用 cv::drawContours() “

比如,我在GOCVHelper中这样进行了实现

? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 //寻找最大的轮廓  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(),contours,CV_RETR_LIST,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()

定义:

? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 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,    // input 8-bit single-channel (binary)  cv::OutputArray labels,    // 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:长这样

分别对应各个轮廓的x,y,width,height和面积。注意0的区域标识的是background

而centroids则对应的是中心点

而label则对应于表示是当前像素是第几个轮廓

例子:

对于图像

? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 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, labels,   stats, centroids   );  cout << "Total Connected Components Detected: " << nccomps << endl;  vector<cv::Vec3b> colors(nccomps+1);  colors[0] = Vec3b(0,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,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

而labels中

完全对的上号,结果为

以上这篇浅谈OpenCV中的新函数connectedComponentsWithStats用法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持服务器之家。

原文链接:https://www.cnblogs.com/jsxyhelu/p/7439655.html