OpenCV16-图像连通域分析

OpenCV16-图像连通域分析

    • 1.图像连通域分析
    • 2.connectedComponents
    • 3.connectedComponentsWithStatus


1.图像连通域分析

连通域是指图像中具有相同像素值并且位置相邻的像素组成的区域。连通域分析是指在图像中寻找彼此互相独立的连通域并将其标记出来。

4邻域与8邻域的概念:点 P 0 ( x , y ) P_0(x,y) P0(x,y) 的4邻域为其上下左右4个像素点,其8邻域为上下左右再加上对角线方向的4个点。

根据两个像素相邻定义方式不同,得到的连通区域也不相同,因此,在分析连通域的同时,一定要声明是在哪种邻域条件下分析得到的结果。

2.connectedComponents

OpenCV提供了用于提取图像中不同连通域的 connectedComponent() 函数:

int connectedComponents(InputArray image, OutputArray labels, // 标记不同连通域后的输出图像int connectivity,   // 标记连通域时使用的邻域种类,4表示4邻域int ltype,   // 输出图像数据类型:CV_32S、CV_16Uint ccltype  // 标记连通域时使用的算法类型
);int connectedComponents(InputArray image, OutputArray labels,int connectivity = 8, int ltype = CV_32S
);enum ConnectedComponentsAlgorithmsTypes {CCL_DEFAULT   = -1, // 8邻域使用SAUF、4邻域使用SAUFCCL_WU        = 0,  // 8邻域使用BBDT、4邻域使用SAUFCCL_GRANA     = 1,  // 8邻域使用BBDT、4邻域使用SAUFCCL_BOLELLI   = 2, CCL_SAUF      = 3,  CCL_BBDT      = 4, CCL_SPAGHETTI = 5, 
};

该函数用于计算二值图像中连通域的个数,并在图像中不同的连通域用不同的数字标签标记,其中标签0表示图像中的背景色。函数返回图像中连通域的数目。

示例代码:

3.connectedComponentsWithStatus

虽然 connectedComponents() 函数可以实现图像中多个连通域的统计,但是只能通过标签将图像中的不同连通域分开,无法得到更多的统计信息。有时,我们希望得到每个连通域中心位置或者在图像中标记出连通域所在的矩形区域, connectedComponents 便无法完成这个任务。

OpenCV中提供了 connectedComponentsWithStatus()函数用于在标记出图像中不同连通域的同时统计连通域的位置、面积的信息:

int connectedComponentsWithStats(InputArray image, OutputArray labels, // 标记不同连通域后的输出图像OutputArray stats,  // 含有不同连通域统计信息的矩阵,CV_32S。矩阵第i行是标签为i的连通域的统计信息。OutputArray centroids, // 每个连通域质心坐标,CV_64Fint connectivity, // 邻域种类int ltype,        // 输出图像数据类型int ccltype       // 标记连通域使用算法标志,同connectedComponents函数参数
);int connectedComponentsWithStats(InputArray image, OutputArray labels,OutputArray stats, OutputArray centroids,int connectivity = 8, int ltype = CV_32S
);

第三个参数为每个连通域统计信息矩阵:

enum ConnectedComponentsTypes {CC_STAT_LEFT   = 0, // 连通域内最左侧像素的x坐标,它是水平方向上的包含连通域边界框的开始CC_STAT_TOP    = 1, // 连通域内最上方像素的y坐标,它是垂直方向上的包含连通域边界框的开始CC_STAT_WIDTH  = 2, // 宽CC_STAT_HEIGHT = 3, // 高CC_STAT_AREA   = 4, // 连通域面积
#ifndef CV_DOXYGENCC_STAT_MAX    = 5  // 统计信息种类数目,无实际含义
#endif
};

使用:stats.at<int>(i, CC_STAT_WIDTH)

第四个参数为每个连通域的质心坐标,使用:centroids.at<double>(i, 0)取得x坐标,centroids.at<double>(i, 1)取得y坐标。

示例代码:

#include <opencv2\opencv.hpp>
#include <opencv2/core/utils/logger.hpp> // debug no logusing namespace cv;
using namespace std;int main()
{cout << "OpenCV Version: " << CV_VERSION << endl;utils::logging::setLogLevel(utils::logging::LOG_LEVEL_SILENT);//对图像进行距离变换Mat img = imread("rice.png");if (img.empty()){cout << "请确认图像文件名称是否正确" << endl;return -1;}imshow("原图", img);Mat rice, riceBW;//将图像转成二值图像,用于统计连通域cvtColor(img, rice, COLOR_BGR2GRAY);threshold(rice, riceBW, 50, 255, THRESH_BINARY);//生成随机颜色,用于区分不同连通域RNG rng(10086);Mat out, stats, centroids;//统计图像中连通域的个数int number = connectedComponentsWithStats(riceBW, out, stats, centroids, 8, CV_16U);vector<Vec3b> colors;for (int i = 0; i < number; i++){//使用均匀分布的随机数确定颜色Vec3b vec3 = Vec3b(rng.uniform(0, 256), rng.uniform(0, 256), rng.uniform(0, 256));colors.push_back(vec3);}//以不同颜色标记出不同的连通域Mat result = Mat::zeros(rice.size(), img.type());int w = result.cols;int h = result.rows;for (int i = 1; i < number; i++){// 中心位置int center_x = centroids.at<double>(i, 0);int center_y = centroids.at<double>(i, 1);//矩形边框int x = stats.at<int>(i, CC_STAT_LEFT);int y = stats.at<int>(i, CC_STAT_TOP);int w = stats.at<int>(i, CC_STAT_WIDTH);int h = stats.at<int>(i, CC_STAT_HEIGHT);int area = stats.at<int>(i, CC_STAT_AREA);// 中心位置绘制circle(img, Point(center_x, center_y), 2, Scalar(0, 255, 0), 2, 8, 0);// 外接矩形Rect rect(x, y, w, h);rectangle(img, rect, colors[i], 1, 8, 0);putText(img, format("%d", i), Point(center_x, center_y),FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 0, 255), 1);cout << "number: " << i << "\tarea: " << area << endl;}//显示结果imshow("标记后的图像", img);waitKey(0);return 0;
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/111028.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

梯度下降算法(Gradient Descent)

GD 梯度下降法的含义是通过当前点的梯度&#xff08;偏导数&#xff09;的反方向寻找到新的迭代点&#xff0c;并从当前点移动到新的迭代点继续寻找新的迭代点&#xff0c;直到找到最优解&#xff0c;梯度下降的目的&#xff0c;就是为了最小化损失函数。 1、给定待优化连续可微…

PRCV 2023:语言模型与视觉生态如何协同?合合信息瞄准“多模态”技术

近期&#xff0c;2023年中国模式识别与计算机视觉大会&#xff08;PRCV&#xff09;在厦门成功举行。大会由中国计算机学会&#xff08;CCF&#xff09;、中国自动化学会&#xff08;CAA&#xff09;、中国图象图形学学会&#xff08;CSIG&#xff09;和中国人工智能学会&#…

分享一个比对图片是否一致的小工具(来源: github)

运行效果图: 官网: GitHub - codingfishman/image-diff: 一个方便的图片对比工具一个方便的图片对比工具. Contribute to codingfishman/image-diff development by creating an account on GitHub.https://github.com/codingfishman/image-diff 优缺点: 1.采用比对各色块是…

从一道面试题开始学习C++标准库提供的并发编程工具

一个空列表&#xff0c;用两个函数&#xff08;只可调用一次&#xff09;轮流写入值&#xff08;一个写奇数&#xff0c;一个写偶数&#xff09;&#xff0c; 最终实现列表的值为1-100&#xff0c;有序排列。 简单分析&#xff1a;假设这两个函数分别为A和B&#xff0c;A函数往…

Sqoop技术文档笔记

Sqoop是一个用于在Hadoop和关系型数据库之间传输数据的开源工具。它可以将结构化数据从关系型数据库&#xff08;如MySQL、Oracle、SQL Server等&#xff09;导入到Hadoop的分布式文件系统&#xff08;HDFS&#xff09;或hive中&#xff0c;并且可以将数据从HDFS、hive导出到关…

安装VSCode,提升工作效率!iPad Pro生产力进阶之路

文章目录 前言1. 本地环境配置2. 内网穿透2.1 安装cpolar内网穿透(支持一键自动安装脚本)2.2 创建HTTP隧道 3. 测试远程访问4. 配置固定二级子域名4.1 保留二级子域名4.2 配置二级子域名 5. 测试使用固定二级子域名远程访问6. iPad通过软件远程vscode6.1 创建TCP隧道 7. ipad远…

mac 启动mysql Error: Failure while executing; `/bin/launchctl bootstrap gui/501

Error: Failure while executing; /bin/launchctl bootstrap gui/501 /Users/<myUserName>/Library/LaunchAgents/homebrew.mxcl.mysql8.0.plist exited with 5.homebrew 给的提示看不到具体消息 查看 homebrew.mxcl.mysql8.0.plist文件&#xff0c;能看到具体的启动命令…

Netty使用SslHandler实现加密通信-双向认证篇

“不积跬步&#xff0c;无以至千里。” 说明 其实Netty使用SslHandler实现加密通信单向认证和双向认证在代码上区别不大&#xff0c;下面是双向认证的代码示例 引入依赖 <dependency><groupId>io.netty</groupId><artifactId>netty-all</artifac…

webrtc基于DTLS的端口复用技术

DTLS协议: DTLS(Datagram Transport Layer Security)数据包安全传输协议,用于在不可靠的数据包传输协议上(如UDP)提供数据的安全传输。 UDP多路复用: 一个UDP多路复用&#xff0c;被用来处理共享同一个UDP端口的多个并发的UDT连接。类似同一个tcp port上创建多个socket connec…

【复盘】主从延迟以及 Waiting for tablemetadata lock 线上问题

背景 今晚DBA给一个大表添加索引&#xff0c;1000多W&#xff0c;正好风控系统这个时间段有查询这个表的请求&#xff0c;于是就出现了复制延迟。 这是正常下的延迟 可以看出基本都是是100毫秒以下。 Waiting for tablemetadata lock&#xff0c;并且业务跑的SQL出现锁等待…

append_ocr_trainf

read_image (Image, D:/图像文件/字符识别/1-1.bmp) access_channel (Image, Image1, 1) * draw_rectangle2 (3600, Row, Column, Phi, Length1, Length2) gen_rectangle2 (Rectangle, 96.0436, 715.9526, 0.0173917050943654, 110.186941, 18.041084) reduce_domain (Image1, …

多线程处理文件集合,先拆分,在执行

try {File file new File(path);File[] files file.listFiles();log.info("当前共有文件 "files.length"个");List<File> filesList new ArrayList<>(Arrays.asList(files));List<List<File>> dividedLists SplitListUtils.sp…

[笔记] 十进制转n进制

思路 n对 xa取模&#xff0c;就是xa-1 位上的数字&#xff0c;因为模出来的数不足xa 举例来说就是5&211&#xff0c;这个1就是20位上的1 当前位取完后&#xff0c;n/xa&#xff0c;表示n将对x(a1)进行取模&#xff08;进入下一位&#xff09; 重复此操作直至n0。 代码实现 …

开发者职场“生存状态”大调研报告分析 - 第四版

听人劝、吃饱饭,奉劝各位小伙伴,不要订阅该文所属专栏。 作者:不渴望力量的哈士奇(哈哥),十余年工作经验, 跨域学习者,从事过全栈研发、产品经理等工作,现任研发部门 CTO 。荣誉:2022年度博客之星Top4、博客专家认证、全栈领域优质创作者、新星计划导师,“星荐官共赢计…

.mxdown-V-XXXXXXXX勒索病毒感染后的下一步:恢复您的文件

引言&#xff1a; 在数字时代&#xff0c;计算机用户日益面临着来自网络犯罪分子的各种威胁&#xff0c;其中包括勒索病毒&#xff0c;如.mxdown-V-XXXXXXXX。这种勒索病毒可以对你的个人和商业数据文件进行加密&#xff0c;并要求支付赎金才能解锁它们。本文91数据恢复将介绍…

矩阵键盘中断扫描

/*----------------------------------------------- 内容&#xff1a;如计算器输入数据形式相同 从右至左 使用行列扫描方法 中断方式可以有效提供cpu工作效率&#xff0c;在有按键动作时才扫描&#xff0c;平时不进行扫描工作 -------------------------------------…

centos 7.9每天定期发送最新备份文件到另外一台服务器

1.需求 在本地化部署的过程中&#xff0c;为了使系统相对来说高可用&#xff0c;一般情况下&#xff0c;我们都会做一个负载&#xff0c;但是客户又会考虑成本&#xff0c;所以只有可怜巴巴的两台服务器&#xff0c;要全部服务都做负载&#xff0c;这个就实现不了。所以只能把…

1.13.C++项目:仿muduo库实现并发服务器之TcpServer模块的设计

文章目录 一、LoopThreadPool模块二、实现思想&#xff08;一&#xff09;管理&#xff08;二&#xff09;流程&#xff08;三&#xff09;功能设计 三、代码 一、LoopThreadPool模块 TcpServer模块&#xff1a; 对所有模块的整合&#xff0c;通过 tcpserver 模块实例化的对象&…

Python中的元组

Python 元组 Python 的元组与列表类似&#xff0c;不同之处在于元组的元素不能修改。以下是关于Python元组的一些基本信息&#xff1a; 元组的使用&#xff1a;元组是一个不可变的序列类型&#xff0c;使用小括号 () 来定义。元组没有增加元素append、修改元素、删除元素pop的…

【ListCtrl可以显示一部分吗】2023/10/14 下午1:38:38

2023/10/14 下午1:38:38 ListCtrl可以显示一部分吗 2023/10/14 下午1:38:45 ListCtrl是一个控件库,它可以在窗口中显示可滚动的列表。您可以使用SetItemCount方法设置要显示的项数,但在视图上只有部分项会显示,用户可以滚动以查看其他项。如果您想要指定要显示的具体项,…