当前位置: 首页 > news >正文

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<VPconnection2(Mat src,Matdraw){    
        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:长这样
img_749ab45cf7604991085a8bb1049cfdd7.png
分别对应各个轮廓的x,y,width,height和面积。注意0的区域标识的是background
centroids则对应的是中心点
而label则对应于表示是当前像素是第几个轮廓
例子:
对于图像
img_5f8042a6c3d5e395778f7a7b3a8fb33d.png
     Mat img = cv::imread"e:/sandbox/rect.png",0); 
    cv::Mat  img_edgelabelsimg_colorstats,centroids;
    cv::threshold(imgimg_edge, 128, 255, cv::THRESH_BINARY);
    bitwise_not(img_edge,img_edge);
    cv::imshow("Image after threshold"img_edge);
    int inccomps = cv::connectedComponentsWithStats (
        img_edgelabels,
        statscentroids
        );
    cout << "Total Connected Components Detected: " << nccomps << endl;
    vector<cv::Vec3bcolors(nccomps+1);
    colors[0] = Vec3b(0,0,0); // background pixels remain black.
    fori = 1; i < nccompsi++ ) {
        colors[i] = Vec3b(rand()%256, rand()%256, rand()%256);
        ifstats.at<int>(icv::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);
    forint y = 0; y < img_color.rowsy++ )
        forint x = 0; x < img_color.colsx++ )
        {
            int label = labels.at<int>(yx);
            CV_Assert(0 <= label && label <= nccomps);
            img_color.at<cv::Vec3b>(yx) = colors[label];
        }
    cv::imshow("Labeled map"img_color);
    cv::waitKey();
注意:
1、对于OpenCV来说,白色代表有数据,黑色代表没有数据,所以图像输入之前要转换成”黑底白图“
2、看 labels  和  stats,其中第1 2 6 个的面积小于200
img_6d542b8747a21fe2a034c9b674052b5e.png
而labels中
img_cce02fa3261beff75bb27c8c591e35c3.gif
完全对的上号,结果为
img_92adae0c24c929bb7493a448c5a17d40.png




来自为知笔记(Wiz)


目前方向:图像拼接融合、图像识别 联系方式:jsxyhelu@foxmail.com

相关文章:

  • ASP.NET Core 运行原理解剖[2]:Hosting补充之配置介绍
  • Spring Boot整合Quartz实现定时任务表配置
  • Arcgis for Js实现graphiclayer的空间查询(续)
  • 【树莓派】服务配置相关2:基于RPi Desktop的服务配置
  • (推荐)叮当——中文语音对话机器人
  • 睿仁医疗郑世斌:医疗智能硬件数据精度应放在第一位
  • 软件开发的流程
  • 理解.NET中的异常(二)
  • Spring 和 SpringMVC 常用注解
  • python并开发编程之协程
  • 探索我的项目管理之路之:软件质量的六个考核要素
  • 使用交换机实现数据单向访问控制
  • 为恶意文件“画像” 瀚思科技基于深度学习技术快速锁定未知威胁
  • 真实案例:一位网页开发者几乎毁掉一家小公司
  • 支付宝灾备能力为何引发争议
  • 【剑指offer】让抽象问题具体化
  • 【跃迁之路】【463天】刻意练习系列222(2018.05.14)
  • create-react-app项目添加less配置
  • CSS 三角实现
  • flutter的key在widget list的作用以及必要性
  • Node 版本管理
  • vue2.0项目引入element-ui
  • vue数据传递--我有特殊的实现技巧
  • webpack+react项目初体验——记录我的webpack环境配置
  • 第三十一到第三十三天:我是精明的小卖家(一)
  • - 概述 - 《设计模式(极简c++版)》
  • 后端_MYSQL
  • 如何设计一个比特币钱包服务
  • 入门到放弃node系列之Hello Word篇
  • 山寨一个 Promise
  • [地铁译]使用SSD缓存应用数据——Moneta项目: 低成本优化的下一代EVCache ...
  • 阿里云服务器购买完整流程
  • ​​​​​​​​​​​​​​汽车网络信息安全分析方法论
  • ​如何在iOS手机上查看应用日志
  • #100天计划# 2013年9月29日
  • #NOIP 2014# day.1 生活大爆炸版 石头剪刀布
  • #我与Java虚拟机的故事#连载19:等我技术变强了,我会去看你的 ​
  • (1)(1.13) SiK无线电高级配置(六)
  • (17)Hive ——MR任务的map与reduce个数由什么决定?
  • (Mirage系列之二)VMware Horizon Mirage的经典用户用例及真实案例分析
  • (Note)C++中的继承方式
  • (webRTC、RecordRTC):navigator.mediaDevices undefined
  • (附源码)php投票系统 毕业设计 121500
  • (一)RocketMQ初步认识
  • (转) ns2/nam与nam实现相关的文件
  • ******之网络***——物理***
  • .net 4.0 A potentially dangerous Request.Form value was detected from the client 的解决方案
  • .net 发送邮件
  • .net 简单实现MD5
  • .NET 使用 ILRepack 合并多个程序集(替代 ILMerge),避免引入额外的依赖
  • .NET 应用启用与禁用自动生成绑定重定向 (bindingRedirect),解决不同版本 dll 的依赖问题
  • .NET处理HTTP请求
  • .NET单元测试
  • /etc/sudoers (root权限管理)
  • @Autowired @Resource @Qualifier的区别