✒️ 连接组件是图像分析中最常用的算法之一,本文主要介绍如何使用该方法进行组件标记,同时还可以运用其实现状态统计,具体内容可以详细阅读下文~
目录
- 连通组件
- 连通组件标记
- 连通组件状态统计
连通组件
连通组件标记
✔️ 概念: 连接组件标记算法(connected component labeling algorithm)是图像分析中最常用的算法之一,算法的实质是扫描二值图像的每个像素点,对于像素值相同的而且相互连通分为相同的组(group),最终得到图像中所有的像素连通组件。
✔️ 函数: retval, labels =cv2.connectedComponents(image, connectivity, ltype)
输入
- image, // 输入二值图像,黑色背景
- connectivity = 8, // 连通域,默认是8连通
- ltype = CV_32, // 输出的labels类型,默认是CV_32S
输出
- retval, //num_labels
- labels, // 输出的标记图像,背景index=0
✔️ 示例:
import cv2 as cvimport numpy as npsrc = cv.imread("pill.png")
src = cv.GaussianBlur(src, (3, 3), 0)gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)cv.imshow("binary", binary)cv.imwrite('binary.png', binary)output = cv.connectedComponents(binary, connectivity=8, ltype=cv.CV_32S)num_labels = output[0]print(num_labels) # output: 5labels = output[1]# 构造颜色colors = []for i in range(num_labels): b = np.random.randint(0, 256) g = np.random.randint(0, 256) r = np.random.randint(0, 256) colors.append((b, g, r))colors[0] = (0, 0, 0)# 画出连通图h, w = gray.shapeimage = np.zeros((h, w, 3), dtype=np.uint8)for row in range(h): for col in range(w): image[row, col] = colors[labels[row, col]]cv.imshow("colored labels", image)cv.imwrite("labels.png", image)print("total componets : ", num_labels - 1)cv.waitKey(0)cv.destroyAllWindows()
连通组件状态统计
✔️ 函数: retval, labels, stats, centroids=cv2.connectedComponentsWithStats(image, connectivity, ltype )
相关的统计信息包括在输出stats的对象中,每个连通组件有一个这样的输出结构体.
- CC_STAT_LEFT: 连通组件外接矩形左上角坐标的X位置信息
- CC_STAT_TOP: 连通组件外接左上角坐标的Y位置信息
- CC_STAT_WIDTH: 连通组件外接矩形宽度
- CC_STAT_HEIGHT: 连通组件外接矩形高度
- CC_STAT_AREA: 连通组件的面积大小,基于像素多少统计
- Centroids输出的是每个连通组件的中心位置坐标(x, y)
✔️ 示例:
import cv2 as cvimport numpy as npsrc = cv.imread("granule.png")
src = cv.GaussianBlur(src, (3, 3), 0)gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)ret, binary_ = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)# 使用开运算去掉外部的噪声kernel = cv.getStructuringElement(cv.MORPH_RECT, (3, 3))binary = cv.morphologyEx(binary_, cv.MORPH_OPEN, kernel)cv.imshow("binary", binary_)num_labels, labels, stats, centers = cv.connectedComponentsWithStats(binary, connectivity=8, ltype=cv.CV_32S)colors = []for i in range(num_labels): b = np.random.randint(0, 256) g = np.random.randint(0, 256) r = np.random.randint(0, 256) colors.append((b, g, r))colors[0] = (0, 0, 0)image = np.copy(src)for t in range(1, num_labels, 1): x, y, w, h, area = stats[t] cx, cy = centers[t] # 标出中心位置 cv.circle(image, (np.int32(cx), np.int32(cy)), 2, (0, 255, 0), 2, 8, 0) # 画出外接矩形 cv.rectangle(image, (x, y), (x+w, y+h), colors[t], 1, 8, 0) cv.putText(image, "No." + str(t), (x, y), cv.FONT_HERSHEY_SIMPLEX, .5, (0, 0, 255), 1); print("label index %d, area of the label : %d"%(t, area)) cv.imshow("colored labels", image) cv.imwrite("labels.png", image) print("total number : ", num_labels - 1)input = cv.imread("granule.png")connected_components_stats_demo(input)
未完待续~
更多Opencv教程将持续发布!
欢迎关注哟~❤️❤️❤️