OpenCV Python连通域处理:connectedComponents与connectedComponentsWithStats详解

Theo
Theo
发布时间:2026-10-16 | 5人浏览过
原创

本文详细介绍OpenCV中用于连通域处理的两个核心函数:connectedComponents()与connectedComponentsWithStats()。通过对比两者在参数设置、返回值结构及信息丰富度上的差异,结合Python代码实例,演示如何从二值图像中提取连通域、获取边界框、面积及中心点等关键统计信息,并探讨预处理对检测结果的影响。

1、两个函数介绍

总体而言,connectedComponents()函数仅生成一个标记图像,其中不同的连通区域使用不同的标记值,且输出图像的尺寸与原始输入图像保持一致。而connectedComponentsWithStats()函数不仅能完成上述标记任务,还能额外返回每个连通区域的关键几何信息,包括边界框(bounding box)、区域面积(area)以及质心(centroid)。

1.1什么是连通域

连通区域通常指在图像中由具有相同像素值且空间位置相邻的前景像素点所构成的图像区域。连通区域分析的目的即是将这些独立的连通区域识别出来并进行标记。

连通区域分析是计算机视觉(CVPR)及图像分析处理领域中一种基础且广泛应用的技术手段。

其应用场景广泛,例如在OCR识别中用于字符分割与提取(涵盖车牌识别、文本识别、字幕识别等场景);在视觉跟踪中用于运动前景目标的分割与提取(如行人入侵检测、遗留物体检测、基于视觉的车辆检测与跟踪等);以及在医学图像处理中用于感兴趣目标区域的提取等。简言之,在需要将前景目标从背景中提取出来以便进行后续处理的应用场景中,均可使用连通区域分析方法。通常情况下,该方法处理的对象是经过二值化处理后的图像。

1.2 cv2.connectedComponents()

函数各参数意义:

num_objects, labels = cv2.connectedComponents(image)

参数介绍如下:

image:即输入图像,必须为二值图,具体表现为8位单通道图像。因此,在调用此函数前,必须对输入图像进行二值化处理。

返回值:

num_labels:表示图像中所有连通域的总数。

labels:图像中每个像素的标记值,使用数字1、2、3……进行表示(不同的数字代表不同的连通域)。

1.3 cv2.connectedComponentsWithStats()

该函数的作用是对图像执行连通域提取,并返回所找到连通域的详细信息,包括retval、labels、stats和centroids。

num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(image, connectivity=8, ltype=None)

参数介绍如下:

  • image:即输入图像,必须是二值图,即8位单通道图像。(因此输入图像必须先进行二值化处理才能被这个函数接受)
  • connectivity:可选值为4或8,分别表示使用4连通还是8连通规则。
  • ltype:输出图像标记的数据类型,目前支持CV_32S和CV_16U。

返回值:

  • num_labels:所有连通域的数目
  • labels:图像上每一像素的标记,用数字1、2、3…表示(不同的数字表示不同的连通域)
  • stats:每一个标记的统计信息,是一个5列的矩阵,每一行对应每个连通区域的外接矩形的x、y、width、height和面积,示例如下: 0 0 720 720 291805
  • centroids:连通域的中心点

2、代码实践

这两个函数的用途基本共通,但cv2.connectedComponentsWithStats函数返回的信息量更为丰富,因此此处主要展示该函数的应用。

import cv2
import numpy as np
# 读入图片
img = cv2.imread("001.jpg")
# 中值滤波,去噪
img = cv2.medianBlur(img, 3)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.namedWindow('original', cv2.WINDOW_AUTOSIZE)
cv2.imshow('original', gray)
# 阈值分割得到二值化图片
ret, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
# 膨胀操作
kernel2 = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
bin_clo = cv2.dilate(binary, kernel2, iterations=2)
# 连通域分析
num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(bin_clo, connectivity=8)
# 查看各个返回值
# 连通域数量
print('num_labels = ',num_labels)
# 连通域的信息:对应各个轮廓的x、y、width、height和面积
print('stats = ',stats)
# 连通域的中心点
print('centroids = ',centroids)
# 每一个像素的标签1、2、3.。。,同一个连通域的标签是一致的
print('labels = ',labels)
# 不同的连通域赋予不同的颜色
output = np.zeros((img.shape[0], img.shape[1], 3), np.uint8)
for i in range(1, num_labels):
    mask = labels == i
    output[:, :, 0][mask] = np.random.randint(0, 255)
    output[:, :, 1][mask] = np.random.randint(0, 255)
    output[:, :, 2][mask] = np.random.randint(0, 255)
cv2.imshow('oginal', output)
cv2.waitKey()
cv2.destroyAllWindows()

打印出的连通域的信息如下:

重点是理解stats和 labels 参数的意义,其他的参数都容易理解:

labels :对原始图中的每一个像素都打上标签,背景为0,连通域打上1,2,3。。。的标签,同一个连通域的像素打上同样的标签。相当与对每一个像素进行了分类(分割)

stats:每一连通域的信息,表示每个连通区域的外接矩形(起始点的x、y、宽和高)和面积

 

连通域检测的效果图:

3、总结

(1)连通域分析可以实现将前景目标提取出来以便后续进行处理(类似于轮廓处理)

(2)重点是cv2.connectedComponentsWithStats函数中stats和 labels 参数的意义

labels :对原始图中的每一个像素都打上标签,背景为0,连通域打上1,2,3。。。的标签,同一个连通域的像素打上同样的标签。相当与对每一个像素进行了分类(分割)

stats:每一连通域的信息,表示每个连通区域的外接矩形(起始点的x、y、宽和高)和面积

(3)从上面的例子可以看出,因物体有重叠会把不同物体的多个连通域 计为一个连通域,所以在连通域分析前可以先进行效果更好的分割和预处理操作。

以上就是OpenCV学习记录python实现连通域处理函数的详细内容,更多关于python opencv连通域处理函数的资料请关注本站其它相关文章!

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表