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

关键字    :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(),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()
定义:
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则对应于表示是当前像素是第几个轮廓
例子:
对于图像
     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中
完全对的上号,结果为


最新文章

  1. 传智播客--高级控件--showdialog关闭(小白内容)
  2. js倒计时跳转链接
  3. Red5 第一个例子之HelloWorld
  4. nfs服务部署记录
  5. Linux下/boot目录
  6. HackerRank &quot;Components in a graph&quot;
  7. intellij 设置-试验过的
  8. C# DataTable的詳細用法 - hcw_peter的专栏 - 博客频道 - CSDN
  9. 内核与ramdisk到底是什么关系
  10. Gradle 1.12 翻译——第十四章. 教程 - 杂七杂八
  11. UVA 10815 Andy&amp;#39;s First Dictionary(字符处理)
  12. PHP单元测试利器:PHPUNIT初探
  13. 7.21.02 switch语句
  14. Cocos2Dv3.4在AppDelegate中不返回的情况及解决
  15. 【算法】螺旋方阵 上交OJ1021
  16. tensorflow 1.0 学习:十图详解tensorflow数据读取机制
  17. java 32个Java面试必考点
  18. python-web自动化-Js-日历操作
  19. DJANGO_SETTINGS_MODULE is undefined报错的解决
  20. shell流程控制与循环结构

热门文章

  1. c++11——列表初始化
  2. JavaIO简单代码实例
  3. 从TCP三次握手说起--浅析TCP协议中的疑难杂症(1)
  4. web图片100%宽度自适应,高度不塌陷
  5. String() 函数把对象的值转换为字符串。
  6. ListView之EmptyView
  7. 第k最短路A*启发式搜索
  8. 模拟退火算法(run away poj1379)
  9. 【node】------mongoose的基本使用------【巷子】
  10. talib 中文文档(九):Volume Indicators 成交量指标