python中的连接组件标签
Posted
技术标签:
【中文标题】python中的连接组件标签【英文标题】:connected component labeling in python 【发布时间】:2018-03-08 14:07:42 【问题描述】:如何用open cv在python中实现连通分量标注? 这是一个图像示例:
我需要连接组件标签来分隔黑白图像上的对象。
【问题讨论】:
【参考方案1】:OpenCV 3.0 docs for connectedComponents()
没有提到 Python,但它实际上已经实现。参见例如this SO question。在 OpenCV 3.4.0 及更高版本上,文档确实包含 Python 签名,如 current master docs 所示。
函数调用很简单:num_labels, labels_im = cv2.connectedComponents(img)
,您可以指定参数connectivity
来检查 4 路或 8 路(默认)连接。不同的是,4路连接只检查顶部、底部、左侧和右侧像素,看看它们是否连接; 8 路检查八个相邻像素中的任何一个是否连接。如果你有对角线连接(就像你在这里做的那样)你应该指定connectivity=8
。请注意,它只是对每个组件进行编号,并从 0 开始为它们提供递增的整数标签。因此,所有零都连接,所有零都连接,等等。如果您想将它们可视化,您可以将这些数字映射到特定颜色。我喜欢将它们映射成不同的色调,将它们组合成一张 HSV 图像,然后再转换成 BGR 来显示。这是您的图片示例:
import cv2
import numpy as np
img = cv2.imread('eGaIy.jpg', 0)
img = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)[1] # ensure binary
num_labels, labels_im = cv2.connectedComponents(img)
def imshow_components(labels):
# Map component labels to hue val
label_hue = np.uint8(179*labels/np.max(labels))
blank_ch = 255*np.ones_like(label_hue)
labeled_img = cv2.merge([label_hue, blank_ch, blank_ch])
# cvt to BGR for display
labeled_img = cv2.cvtColor(labeled_img, cv2.COLOR_HSV2BGR)
# set bg label to black
labeled_img[label_hue==0] = 0
cv2.imshow('labeled.png', labeled_img)
cv2.waitKey()
imshow_components(labels_im)
【讨论】:
感谢 alexander,我已经在使用 cv2.connectedComponents,但我发现这样的错误,AttributeError: 'module' object has no attribute 'connectedComponents' 啊,那么您可能使用的是尚未移植绑定的旧版 OpenCV。您使用的是什么版本的 OpenCV?如果你不能升级,那么考虑另一个库,比如scikit-image
; here's an example 与该库。或者,您可以检测轮廓并使用它来标记图像。
我的 opencv 版本 '2.4.13'。非常感谢,很有帮助,我觉得我的opencv需要升级了
@AlexanderReynolds 非常感谢您的回答。这个ret, labels = cv2.connectedComponents(img)
适用于二维数组。请问是否可以为 3D 数据执行此操作?
@S.EB 我不认为 OpenCV 的连接组件适用于 3D 数据,但我很确定 scikit-image 的连接组件算法 (skimage.morphology.label()
) 会。请参阅文档here。如果这不起作用,请为它打开一个新问题并在此处链接我,我会看看!【参考方案2】:
我在 2D 中对 CCL 的改编是:
1) 将图像转换为 1/0 图像,其中 1 为对象像素,0 为背景像素。
2) 通过执行带有遍压缩的 Union-Find 算法来制作 2 遍 CCL 算法。你可以看到更多here。
在此 CCL 实现的第一遍中,您检查相邻像素(如果您的目标像素是对象像素),并比较它们之间的标签,以便您可以在它们之间生成等价。您将那些作为对象像素(标签> 0)的相邻像素中的最小标签分配给您的目标像素。这样,您不仅为目标像素 (label>0) 分配了一个对象标签,而且还创建了一个等价列表。
2) 在第二遍中,您遍历所有像素,并通过查看存储在您的 Union-Find 类中的等效表,通过其父标签的标签更改它们之前的标签。
3)我实现了一个额外的通道,使标签遵循顺序 (1,2,3,4....) 而不是随机顺序 (23,45,1,...)。这涉及仅出于审美目的更改标签“名称”。
【讨论】:
以上是关于python中的连接组件标签的主要内容,如果未能解决你的问题,请参考以下文章