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

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

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

基本概念解释

-图像联通组件

-四邻域与八邻域联通

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.mrgr.cn/news/61541.html

相关文章:

  • conntrack iptables 安全组
  • 自动驾驶---E2E架构演进
  • 深入浅出 OpenResty
  • 一文流:Maven精讲
  • GoZero项目中解决`go.mod`和`go.sum`校验和不匹配问题的解决方案
  • STM32的存储结构
  • netframework安装不上怎么办
  • LeetCode 热题 100 回顾8
  • Java——lambda表达式和StreamAPI
  • AI-Talk开发板之启动问题
  • Windows 下实验视频降噪算法 MeshFlow 详细教程
  • Java学习第六天~第七天-程序控制结构:
  • 《操作系统真象还原》第4章 保护模式入门
  • 使用Node.js内置的http模块创建简单的HTTP服务器,并根据请求的路径返回不同的文本响应。
  • LeetCode 3211.生成不含相邻零的二进制字符串:二进制枚举+位运算优化
  • 计算机毕业设计——ssm基于HTML5的互动游戏新闻网站的设计与实现录像演示2021
  • modelsim命令:add atv
  • 【Java数据结构】树】
  • 基于SSM积分商城管理系统的设计与实现(源码+lw+部署文档+讲解等)
  • 小红书图文无水印下载
  • 进一步认识ICMP协议
  • MySQL用户权限管理属于SQL语句中的DCL语句
  • 深入理解阻塞队列
  • 鸿蒙生态崛起:开发者的机遇与挑战
  • 数据结构————map,set详解
  • Rust实现Kafka - 前言