加强版 第四节联通组件分析与演示

news2024/11/27 18:35:14

得到二值图像的目的是为了后面的分析

基本概念解释

-图像联通组件

-四邻域与八邻域联通

ccl联通组件标记

通过四邻域和八邻域来对图像进行边缘寻找与噪声处理的功能

常见算法来寻找联通组件

-基于像素扫描方法

-基于块扫描的方法

-两步法扫描

  • API: OpenCV中支持连通组件扫描的API有两个,一个是带统计信息connectedComponentsWithStats 一个不带统计信息connectedComponents
  • 黑色背景
1. 整体功能

• connectedComponentsWithStats是OpenCV中用于图像分析的一个重要函数,主要用于对图像中的连通区域进行标记、统计相关信息和计算质心。

2. 输入参数(重点是前两个)

• image:这是进行连通区域分析的基础。通常是一幅经过预处理的二值图像,例如,通过阈值分割得到的图像,其中白色(非零)像素表示前景物体,黑色(零)像素表示背景。函数会根据这些前景像素的分布来确定连通区域。

• labels:在调用函数之前就创建好的一个矩阵,用于存储连通区域的标签信息。它的尺寸和image相同,数据类型为CV_32S(前面提到过这个类型的好处)。在函数执行过程中,每个像素会被赋予一个标签值,代表它所属的连通区域。

3. 输出参数(重点是中间两个)

• stats:这是一个矩阵,每一行代表一个连通区域(背景区域通常不包含在内)。这个矩阵包含了非常有用的统计信息,比如连通区域的外接矩形的左上角坐标(x和y)、宽度、高度和面积等。这些信息可以用于后续对连通区域的形状、大小等特征的分析。

• centroids:用于存储每个连通区域(不包括背景)的质心坐标。质心坐标可以帮助确定物体在图像中的中心位置,对于目标跟踪、物体定位等应用场景很有帮助。

4. 连通性参数

• 函数中的8参数用于指定连通性。8连通性意味着一个像素与其周围的8个像素(上下左右、四个对角)都被认为是连通的;如果是4连通性,一个像素只与其上下左右4个像素连通。这个参数会影响连通区域的划分结果。

5. 数据类型和算法参数

• CV_32S参数是为了确保labels矩阵的数据类型和函数内部的处理要求相匹配,保证标签能够正确存储。CCL_DEFAULT参数通常用于指定使用默认的连通组件标记算法,在大多数情况下不需要改变这个参数,它可以保证算法以比较合理的方式运行。


方便个人理解我将源代码分为三部分,基于当前的学习阶段,我将代码敲完之后发现25个物体被识别成了27个,后来发现右边又很小的一条白条,所以此API对于黑底背景十分敏感。

第一步思路先将图像转化为灰度图像后进行高斯模糊,可以更好地帮助进行二值化。

int main(int argc, char** argv) {
    Mat src = imread("C:/newword/image/3.png");
    if (src.empty()) {
        printf("could not find image file");
        return -1;
    }
    namedWindow("input", WINDOW_AUTOSIZE);
    imshow("input", src);
    GaussianBlur(src, src, Size(3, 3), 0);
    Mat gray, binary;
    cvtColor(src, gray, COLOR_BGR2GRAY);to那个
    threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
    imshow("binary", binary);



后面需要将目标图像中的关键信息用连通组件进行寻找,首先要建立一个新的同等规模的图像,将其初始化,规模为32s,之后将目标图像用connectedComponentsWithStats函数进行连通寻找,我们想要将目标图像中的关键信息的颜色改变;那就需要建立同等规模的三通道容器,里面包含了BGR元素,首先将元素背景设置为黑色,之后将经过连通寻找后的图像从1开始遍历,并将连通其中的颜色随机化,注:此代码只有标记功能没有上色功能

void ccl_stats_demo(Mat& image) {
    Mat labels = Mat::zeros(image.size(), CV_32S);//创建了一个与给定图像 image 尺寸相同的矩阵 labels,数据类型为 CV_32S(32 位有符号整数),并且初始值全为零。
    Mat stats, centroids;
    int num_labels = connectedComponentsWithStats(image, labels, stats, centroids, 8, CV_32S, CCL_DEFAULT);
    vector<Vec3b> colorTable(num_labels);//vector动态数组库,vec3b三通道,color table容器
    colorTable[0] = Vec3b(0, 0, 0);//将背景设置为黑色
    for (int i = 1; i < num_labels; i++) {
        colorTable[i] = Vec3b(rng.uniform(0, 256), rng.uniform(0, 256), rng.uniform(0, 256));
    }

下面代码是将刚标记的连通图进行上色

Mat result = Mat::zeros(image.size(), CV_8UC3);
int w = result.cols;
int h = result.rows;
for (int row = 0; row < h; row++) {
    for (int col = 0; col < w; col++) {
        int label = labels.at<int>(row, col);
        result.at<Vec3b>(row, col) = colorTable[label];//上色
    }

}



最后将连通标记上色后的图片用矩形框出来,并显示左上角信息与原点位置

    for (int i = 1; i < num_labels; i++) {
        int cx = centroids.at<double>(i, 0);
        int cy = centroids.at<double>(i, 1);
        int x = stats.at<int>(i, CC_STAT_LEFT);
        int y = stats.at<int>(i, CC_STAT_TOP);
        int width = stats.at<int>(i, CC_STAT_WIDTH);
        int height = stats.at<int>(i, CC_STAT_HEIGHT);
        int area = stats.at<int>(i, CC_STAT_AREA);
        circle(result, Point(cx, cy), 3, Scalar(0, 0, 255), 2, 8, 0);//circle(result, Point(cx, cy), 3, Scalar(0, 0, 255), 2, 8, 0);:在结果图像result上,以质心坐标(cx, cy)为圆心,绘制一个半径为 3 的红色(Scalar(0, 0, 255))圆圈,线宽为 2,采用 8 连接方式。这个圆圈标记了连通区域的质心位置。
        Rect box(x, y, width, height);
        rectangle(result, box, Scalar(0, 255, 0), 2, 8);//Rect box(x, y, width, height);和rectangle(result, box, Scalar(0, 255, 0), 2, 8);:创建一个以(x, y)为左上角坐标,宽度为width,高度为height的矩形box,然后在结果图像上绘制一个绿色(Scalar(0, 255, 0))的矩形框,线宽为 2,采用 8 连接方式。这个矩形框标记了连通区域的外接矩形。rectangle(图像矩阵, 矩形区域, 颜色, 线宽, 线类型, 偏移量)。例如代码中rectangle(result, box, Scalar(0, 255, 0), 2, 8);,result是要绘制矩形的图像,box是一个Rect类型的矩形区域对象,Scalar(0, 255, 0)表示绿色的颜色,2是线宽,8是线类型(连接方式)。
        putText(result, format("%d", area), Point(x, y), FONT_HERSHEY_PLAIN, 1.0, Scalar(0, 255, 0), 1);
    }
    putText(result, format("number: %d", num_labels - 1), Point(10, 10), FONT_HERSHEY_PLAIN, 1.0, Scalar(0, 255, 0), 1);//


一、第一个putText

1. 参数解释

• result:要在其上绘制文本的图像。

• format("%d", area):要绘制的文本内容,这里是将整数area(可能是某个连通区域的面积值)格式化为字符串。

• Point(x, y):文本在图像上的位置坐标,这里的坐标通常是与某个连通区域相关的位置,比如外接矩形的左上角坐标。

• FONT_HERSHEY_PLAIN:字体类型,这里表示使用一种简单的字体风格。

• 1.0:字体大小。

• Scalar(0, 255, 0):文本的颜色,这里是绿色。

• 1:文本的线宽。

2. 作用

• 在结果图像上,在特定位置(与连通区域相关的位置)绘制文本,显示该连通区域的面积值。

二、第二个putText

1. 参数解释

• result:同样是要在其上绘制文本的图像。

• format("number: %d", num_labels - 1):要绘制的文本内容,这里显示的是“number: ”加上连通区域的数量减 1。

• Point(10, 10):文本在图像上的位置坐标,这里是固定的坐标(10, 10)。

• FONT_HERSHEY_PLAIN:字体类型。

• 1.0:字体大小。

• Scalar(0, 255, 0):文本的颜色,绿色。

• 1:文本的线宽。

2. 作用

• 在结果图像上的固定位置(10, 10)绘制文本,显示连通区域的总数(排除背景区域后的数量)

    printf("total labels : %d \n", (num_labels - 1));
    imshow("CCL demo", result);
}

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

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

相关文章

闯关leetcode——232. Implement Queue using Stacks

大纲 题目地址内容 解题代码地址 题目 地址 https://leetcode.com/problems/implement-queue-using-stacks/description/ 内容 Implement a first in first out (FIFO) queue using only two stacks. The implemented queue should support all the functions of a normal …

【Unity基础】初识UI Toolkit - 编辑器UI

&#xff08;本文所需图片在文章上面的资源中&#xff0c;点击“立即下载”。&#xff09; 本文介绍了如何通过UI工具包&#xff08;UI Toolkit&#xff09;来创建一个编辑器UI。 一、创建项目 1. 打开Unity创建一个空项目&#xff08;任意模板&#xff09;&#xff0c;这里我…

什么?Flutter 又要凉了? Flock 是什么东西?

今天突然看到这个消息&#xff0c;突然又有一种熟悉的味道&#xff0c;看来这个月 Flutter “又要凉一次了”&#xff1a; 起因 flutter foundation 决定 fork Flutter 并推出 Flock 分支用于自建维护&#xff0c;理由是&#xff1a; foundation 推测 Flutter 团队的劳动力短缺…

windows文件实时同步

在现今这个高效运转的工作时代&#xff0c;数据同步与备份的重要性愈发凸显。特别是对于Windows用户&#xff0c;实现文件在不同设备间的实时流转&#xff0c;不仅能够显著提升工作效率&#xff0c;更是数据安全的一道重要防线。接下来&#xff0c;我们将深入剖析Windows文件实…

全桥PFC电路及MATLAB仿真

一、PFC电路原理概述 PFC全称“Power Factor Correction”&#xff08;功率因数校正&#xff09;&#xff0c;PFC电路即能对功率因数进行校正&#xff0c;或者说是能提高功率因数的电路。是开关电源中很常见的电路。功率因数是用来描述电力系统中有功功率&#xff08;实际使用…

rom定制系列------红米note8_miui14安卓13定制修改固件 带面具root权限 刷写以及界面预览

&#x1f49d;&#x1f49d;&#x1f49d;红米note8机型代码&#xff1a;ginkgo。高通芯片。此固件官方最终版为稳定版12.5.5安卓11的版本。目前很多工作室需要高安卓版本的固件来适应他们的软件。并且需要root权限。根据客户要求。修改固件为完全root。并且修改为可批量刷写的…

【传知代码】图像处理解决种子计数方法

文章目录 一、背景及意义介绍研究背景农业考种需求传统计数方法的局限性人工计数仪器设备计数 研究意义提高育种效率提高计数准确性广泛的适用性数据存档与分析便利 二、概述三、材料与数据准备以及方法介绍整体流程图像采集图像预处理形态学操作腐蚀运算开运算 图像二值化种子…

【鸿蒙HarmonyOS实战:通过华为应用市场上架测试版App实现HBuilder X打包的UniApp项目的app转hap教程(邀请码)方式教程详解】

鸿蒙HarmonyOS实战&#xff1a;通过华为应用市场上架测试版App实现HBuilder X打包的UniApp项目的app转hap教程&#xff08;邀请码&#xff09;方式详解 在使用uniapp打包的鸿蒙项目的过程中&#xff0c;由于生成的是app文件&#xff0c;而hdc传给鸿蒙HarmonyOS系统需要的是hap文…

2025选题|基于协同推荐的黔醉酒业白酒销售系统

作者主页&#xff1a;编程指南针 作者简介&#xff1a;Java领域优质创作者、CSDN博客专家 、CSDN内容合伙人、掘金特邀作者、阿里云博客专家、51CTO特邀作者、多年架构师设计经验、多年校企合作经验&#xff0c;被多个学校常年聘为校外企业导师&#xff0c;指导学生毕业设计并参…

从0开始学python-day17-数据结构2

2.3 队列 队列(Queue)&#xff0c;它是一种运算受限的线性表,先进先出(FIFO First In First Out) 队列是一种受限的线性结构 受限之处在于它只允许在表的前端&#xff08;front&#xff09;进行删除操作&#xff0c;而在表的后端&#xff08;rear&#xff09;进行插入操作 P…

Element Plus在Vue3的安装

本来想下载element ui 的&#xff0c;但是不支持报错了 所以我们使用element plus 在终端使用下命令下载 npm install element-plus --save 然后就可以在package.json里面看到所下载的版本号了 之后在main.js中根据自己的的情况配置Element-Plus // main.ts import { create…

App Inventor 2 列表显示框能否实现多选?

Q&#xff1a;列表显示框有没有办法做到多选的功能&#xff1f; // 问题分析 // AppInventor2列表显示框原生并没有多选功能&#xff0c;只能点击其中一项&#xff0c;然后触发“选择完成时”这个事件&#xff0c;那么有没有办法做到多选呢&#xff1f; // 问题思路 // 经过…

Topaz Video AI for Mac 视频无损放大软件安装教程【保姆级,操作简单轻松上手】

Mac分享吧 文章目录 Topaz Video AI for Mac 视频无损放大软件 安装完成&#xff0c;软件打开效果一、Topaz Video AI 视频无损放大软件 Mac电脑版——v5.3.5⚠️注意事项&#xff1a;1️⃣&#xff1a;下载软件2️⃣&#xff1a;安装软件&#xff0c;将安装包从左侧拖入右侧文…

Linux基础—基础命令及相关知识5(ubuntu网络配置)

网络的配置方法 centos网络配置 centos的网卡位置 /etc/sysconfig/network-scripts/ifcfg-ens33(centos网卡文件) bootproto表示获得IP地址的方式是静态的还是动态 onboot表示启动系统时是否激活该网络接口 设置IP地址&#xff0c;子网掩码&#xff0c;网关&#xff0c;dns…

数据分析与效果评估的有效方法与实践探讨

内容概要 在现代社会中&#xff0c;数据分析与效果评估已成为各类项目管理和决策制定中的重要组成部分。首先&#xff0c;数据分析为我们提供了一种系统化的方法&#xff0c;以深入了解所收集数据的内涵与趋势。通过对数据进行整理、分类和分析&#xff0c;我们能够发现潜在的…

一篇文章入门傅里叶变换

文章目录 傅里叶变换欧拉公式傅里叶变换绕圈记录法质心记录法傅里叶变换公式第一步&#xff1a;旋转的表示第二步&#xff1a;缠绕的表示第三步&#xff1a;质心的表示最终步&#xff1a;整理积分限和系数 参考文献 傅里叶变换 在学习傅里叶变换之前&#xff0c;我们先来了解一…

电源完整性

电源分配系统 电源分配系统:Power Distribution Network(简称 PDN) 真正用电节点在 Die&#xff0c;所以PDN系统包含 PCB 和 Package上的部分 PCB 上:VRM、大电容、小电容、电源平面、地平面 Package内:电容、电源平面、地平面 电源噪声的产生 稳压电源芯片本身的输出不恒定&a…

Springboot 日志处理

一、日志存入数据库&#xff08;AOP&#xff09; 1.引入aop依赖 <!-- aop依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> 2.创建aop包&#…

SpringBoot3使用MyBatisPlus时遇到的问题 Invalid bean definition with name

问题&#xff1a; 运行springboot3项目报错&#xff1a;Invalid bean definition with name ‘XXXMapper’ defined in file… 原因&#xff1a;springboot3支持的mabits-plus依赖不同导致的 解决办法&#xff1a; 修改为&#xff1a; <dependency><groupId>com…

Chrome和Firefox哪款浏览器的密码管理更安全

在当今数字化时代&#xff0c;浏览器已成为我们日常生活中不可或缺的工具。其中&#xff0c;谷歌Chrome和Mozilla Firefox是两款广受欢迎的浏览器。除了浏览网页外&#xff0c;它们还提供了密码管理功能&#xff0c;帮助用户保存和管理登录凭证。然而&#xff0c;关于哪款浏览器…