如何在Python中使用OpenCV实现连通组件标记?以下是图像示例:
我需要使用连通组件标记来分离黑白图像上的物体。
如何在Python中使用OpenCV实现连通组件标记?以下是图像示例:
我需要使用连通组件标记来分离黑白图像上的物体。
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)
我对二维CCL的改进如下:
1)将图像转换为1/0图像,其中1表示对象像素,0表示背景像素。
2)通过实现带有传递压缩的并查集算法来制作2次CCL算法。您可以在这里看到更多信息。
在此CCL实现中的第一遍中,您检查邻居像素,在目标像素是对象像素的情况下,比较它们之间的标签,以便您可以生成它们之间的等价关系。您将最小标签分配给那些对象像素(label>0)的邻居像素,以分配对象标签给目标像素(label>0),同时创建等价列表。
2)在第二遍中,您遍历所有像素,并通过仅查看存储在您的并查集类中的等价表格来更改其父标签的先前标签。
3) 我实现了一个额外的步骤,使标签按顺序(1、2、3、4...)而不是随机顺序(23、45、1...)进行跟踪。这涉及仅出于美观目的更改标签“名称”。
scikit-image
;这里有一个例子使用该库。或者您可以检测轮廓并使用它来标记图像。 - alkasmret, labels = cv2.connectedComponents(img)
适用于2D数组。我可以问一下,是否有可能对3D数据进行此操作? - S.EBskimage.morphology.label()
)可以。请参见文档here。如果它不起作用,请提一个新问题并链接我在这里,我会再看一下! - alkasm