在Python OpenCV中找到connectedComponents的颜色。

5
假设我有一个已经二值化的numpy数组图像:所有值都是0或255。在Python版的OpenCV中,我可以执行以下操作:
conn = cv2.connectedComponentsWithStats(mask, 8, cv2.CV_32S)

conn 对象将提供以下信息:

  • 有多少个联通组件(标签)。
  • 原始图像中每个像素的标签。
  • 每个联通组件的边界框和面积。
  • 每个联通组件的质心位置。

此外,保证标签 0 是“背景”标签,但根据 文档 ,没有说明如何确定背景。

假设我的图像是白色背景上的黑点,其行为实际上没有任何保证:可能是一个黑点实际上溢出了背景(留下了“背景角落”),也可能是多个小块点,甚至是排列成黑点之间形成白色岛屿等。

但我只对我的黑点感兴趣。

当我对 openCV 提供的背景组件的颜色没有信心时,有没有一种简单的 Pythonic 方法 来确定每个连通段的底层颜色? 或者说:我是否忽略了关于 connectedComponent 功能或 OpenCV API 的明显内容?

(注意:我知道可以 brute force 这个问题:循环遍历标签,在提供的标签数组中查找每个标签的第一个实例,然后探测图像数组中相应的索引。至少我认为我可以这样做--文档很简单。但我认为这种方法非常不简洁。)

2个回答

1
作为一个有趣的点,ImageMagick中的连通组件列出了区域的平均颜色,因为它允许模糊颜色区域的确定(根据模糊值),这里没有显示。
这是一个简单的二进制示例,因此平均颜色就是实际颜色:

enter image description here

magick objects.gif -define connected-components:verbose=true -connected-components 4 -auto-level regions.png

Objects (id: bounding-box centroid area mean-color):
  0: 256x171+0+0 119.2,80.8 33117 srgb(0,0,0)
  2: 120x135+104+18 159.5,106.5 8690 srgb(255,255,255)
  3: 50x36+129+44 154.2,63.4 1529 srgb(0,0,0)
  4: 21x23+0+45 8.8,55.9 409 srgb(255,255,255)
  1: 4x10+252+0 253.9,4.1 31 srgb(255,255,255)

enter image description here

该列表按最大区域排序。因此,“背景”将由最大区域确定,并列在第一位。
结果通过ID编号编码为灰度级别,通过-auto-level进行拉伸以获得完整的动态范围进行查看。
还有一个定义参数可以设置,以制作一个输出,该输出通过区域过滤,然后显示一个包含其平均颜色的图像。
magick objects.gif -define connected-components:area-threshold=410 -define connected-components:mean-color=true -connected-components 4 filtered.png


enter image description here


1
对于每个连通组件,您可以创建一个掩码并使用此函数计算平均值: cv2.mean(image, mask)
conn = cv2.connectedComponentsWithStats(input_binary, 8, cv2.CV_32S)
num_labels = conn[0]
labels = conn[1]
stats = conn[2]
centroids = conn[3]

for l in labels:
    mask = np.array(labels, dtype=np.uint8)
    mask[labels==l] = 255 

    mean_label = cv2.mean(input_binary, mask)
    print(mean_label)

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