Python 中的连通组件标记化

28

如何在Python中使用OpenCV实现连通组件标记?以下是图像示例:

我需要使用连通组件标记来分离黑白图像上的物体。

2个回答

77

OpenCV 3.0文档中的connectedComponents()并未提及Python,但实际上已经实现了。例如,可以参考这个SO问题。在OpenCV 3.4.0及以上版本中,文档包括Python签名,如当前主要文档所示。

函数调用很简单: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' - Willy Andika Putra
啊,那么你可能使用的是旧版本的OpenCV,其中绑定尚未移植。你使用的是哪个版本的OpenCV?如果无法升级,则可以考虑使用另一个库,例如scikit-image这里有一个例子使用该库。或者您可以检测轮廓并使用它来标记图像。 - alkasm
我的OpenCV版本是'2.4.13'。非常感谢,非常有帮助,我认为我的OpenCV需要升级。 - Willy Andika Putra
@AlexanderReynolds 非常感谢您的回答。这个 ret, labels = cv2.connectedComponents(img) 适用于2D数组。我可以问一下,是否有可能对3D数据进行此操作? - S.EB
@S.EB 我不认为OpenCV的连通组件适用于3D数据,但我非常确定scikit-image的连通组件算法(skimage.morphology.label())可以。请参见文档here。如果它不起作用,请提一个新问题并链接我在这里,我会再看一下! - alkasm

0

我对二维CCL的改进如下:

1)将图像转换为1/0图像,其中1表示对象像素,0表示背景像素。

2)通过实现带有传递压缩的并查集算法来制作2次CCL算法。您可以在这里看到更多信息。

在此CCL实现中的第一遍中,您检查邻居像素,在目标像素是对象像素的情况下,比较它们之间的标签,以便您可以生成它们之间的等价关系。您将最小标签分配给那些对象像素(label>0)的邻居像素,以分配对象标签给目标像素(label>0),同时创建等价列表。

2)在第二遍中,您遍历所有像素,并通过仅查看存储在您的并查集类中的等价表格来更改其父标签的先前标签。

3) 我实现了一个额外的步骤,使标签按顺序(1、2、3、4...)而不是随机顺序(23、45、1...)进行跟踪。这涉及仅出于美观目的更改标签“名称”。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接