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中的连接组件标签的主要内容,如果未能解决你的问题,请参考以下文章

如何使用两个连接的组件更改 React 中的变量 [重复]

如何通过opencv获取连接组件中的所有像素?

Redux 连接的组件不渲染

Python3 tkinter初级

选择器视图选项填充标签

反应组件中的标签顺序?