在OpenCV 3中提供了两个很好的函数,在OpenCV 2中没有。

(1)connectedComponents()

(2)connectedComponentsWithStats()

对应的官方文档为:https://docs.opencv.org/3.3.1/d3/dc0/group__imgproc__shape.html#ga107a78bf7cd25dec05fb4dfc5c9e765f
函数原型:

int  cv::connectedComponents (cv::InputArrayn image,                // //8位单通道二值图像 (binary)cv::OutputArray labels,               // output label map //和原图一样大的标记图int             connectivity = 8,     // 4- or 8-connected componentsint             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 mapcv::OutputArray stats,                // Nx5 matrix (CV_32S) of statistics:// [x0, y0, width0, height0, area0;//nccomps×5的矩阵 表示每个连通区域的外接矩形和面积(pixel)//  ... ; x(N-1), y(N-1), width(N-1), height(N-1), area(N-1)]cv::OutputArray centroids,          //nccomps×2的矩阵 表示每个连通区域的质心(pixel)Nx2 CV_64F matrix of centroids: [ cx0, cy0; ... ; cx(N-1), cy(N-1)]int             connectivity = 8,     // 4- or 8-connected componentsint             ltype        = CV_32S // Output label type (CV_32S or CV_16U));

其中connectedComponents()仅仅创建了一个标记图(图中不同连通域使用不同的标记,和原图宽高一致),connectedComponentsWithStats()可以完成上面任务,除此之外,还可以返回每个连通区域的重要信息--bounding box, area, andcentroid
参数说明:

该函数有返回值,返回一个int整型 nccomps,函数返回值为连通区域的总数N,范围为[0,N-1],其中0代表背景。

image:输入8位单通道二值图像;

label:输出,和原图image一样大的标记图,label对应于表示是当前像素是第几个轮廓,背景置0;

centroids:对应的是轮廓的中心点。nccomps×2的矩阵 表示每个连通区域的质心

stats:输出,nccomps×5的矩阵 ,表示每个连通区域的外接矩形和面积(pixel),例如下列:

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

例子:from:https://www.cnblogs.com/jsxyhelu/p/7439655.html

对上图进行连通域分析,看labels 和 stats,其中第1 2 6 个的面积小于200

而labels中

完全对的上号,结果为

实例:

对图像进行连通域分析,将面积小于100的区域作为背景,进行剔除,去除很小的连通域(相当于无损降噪)

#include<opencv2\opencv.hpp>
#include<algorithm>
#include<iostream>
using namespace std;
using namespace cv;
Mat src, src_color,g_src, labels, stats, centroids;
int g_threshold = 30;
void trackbar(int, void*);
int main() {src = imread("133.png", 0);namedWindow("src", 1);createTrackbar("threshold", "src", &g_threshold, 255, trackbar);imshow("src", src);/*threshold(src, g_src, 170, 255, THRESH_BINARY);imshow("d", g_src);int num = connectedComponentsWithStats(g_src, labels, stats, centroids);cout <<"轮廓数" << num << endl;vector<Vec3b> color(num + 1);color[0] = Vec3b(0, 0, 0);//背景色for (int m = 1; m <=num ; m++) {color[m] = Vec3b(rand() % 256, rand() % 256, rand() % 256);if (stats.at<int>(m - 1, CC_STAT_AREA) < 100)//连通域面积小于100的区域,将其当作背景color[m] = Vec3b(0, 0, 0);}src_color=Mat::zeros(src.size(), CV_8UC3);for (int x = 0; x < src.rows; x++)for (int y = 0; y < src.cols; y++){int label = labels.at<int>(x, y);//注意labels是int型,不是uchar.src_color.at<Vec3b>(x, y) = color[label];}imshow("labelMap", src_color);*/waitKey(0);
}
void trackbar(int, void*) {threshold(src, g_src, g_threshold, 255, THRESH_BINARY_INV);imshow("d", g_src);int num = connectedComponentsWithStats(g_src, labels, stats, centroids);cout << "轮廓数" << num << endl;vector<Vec3b> color(num + 1);color[0] = Vec3b(0, 0, 0);//背景色for (int m = 1; m <= num; m++) {color[m] = Vec3b(rand() % 256, rand() % 256, rand() % 256);//if (stats.at<int>(m - 1, CC_STAT_AREA) < 30)//color[m] = Vec3b(0, 0, 0);}src_color = Mat::zeros(src.size(), CV_8UC3);for (int x = 0; x < src.rows; x++)for (int y = 0; y < src.cols; y++){int label = labels.at<int>(x, y);//注意labels是int型,不是uchar.src_color.at<Vec3b>(x, y) = color[label];}imshow("labelMap", src_color);}

结果:

from:https://blog.csdn.net/i_chaoren/article/details/78358297

OpenCV3学习(9.2)连通域分析函数详解connectedComponents()和connectedComponentsWithStats()相关推荐

  1. java 检查bytebuf长度_Java学习笔记16-Netty缓冲区ByteBuf详解

    Java学习笔记16-Netty缓冲区ByteBuf详解 Netty自己的ByteBuf ByteBuf是为解决ByteBuffer的问题和满足网络应用程序开发人员的日常需求而设计的. JDK Byt ...

  2. spring学习笔记03-spring-DI-依赖注入详解(通过xml配置文件来配置依赖注入)

    spring学习笔记03-spring-DI-依赖注入详解 1.概念 2.构造函数注入 3.set方法注入 4.集合的注入 需要被注入的实体对象 package com.itheima.service ...

  3. Java NIO学习篇之缓冲区ByteBuffer详解

    定义: ByteBuffer是Buffer的实现类之一,是一个通用的缓冲区,功能要比其他缓冲区子类多.支持直接内存.是一个抽象类.子类实现是HeapByteBuffer(非直接缓冲区子类),Direc ...

  4. Python学习二:词典基础详解

    作者:NiceCui 本文谢绝转载,如需转载需征得作者本人同意,谢谢. 本文链接:http://www.cnblogs.com/NiceCui/p/7862377.html 邮箱:moyi@moyib ...

  5. 【学习笔记】线段树详解(全)

    [学习笔记]线段树详解(全) 和三个同学一起搞了接近两个月的线段树,头都要炸了T_T,趁心态尚未凉之前赶快把东西记下来... [目录] [基础]作者:\((Silent\)_\(EAG)\) [懒标记 ...

  6. html学习 - jquery事件监听详解

    html学习 - jquery事件监听详解 html学习 - jquery事件监听详解 监听方法 监听方法参数解释 click参数 事件自动执行问题解决 bind方法 live方法 监听方法 在jqu ...

  7. OpenCV-Python学习之(一)waitKey()函数详解

    OpenCV-Python学习之(一)waitKey()函数详解 waitKey()函数详解 : 1.1 waitKey()--这个函数是在一个给定的时间内(单位ms)等待用户按键触发;如果用户没有按 ...

  8. 【STM32】标准库与HAL库对照学习教程八--串口通信详解

    [STM32]标准库与HAL库对照学习教程八--串口通信详解 一.前言 二.准备工作 三.通信的基本概念 1.通信方式 2.串行通信与并行通信 (1)串行通信 (2)并行通信 3.异步通信与同步通信 ...

  9. [网络安全学习篇2]:IP详解及简单的DOS命令(千峰网络安全视频笔记 2 day)

    引言:我的系列博客[网络安全学习篇]上线了,小编也是初次创作博客,经验不足:对千峰网络信息安全开源的视频公开课程的学习整理的笔记整理的也比较粗糙,其实看到目录有300多集的时候,讲道理,有点怂了,所以 ...

最新文章

  1. 对比java_java集合对比
  2. 网页制作遵循四大原则让网站建设更加优质
  3. Spark RDD概念学习系列之RDD的重要内部属性(十五)
  4. pipe()函数精解
  5. kong安装配置手册
  6. java定时器写法_java定时器的写法是什么样?
  7. LeetCode 1674. 使数组互补的最少操作次数(差分思想)
  8. intent Filter
  9. 计算机基础知识教材pdf,计算机基础知识 2教材.pdf
  10. 5岁儿童自学python编程-为什么外国5岁孩子就要学编程?原因你一定想知道
  11. PL/SQL Developer工具的使用简介
  12. js中的相等与不等运算
  13. 关于button onclick a href 分析
  14. tar打包忽略某个目录
  15. 风口来了第二期——电子科学与技术专业现状和前景介绍分享
  16. 使用toUpperCase toLowerCase getBytes方法实现一串字母字符的大小写转换
  17. spring事务传播级别
  18. 常用英语食品词汇- 调味品类
  19. Verilog除法器(32位无符号+带符号)
  20. 京东淘宝手机销售量排行

热门文章

  1. cesium添加填充_cesium编程中级(四)使用渐变纹理
  2. android 外部存储列表,如何获取Android设备的已安装外部存储列表
  3. 使用php进行后台开发,PHP后台开发用到的基础方法整理【原创】
  4. SPP-net论文笔记
  5. Fiddler如何查找登陆的可用cookie用于其他请求?方式一
  6. 如何免费的让网站启用HTTPS
  7. 实现多线程爬取数据并保存到mongodb
  8. 每个开发者都应该懂一点单元测试
  9. 从字符串数组中寻找数字的元素
  10. CSS浮动(Float)(二)