gpt4 book ai didi

python - 如何使用 python OpenCV 在匹配特定值的单 channel 图像中查找最大连通分量?

转载 作者:太空宇宙 更新时间:2023-11-03 10:52:29 27 4
gpt4 key购买 nike

所以我有一个单 channel 图像,主要是 0s(背景),前景像素的一些值,如 20、21、22。非零前景像素大部分与具有相同值的其他前景像素聚集在一起。但是,图像中存在一些噪点。为了消除噪声,我想使用连通分量分析,并且对于每个值(在本例中为 20、21、22),将除最大连通分量以外的所有值都归零。所以最后,我将有 3 个大的连接组件并且没有噪音。我将如何使用 cv2.connectedComponentsWithStats 来完成这个?它似乎没有记录,甚至在查看 this post 之后也是如此,我不完全明白如何解析函数的返回值。有没有一种方法可以指定我只需要与特定灰度值匹配的连通分量的函数?

最佳答案

一般的做法是:

  1. 创建一个新的空白图像以将组件添加到
  2. 遍历图像中每个不同的非零值
  3. 为每个值创建一个掩码(为每个值提供多个 blob)
  4. 在面具上运行 connectedComponentsWithStats()
  5. 找到最大面积对应的非零标签
  6. 创建一个具有最大标签的蒙版,并将值插入新图像中蒙版位置

这里令人讨厌的是第 5 步,因为 0 的值通常但不总是最大的组件。所以我们需要按面积获取最大的非零分量。

这是一些我认为可以实现一切的代码(一些示例图像肯定会很好):

import cv2
import numpy as np

img = np.array([
[1, 0, 1, 1, 2],
[1, 0, 1, 1, 2],
[1, 0, 1, 1, 2],
[1, 0, 1, 1, 2],
[1, 0, 1, 1, 2]], dtype=np.uint8)

new_img = np.zeros_like(img) # step 1
for val in np.unique(img)[1:]: # step 2
mask = np.uint8(img == val) # step 3
labels, stats = cv2.connectedComponentsWithStats(mask, 4)[1:3] # step 4
largest_label = 1 + np.argmax(stats[1:, cv2.CC_STAT_AREA]) # step 5
new_img[labels == largest_label] = val # step 6

print(new_img)

显示所需的输出:

[[0 0 1 1 2]
[0 0 1 1 2]
[0 0 1 1 2]
[0 0 1 1 2]
[0 0 1 1 2]]

为了完成代码,首先我们创建新的标记图像,毫无想象力地称为 new_img,其中填充了零,稍后将由正确的标签填充。然后,np.unique() 找到图像中的唯一值,我将除第一个值外的所有值;请注意,np.unique() 返回一个排序数组,因此 0 将是第一个值,我们不需要找到零的分量。对于每个唯一的 val,创建一个填充有 0 和 1 的掩码,并在此掩码上运行连接的组件。这将使用不同的标签标记每个不同的区域。然后我们可以抓取最大的非零标记组件**,为它创建一个掩码,并将该 val 添加到新图像的那个地方。

** 这是代码中看起来很奇怪的令人讨厌的部分。

largest_label = 1 + np.argmax(stats[1:, cv2.CC_STAT_AREA])

首先,您可以查看您链接的关于 stats 数组形状的答案,但每一行都对应一个标签(因此标签 0 将对应第一行,等等),并且该列由整数 cv2.CC_STAT_AREA(仅为 4)定义。我们需要确保我们正在查看最大的非零标签,所以我只查看第一行之后的行。然后,抓取最大区域对应的索引。由于我们去掉了零行,索引现在对应于 label-1,所以加 1 以获得正确的标签。然后我们可以像往常一样屏蔽并插入值。

关于python - 如何使用 python OpenCV 在匹配特定值的单 channel 图像中查找最大连通分量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47520487/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com