import cv2 as cv
import numpy as np
def connected_components_demo(src):
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)
output = cv.connectedComponents(binary, connectivity=8, ltype=cv.CV_32S)
num_labels = output[0]
labels = 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.shape
image = 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)
count = num_labels - 1
print("total rice : ", count)
return image,count
src = cv.imread("../images/rice.png")
h, w = src.shape[:2]
dst, count = connected_components_demo(src)
result = np.zeros([h, w*2, 3], dtype=src.dtype)
result[0:h,0:w,:] = src
result[0:h,w:2*w,:] = dst
cv.putText(result, "input", (10, 30), cv.FONT_ITALIC, 1.0, (0, 0, 255), 2)
cv.putText(result, "colored labels(total rice: %s)"%count, (w+10, 30), cv.FONT_ITALIC, 1.0, (0, 0, 255), 2)
cv.imshow("result", result)
cv.waitKey(0)
cv.destroyAllWindows()
连接组件标记算法(connected component labeling algorithm)是图像分析中最常用的算法之一,算法的实质是扫描二值图像的每个像素点,对于像素值相同的而且相互连通分为相同的组(group),最终得到图像中所有的像素连通组件。扫描的方式可以是从上到下,从左到右,对于一幅有N个像素的图像来说,最大连通组件个数为N/2。扫描是基于每个像素单位,OpenCV中进行连通组件扫码调用的时候必须保证背景像素是黑色、前景像素是白色。最常见的连通组件扫码有如下两类算法:
OpenCV中支持连通组件扫描的API有两个,一个是带统计信息一个不带统计信息。
不带统计信息的API及其解释如下:
retval, labels = cv.connectedComponents(image[, labels[, connectivity[, ltype]]])
image
: 输入二值图像,黑色背景labels
: 输出的标记图像,背景index=0connectivity = 8
: 连通域,默认是8连通ltype = CV_32S
: 输出的labels类型,默认是CV_32S所有内容均来源于贾志刚老师的知识星球——OpenCV研习社,本文为个人整理学习,已获得贾老师授权,有兴趣、有能力的可以加入贾老师的知识星球进行深入学习。