【问题标题】:connected component labeling in pythonpython中的连接组件标签
【发布时间】:2018-03-08 14:07:42
【问题描述】:

如何用open cv在python中实现连通分量标注? 这是一个图像示例:

我需要连接组件标签来分隔黑白图像上的对象。

【问题讨论】:

    标签: python-2.7 opencv image-processing connected-components


    【解决方案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-imagehere'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,...)。这涉及仅出于审美目的更改标签“名称”。

    【讨论】:

      猜你喜欢
      • 2017-05-07
      • 2011-01-10
      • 2014-05-19
      • 2011-07-31
      • 2014-04-13
      • 2013-12-02
      • 2013-01-06
      • 1970-01-01
      相关资源
      最近更新 更多