0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

OpenCV4笔记之连通域分析

OpenCV学堂 来源:OpenCV学堂 2023-12-25 17:16 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

Part11. 图像的连通域以及连通域分析

在该系列第六篇文章中,曾经介绍过连通的概念,下面再来回顾一下。

连通:若 S 是图像中的一个像素子集,对于任意的 。如果存在一条由 S 中像素组成的从 p 到 q 的通路,则称 p 在像素集 S 中与 q 连通

连通域是指具有相同属性的连通集合。例如,在一个二值图像中,具有相同像素值的区域构成一个连通域。

所以,连通连通域是两个不同的概念,连通域连通的子集。连通域具有以下特性:

一个连通域中的所有像素都具有相同的性质。

一个连通域中的任意两个像素都可以通过连续的路径连接起来。

一个连通域可以是单连通的,也可以是多连通的。

连通域分析是指在图像中查找标记连通域的算法。这是一种常用的图像处理技术,可以用于目标检测、图像分割和形状识别等等。本文是基于二值图像进行连通域的分析。

Part22. 连通域分析的算法

连通域分析的算法可以分为以下几类:

基于标记的算法:该类算法首先将每个像素分配一个唯一的标记,然后使用某种策略将具有相同标记的像素连接起来。基于标记的算法包括两遍扫描法、种子填充法和快速连通域查找法。

基于邻域查找的算法:该类算法从图像中的一个起始像素开始,逐个检查其邻域像素,如果邻域像素具有相同像素值,则将其加入到当前连通域中。基于邻域查找的算法包括深度优先搜索(DFS)和广度优先搜索(BFS)。

基于分割的算法:该类算法将图像分割成多个区域,每个区域都具有相同的像素值。基于分割的算法包括图论方法和区域生长法。

其中,基于标记的算法是比较常用的连通域分析的算法。

12.1 两遍扫描法

两遍扫描算法的步骤如下

第一遍扫描

从左到右,从上到下遍历图像。

将每个有效像素赋予一个唯一的标记。

第二遍扫描

再次从左到右,从上到下遍历图像。

检查两个相邻像素是否具有相同的标记。

如果两个相邻像素具有相同的标记,则将它们连接起来。

6852f152-a304-11ee-8b88-92fbcf53809c.giftwo-pass.gif

22.2 种子填充法

种子填充算法的步骤如下:

初始化:将图像中的所有像素标记为未访问。

选择一个起始像素作为种子。

将种子像素标记为已访问。

检查种子像素的邻域像素。

如果邻域像素具有相同的像素值,则将其标记为已访问。

如果邻域像素具有不同的像素值,则忽略。

重复步骤 4,直到图像中的所有像素都被标记为已访问或直到没有未访问的邻域像素为止。

68707b8c-a304-11ee-8b88-92fbcf53809c.gifseed-filling.gif

Part33. OpenCV 自带的连通域函数

OpenCV 提供了两个函数:connectedComponents()、connectedComponentsWithStats() 在二值图像中查找连通域。

下面的例子,在图中找到连通域并标记不同的颜色。

#include
#include
#include"opencv2/imgproc.hpp"
#include"opencv2/highgui.hpp"

usingnamespacestd;
usingnamespacecv;

voidlabelColor(Mat&labelImg,Mat&dst)
{
mapcolors;

intwidth=labelImg.cols;
intheight=labelImg.rows;

dst=Mat::zeros(labelImg.size(),CV_8UC3);

ucharr=255*(rand()/(1.0+RAND_MAX));
ucharg=255*(rand()/(1.0+RAND_MAX));
ucharb=255*(rand()/(1.0+RAND_MAX));

for(inti=0;i< height; i++)
    {
        int* data_src = (int*)labelImg.ptr(i);
uchar*data_dst=dst.ptr(i);

for(intj=0;j< width; j++)
        {
            int pixelValue = data_src[j];
            if (pixelValue >=1)
{
if(colors.count(pixelValue)==0)
{
colors[pixelValue]=Scalar(b,g,r);
r=255*(rand()/(1.0+RAND_MAX));
g=255*(rand()/(1.0+RAND_MAX));
b=255*(rand()/(1.0+RAND_MAX));
}

Scalarcolor=colors[pixelValue];
*data_dst++=color[0];
*data_dst++=color[1];
*data_dst++=color[2];
}
else
{
data_dst++;
data_dst++;
data_dst++;
}
}
}
}

intmain(intargc,char**argv){
Matsrc=imread(".../coins.jpg");
imshow("src",src);

Matgray,thresh;
cvtColor(src,gray,cv::COLOR_BGR2GRAY);//灰度化
imshow("gray",gray);

Matgauss;
GaussianBlur(gray,gauss,Size(15,15),0);//降噪

threshold(gauss,thresh,0,255,THRESH_BINARY|THRESH_OTSU);
imshow("thresh",thresh);

Matlabels,stats,centroids;
intnum_labels=connectedComponents(thresh,labels,8,CV_32S);
cout<< "num_labels = " << num_labels << endl;

    Mat result;
    labelColor(labels,result);
    imshow("Connected Components", result);

    waitKey(0);

    return 0;
}
原图和灰度化.png 二值化和标记连通域.png
intconnectedComponents(InputArrayimage,OutputArraylabels,intconnectivity,intltype,intccltype);

其各个参数的含义:

第一个参数 image:输入图像必须是二值图像1。第二个参数 labels:输出图像,其中每个像素值表示其所在连通域的标签。标签的值从 0 开始,依次递增。第三个参数 connectivity:标记连通域时使用的邻域种类。可选的是 4、8,默认值是 8。第四个参数 ltype:输出标签的类型。可以设置为 CV_32S 或 CV_16U,默认值是 CV_32S 。第五个参数 ccltype:标记连通域分析算法的类型。

参数类型 作用
CCL_WU 0 8 邻域和 4 邻域均用 SAUF 算法。
CCL_DEFAULT -1 8 邻域用 BBDT 算法,4 邻域用 SAUF 算法。
CCL_GRANA 1 8 邻域用 BBDT 算法,4 邻域用 SAUF 算法。

connectedComponentsWithStats() 函数除了返回每个连通域的标签之外,还返回每个连通域的其他信息,包括:

面积

外接矩形

中心坐标

intmain(intargc,char**argv){
Matsrc=imread(".../coins.jpg");
imshow("src",src);

Matgray,thresh;
cvtColor(src,gray,cv::COLOR_BGR2GRAY);//灰度化
imshow("gray",gray);

Matgauss;
GaussianBlur(gray,gauss,Size(15,15),0);//降噪

threshold(gauss,thresh,0,255,THRESH_BINARY|THRESH_OTSU);
imshow("thresh",thresh);

Matlabels,stats,centroids;
intnum_labels=connectedComponentsWithStats(thresh,labels,stats,centroids);
cout<< "num_labels = " << num_labels << endl;

    for (int i = 1; i < num_labels; i++)
    {
        int area = stats.at(i,CC_STAT_AREA);
intleft=stats.at(i,CC_STAT_LEFT);
inttop=stats.at(i,CC_STAT_TOP);
intwidth=stats.at(i,CC_STAT_WIDTH);
intheight=stats.at(i,CC_STAT_HEIGHT);
intcx=centroids.at(i,0);
intcy=centroids.at(i,1);

cout<< "Object " << i << ": " << "Area=" << area << ", Left=" << left << ", Top=" << top << ", Width=" << width << ", Height=" << height << ", Centroid=(" << cx << ", " << cy << ")" << endl;

        rectangle(src, Point(left, top), Point(left + width, top + height), Scalar(0,0,255), 2);
        circle(src, Point(cx, cy), 2, Scalar(0,0,255), 2);
    }
    imshow("Connected Components", src);
    waitKey(0);

    return 0;
}

执行结果:

num_labels=8
Object1:Area=17061,Left=344,Top=160,Width=144,Height=151,Centroid=(415,234)
Object2:Area=9655,Left=592,Top=411,Width=108,Height=114,Centroid=(645,467)
Object3:Area=9558,Left=776,Top=441,Width=108,Height=113,Centroid=(828,497)
Object4:Area=17874,Left=435,Top=517,Width=150,Height=152,Centroid=(509,592)
Object5:Area=17502,Left=660,Top=648,Width=148,Height=151,Centroid=(733,723)
Object6:Area=10420,Left=726,Top=864,Width=114,Height=117,Centroid=(782,922)
Object7:Area=15634,Left=628,Top=1075,Width=141,Height=143,Centroid=(698,1146)

Part44. 总结

连通域分析是图像处理中常用的算法之一,用于在二值图像中找到具有相同像素值且相互连接的区域。它在图像处理中具有广泛的应用场景。

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 算法
    +关注

    关注

    23

    文章

    4761

    浏览量

    97147
  • 图像
    +关注

    关注

    2

    文章

    1095

    浏览量

    42162
  • 函数
    +关注

    关注

    3

    文章

    4406

    浏览量

    66841
  • OpenCV
    +关注

    关注

    33

    文章

    651

    浏览量

    44420

原文标题:OpenCV4笔记 之 连通域分析

文章出处:【微信号:CVSCHOOL,微信公众号:OpenCV学堂】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    ACER 370笔记本电脑主板电路图

    本帖最后由 gk320830 于 2015-3-9 03:41 编辑 ACER 370笔记本电脑主板电路图
    发表于 08-16 20:45

    爱鼓捣stm32笔记

    爱鼓捣stm32笔记1-4
    发表于 06-16 17:37

    STM32笔记 EXIT(外部中断)精选资料分享

    /O映像三、中断服务四、配置流程(代码解析)五、中断函数处理在上一篇STM32笔记 GPIO引脚中,有用到 EXIT外部中断作为 Key输入触发,所以本篇来...
    发表于 08-05 06:10

    华硕ASUS F7KR R2.0.0笔记本原理图

    华硕ASUS F7KR R2.0.0笔记本原理图:
    发表于 03-02 16:15 799次下载
    华硕ASUS F7KR R2.0.0<b class='flag-5'>笔记</b>本原理图

    简易AD13笔记

    个人资料心得,一点一点,不多,请见谅!13笔记,有点用
    发表于 11-17 11:43 10次下载

    STM32各模块学习笔记

    ..........................................................4 STM32笔记四 STM32中定时器的时钟源............................15
    发表于 11-30 03:32 3323次阅读

    联想电脑维修实际案例--G470笔记本电路分析

    联想电脑维修实际案例--G470笔记本电路分析
    发表于 02-03 10:45 339次下载

    惠普G4-2000笔记本的电路原理图合集

    本文档的主要内容详细介绍的是惠普1000 G4-2000 CQ35-701TU CQ45笔记本的电路原理图合集。
    发表于 10-29 08:00 20次下载
    惠普G<b class='flag-5'>4</b>-2000<b class='flag-5'>笔记</b>本的电路原理图合集

    基于opencv4和Yolo-Fastest,实现PC和单片机通信,控制步进电机捕获目标

    效果视频 基于opencv4和yolo,实现PC和单片机通信,控制步进电机捕获目标
    发表于 11-23 17:36 16次下载
    基于<b class='flag-5'>opencv4</b>和Yolo-Fastest,实现PC和单片机通信,控制步进电机捕获目标

    [笔记]|[stm32]|[寄存器存储器区别]|[PWM]|[串口]|[Timer]stm32f103笔记

    [笔记]|[stm32]|[寄存器存储器区别]|[PWM]|[串口]|[Timer]stm32f103笔记笔记为18.12.21者期末复习所写 ——仅作为自己期末复习以及过后查阅
    发表于 12-06 18:51 10次下载
    [<b class='flag-5'>笔记</b>]|[stm32]|[寄存器存储器区别]|[PWM]|[串口]|[Timer]stm32f103<b class='flag-5'>笔记</b>

    dell 7559笔记本电路图方框图免费下载

    dell 7559笔记本电路图方框图免费下载。
    发表于 03-28 15:46 52次下载

    如何在Raspberry Pi 3上安装OpenCV4

    今天我们将学习如何在 Raspberry Pi 3 上安装 OpenCV4 库,以便我们可以将其用于计算机视觉应用程序。这将允许 OpenCV 在像 Pi 这样的便携式设备上运行,从而打开许多可能性的大门。所以让我们开始吧
    的头像 发表于 09-08 16:09 2345次阅读
    如何在Raspberry Pi 3上安装<b class='flag-5'>OpenCV4</b>库

    OpenCV4源码分析

    宏定义必须写在函数之外,其作用是 #define 开始,到源程序结束。如果要提前结束它的作用则用 #undef 命令
    的头像 发表于 02-22 10:00 1767次阅读
    <b class='flag-5'>OpenCV4</b>源码<b class='flag-5'>分析</b>

    学习OpenCV4的系统化路线图

    OpenCV4发布测试版本开始,作者就一直关注!根据自己近十年图像处理OpenCV开发相关工作经验,花了七个月的时间,针对OpenCV4、精心选择OpenCV中常用模块与知识点,构建
    的头像 发表于 07-05 11:30 1209次阅读
    学习<b class='flag-5'>OpenCV4</b>的系统化路线图

    联想E46L DAOLL6笔记本电脑图纸

    联想E46L DAOLL6笔记本电脑图纸
    发表于 12-20 15:27 6次下载