OpenCV- communication domain analysis connectedComponentsWithStats ()

The main content of the following from the "Learning OpenCV 3" page417-419 and official documents 

Provides two functions in OpenCV 3 good, there is no in OpenCV 2. 

(1)cv::connectedComponents()

(2)cv::connectedComponentsWithStats()

Corresponding official document: https://docs.opencv.org/3.3.1/d3/dc0/group__imgproc__shape.html#ga107a78bf7cd25dec05fb4dfc5c9e765f

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)
);
Wherein connectedComponents () creates a signature only (FIG. Different communication domains using labeled, and consistent picture width and height), connectedComponentsWith the Stats () above, the task can be completed, in addition, communication may also return each important information area - bounding Box, area, and Center mass (of . centroid) If the centroid of the connected component is not required, set the parameter centroids CV :: noArray () , this sentence runs in my version to be wrong .

Function returns the total number of the communication area N, the range [0, N-1], where 0 represents background.


The following is a simple example, the communication areas shown marked, while removing small connected components (noise corresponding to lossless).


#include <opencv2/opencv.hpp>
#include <algorithm>
#include <iostream>
using namespace std;
int main()
{
      cv::Mat src_img, img_bool, labels, stats, centroids, img_color, img_gray;
      
      if( (src_img = cv::imread("2.bmp",0)).empty())
      {
            cout<<"load image error!";
            return -1;
      }
      cv::threshold(src_img, img_bool, 0, 255, cv::THRESH_OTSU);
      //连通域计算
      int nccomps = cv::connectedComponentsWithStats (
            img_bool, //二值图像
            labels,     //和原图一样大的标记图
            stats, //nccomps×5的矩阵 表示每个连通区域的外接矩形和面积(pixel)
            centroids //nccomps×2的矩阵 表示每个连通区域的质心
            );
      //显示原图统计结果
      char title[1024];
      sprintf(title,"原图中连通区域数:%d\n",nccomps);
      cv::String num_connect(title);
      cv::imshow(num_connect, img_bool);
      
      //去除过小区域,初始化颜色表
      vector<cv::Vec3b> colors(nccomps);
      colors[0] = cv::Vec3b(0,0,0); // background pixels remain black.
      for(int i = 1; i < nccomps; i++ ) {
            colors[i] = cv::Vec3b(rand()%256, rand()%256, rand()%256);
            //去除面积小于100的连通域
            if( stats.at<int>(i, cv::CC_STAT_AREA) < 100 )
                  colors[i] = cv::Vec3b(0,0,0); // small regions are painted with black too.
      }
      //按照label值,对不同的连通域进行着色
      img_color = cv::Mat::zeros(src_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::cvtColor(img_color,img_gray,cv::COLOR_BGR2GRAY);
      cv::threshold(img_gray, img_gray, 1, 255, cv::THRESH_BINARY);
      nccomps = cv::connectedComponentsWithStats (img_gray, labels,stats,centroids);
      sprintf(title,"过滤小目标后的连通区域数量:%d\n",nccomps);
      num_connect = title;
      cv::imshow(num_connect, img_color);
      cv::waitKey();
      return 0;
}



发布了89 篇原创文章 · 获赞 210 · 访问量 47万+

Guess you like

Origin blog.csdn.net/i_chaoren/article/details/78358297