opencv#35 连通域分析

连通域分割原理

像素领域介绍:

4邻域是指中心的像素与它邻近的上下左右一共有4个像素,那么称这4个像素为中心像素的4邻域。

8邻域是以中心像素周围的8个像素分别是上下左右和对角线上的4个像素。

连通域的定义(分割)分为两种:以4邻域为相邻判定条件的连通域分割和8邻域为判定条件的连通域分割。连通域指某个区域内所有像素是相邻的,如果一个像素不能够通过这个区域中的像素到达另一个像素,那么这两个像素就不再同一连通域内。

连通域的划分通常采用两遍法,在进行连通域分析的时候,我们往往先对图像进行二值化处理,确定连通域的判定标准是采用4邻域还是8邻域,然后先对图像进行遍历得到结果,然后再对此结果进行遍历得到最终结果。

在进行遍历时遇到非0(非黑)的像素值,就对此像素进行编号,例如上图,进行第一次遍历时,遇到黄色的方格,标记为1,之后凡是与此放个相邻的像素,都将其设置为1,第一行遍历完后,赋值了1个1,遍历第二行,最左侧有个黄色像素,此像素的上方和左方的像素若有标记的数值,那么就将这个黄色像素标记为上方与左方数值较小的数,这里可以看到上方为空,左方是边缘,因此这个像素没有办法借助上方和左方标记,我们就需要对其进行独立标记,由于1已经用过,我们将其标记为2。

然后看下一个黄色的像素,这个像素左边的像素被标记为2,而上方是一个没有被标记的像素,因此这个像素也被标记为2。

然后继续看下一个像素,这个像素的左方和上方都被标记了,而两者标记数值不一致,因此我们根据规则选择两者之间较小数值,即1。

到达第三行时,遇见黄色像素,因为此像素上方的像素为1,因此也要记为1。

来到第四行,第四行第一个像素,左侧和上方都没有被标记,因此需要进行独立标记,1和2都用过了,我们对此像素标记3 。

下一个像素左侧为3上方为1,标记为1。

最后一行分别被标记为3和1。

 zhe

这样完成了第一次遍历,第二次遍历,将两个邻近的结果进行统一,比如上图第二行,标记为2和标记1的像素相连,因此我们将其中的2全部置为1,下方像素同理。 

这样便完成了两遍法实现图像邻域分割,图像分割的结果通过示例中也可以看出是一个与原图像具有相同尺寸的图像 。

只分割连通域的函数

connectedComponents()

int cv::connectedComponents(InputArray    image,OutputArray   labels,connectivity =int           8,int           Itype = CV_325)

·image:待标记不同连通域的图像单通道,数据类型必须为CV_8U。上面说过图像通常会进行二值化处理,若不进行二值化,则会将1~255之间的任何数都独立的看成不同区域,也就是即使出现2,3,4相邻的区域,也会判断为3个不同的连通域,因此,我们最好是使用0~255的数据,这样的数据是有限的,若我们使用0~1之间的小数,分割形式是无限的,那么分割的结果就会出现每一个单独的像素都是一个单独的连通域。我们要先对图像进行二值化,因为图像可能会受到光照影响,即使在真实物理世界中,是同一个像素值的物体,通过相机的采集,也会出现不同像素值的情况。

·labels:标记不同连通域后的输出图像,与输入图像具有相同尺寸。

·connectivity:标记连通域时使用的邻域种类,4表示4-邻域,8表示8-邻域,默认参数为8.

·ltype:输出图像的数据类型,目前支持CV_32S和CV_16U两种数据类型,默认参数为CV_32S。

分割并统计连通域信息的函数

connectedComponentsWithStats()

void cv::connectedComponentsWithStats(InputArray    images,OutputArray   labels,OutputArray   stats,OutputArray   centroids,connectiviity =int           8,int           ltype = cv_32s)

·image:待标记不同连通域的图像单通道,数据类型必须为CV_8U。

·labels:标记不同连通域后的输出图像,与输入图像具有相同的尺寸。

·stats:不同连通域的统计信息矩阵,矩阵的数据类型为CV_32S。矩阵中第i行是标签为i的连通域的统计特性。

·centroids:每个连通域的质心坐标,数据类型为CV_64F。

·connectivity:标记连通域时使用的邻域种类,4表示4-邻域,8表示8-邻域,默认参数为8。

·ltype:输出图像的数据类型,目前支持CV_32S和CV_16U两种数据类型,默认参数为CV_32S。

上图参数是此函数可以获得的信息。

示例 
#include <opencv2/opencv.hpp>
#include <iostream>
#include <vector>using namespace cv; //opencv的命名空间
using namespace std;//主函数
int main()
{//对图像进行距离变换Mat img = imread("E:/opencv/opencv-4.6.0-vc14_vc15/opencv/hua.jpg");if (img.empty()){cout << "请确认图像文件名是否正确" << endl;return -1;}Mat hua, huaBW;//将图像转成二值化的图像,用于统计连通域。cvtColor(img, hua, COLOR_BGR2GRAY);threshold(hua, huaBW, 25, 255, THRESH_BINARY); //二值化//生成随机颜色,用于区分不同连通域。RNG rng(10086); //RNG用来生成随机数,这里用了10086进行初始化。Mat out;int number = connectedComponents(huaBW, out, 8, CV_16U); //统计图像中连通域的个数vector<Vec3b> colors; //vector是一个能够存放任意类型的动态数组,Vec3b可以看成vector<uchar,3>,即一个uchar类型,长度为3的vector向量(简单地说,就是一个uchar类型的数组,长度为3).for (int i = 0; i < number; i++);{//使用均匀分布的随机数确定颜色;rng.uniform(),可以生成指定范围的均匀分布的随机数Vec3b vec3 = Vec3b(rng.uniform(0, 256), rng.uniform(0, 256), rng.uniform(0, 256));colors.push_back(vec3);}//以不同的颜色标记出不同的连通域Mat result = Mat::zeros(hua.size(), img.type());int w = result.cols;int h = result.rows;for (int row = 0; row < h; row++){for (int col = 0; col < w; col++){int label = out.at<uint16_t>(row, col);if (label == 0) //背景的黑色不改变{continue;}result.at<Vec3b>(row, col) = colors[label];}}//显示结果imshow("原图", img);imshow("标记后的图像", result);cout <<"接下来统计连通域信息"<< endl;waitKey(0);Mat stats, centroids;number = connectedComponentsWithStats(huaBW, out, stats, centroids, 8, CV_16U);vector<Vec3b> colors_new;for (int i = 0; i < number; i++){//使用均匀分布的随机数确定颜色Vec3b vec3 = Vec3b(rng.uniform(0, 256), rng.uniform(0, 256), rng.uniform(0, 256));colors_new.push_back(vec3);}//以不同的颜色标记出不同的连通域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_new[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 << ",aera:" << area << endl;}//显示结果imshow("标记后的图像", img);waitKey(0);//等待函数用于显示图像,按下键盘任意键后退出return 0;}

原图:

结果 

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

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

相关文章

让AI帮你说话--GPT-SoVITS教程

有时候我们在录制视频的时候&#xff0c;由于周边环境嘈杂或者录音设备问题需要后期配音&#xff0c;这样就比较麻烦。一个比较直观的想法就是能不能将写好的视频脚本直接转换成我们的声音&#xff0c;让AI帮我们完成配音呢&#xff1f;在语音合成领域已经有很多这类工作了&…

ChatGPT的工作原理

ChatGPT正在做什么...以及为什么它有效? GPT代表"Generative Pre-trained Transformer",是一种基于Transformer架构的生成式预训练模型。只需一次添加一个单词 当ChatGPT生成文本时,它通过不断询问“给定到目前为止的文本,下一个单词应该是什么?”来进行预测。在…

快捷键:IDEA 清理无效导入依赖

快捷键&#xff1a;IDEA 清理无效导入依赖 要批量清理无用的import语句&#xff08;类级别的依赖&#xff09;&#xff0c;可以使用快捷键&#xff1a; Windows/Linux系统&#xff1a;Ctrl Alt OmacOS系统&#xff1a;Cmd Option O 这个快捷键的作用是优化导入&#xff…

1.Mybatis入门

目录 前言 1入门 1.1 入门程序实现 1.2 数据准备 ​编辑 1.3 配置Mybatis 1.4 编写SQL语句 1.5 单元测试 1.6 解决SQL警告与提示 2. JDBC介绍(了解) 2.1 介绍 2.2 代码 2.3 问题分析 2.4 技术对比 3. 数据库连接池 3.1 介绍 3.2 产品 4. lombok 4.1 介绍 4.…

flink源码分析 - jar包中提取主类和第三方依赖

flink版本: flink-1.11.2 提取主类代码位置: org.apache.flink.client.program.PackagedProgram#getEntryPointClassNameFromJar 提取第三方依赖代码位置:org.apache.flink.client.program.PackagedProgram#getJobJarAndDependencies 代码逻辑比较简单&#xff0c;此处不再赘…

AOP+Redisson 延时队列,实现缓存延时双删策略

一、缓存延时双删 关于缓存和数据库中的数据保持一致有很多种方案&#xff0c;但不管是单独在修改数据库之前&#xff0c;还是之后去删除缓存都会有一定的风险导致数据不一致。而延迟双删是一种相对简单并且收益比较高的实现最终一致性的方式&#xff0c;即在删除缓存之后&…

哪些 3D 建模软件值得推荐?

云端地球是一款免费的在线实景三维建模软件&#xff0c;不需要复杂的技巧&#xff0c;只要需要手机&#xff0c;多拍几张照片&#xff0c;就可以得到完整的三维模型&#xff01; 无论是大场景倾斜摄影测量还是小场景、小物体建模&#xff0c;都可以通过云端地球将二维数据向三…

【JLU】校园网linux客户端运行方法

终于给这输入法整好了&#xff0c;就像上面图里那样执行命令就行 写一个开机自启的脚本会更方便&#xff0c;每次都运行也挺烦的 补充了一键运行脚本&#xff0c;文件路径需要自己修改 #!/bin/bashrun_per_prog"sudo /home/d0/ubuntu-drclient-64/DrClient/privillege.s…

为什么3d合并的模型不能移动---模大狮模型网

当你在3D软件中合并模型后&#xff0c;如果无法移动合并后的模型&#xff0c;可能有以下几个可能的原因&#xff1a; 模型被锁定或冻结&#xff1a;在3D软件中&#xff0c;你可能会将模型锁定或冻结以防止意外的移动或编辑。请确保解锁或解冻模型&#xff0c;这样你就可以自由地…

学籍管理系统(c++文件实现)

要求&#xff1a; 实现增删查改&#xff0c;两种方式查询&#xff0c;登录功能 设计&#xff1a; 学生端&#xff1a;可以查询个人成绩 管理员端&#xff1a;对学籍信息增删查改&#xff0c;查看所有信息&#xff0c;单人信息&#xff0c;学籍排序&#xff0c;统计绩点 三个…

【Python】采用OpenCV和Flask来进行网络图像推流的低延迟高刷FPS方法(项目模板)

【Python】采用OpenCV和Flask来进行网络图像推流的低延迟高刷FPS方法&#xff08;项目模板&#xff09; gitee项目模板&#xff1a; 网络图像推流项目模板&#xff08;采用OpenCV和Flask来进行网络图像推流的低延迟高刷FPS方法&#xff09; 前文&#xff1a; 【最简改进】基于…

伊恩·斯图尔特《改变世界的17个方程》相对论笔记

它告诉我们什么&#xff1f; 物质包含的能量等于其质量乘以光速的平方。 为什么重要&#xff1f; 光的速度很快&#xff0c;它的平方绝对是一个巨大的数。1千克的物质释放出的能量相当于史上最大的核武器爆炸所释放能量的约40%。一系列相关的方程改变了我们对空间、时间、物质和…

字符串二叉树遍历

假定一棵二叉树的每个结点都用一个大写字母描述。给定这棵二叉树的前序遍历和中序遍历&#xff0c;求其后序遍历。 输入格式 输入包含多组测试数据。每组数据占两行&#xff0c;每行包含一个大写字母构成的字符串&#xff0c;第一行表示二叉树的前序遍历&#xff0c;第二行表示…

Prompt Learning 的几个重点paper

Prefix Tuning: Prefix-Tuning: Optimizing Continuous Prompts for Generation 在输入token之前构造一段任务相关的virtual tokens作为Prefix&#xff0c;然后训练的时候只更新Prefix部分的参数&#xff0c;PLM中的其他参数固定。针对自回归架构模型&#xff1a;在句子前面添…

测试的常用工具介绍,Fiddler、Postman、JMeter

前言 大家好&#xff0c;我是chowley&#xff0c;今天介绍几个在软件测试领域比较常用的测试工具。 本文将介绍三种常用的测试工具&#xff1a;Fiddler、Postman、JMeter&#xff0c;它们分别在不同测试场景下展现了强大的功能和灵活性。 测试工具 在软件开发和测试领域&am…

vue 使用echarts-gl实现3d旋转地图

之前也有使用过echarts开发项目中涉及到的地图功能&#xff0c;当时使用geo来实现地图轮廓&#xff0c;看上去有种3d的感觉。最近闲来无事看了一份可视化大屏的UI设计图&#xff0c;感觉3d旋转地图挺好玩的&#xff0c;今天就来尝试实现下。 首先安装下echarts和echarts-gl依赖…

MyBatis框架-配置解析

文章目录 Mybatis配置解析核心配置文件environments 环境配置transactionManager 事务管理器dataSource 数据源mappers 映射器Mapper文件Properties优化类型别名&#xff08;typeAliases&#xff09;setting类型处理器&#xff08;typeHandlers&#xff09;对象工厂&#xff08…

shell脚本——条件语句

目录 一、条件语句 1、test命令测试条件表达式 2、整数数值比较 3、字符串比较 4、逻辑测试&#xff08;短路运算&#xff09; 5、双中括号 二、if语句 1、 分支结构 1.1 单分支结果 1.2 双分支 1.3 多分支 2、case 一、条件语句 条件测试&#xff1a;判断某需求是…

MySQL事务和锁02

官网地址&#xff1a;MySQL :: MySQL 5.7 Reference Manual :: 13.3.2 Statements That Cannot Be Rolled Back 欢迎关注留言&#xff0c;我是收集整理小能手&#xff0c;工具翻译&#xff0c;仅供参考&#xff0c;笔芯笔芯. Mysql5.7参考手册 / ... / 不能回滚的语句 13.…

1002. HarmonyOS 开发问题:鸿蒙 OS 技术特性是什么?

1002. HarmonyOS 开发问题&#xff1a;鸿蒙 OS 技术特性是什么? 硬件互助&#xff0c;资源共享 分布式软总线 分布式软总线是多种终端设备的统一基座&#xff0c;为设备之间的互联互通提供了统一的分布式通信能力&#xff0c;能够快速发现并连接设备&#xff0c;高效地分发…