gpt4 book ai didi

python - numpy/python 中的 Floodfill 分割图像

转载 作者:太空狗 更新时间:2023-10-30 02:27:51 26 4
gpt4 key购买 nike

我有一个 numpy 数组,它表示来自图像的分段二维矩阵。基本上,它是一个稀疏矩阵,带有一堆闭合形状,这些形状是图像片段的轮廓。我需要做的是在 numpy 中使用不同的颜色/标签为每个闭合形状内的空像素着色。

我知道我可以在 PIL 中使用 floodfill 来做到这一点,但我正在尝试不必将矩阵从 numpy 来回转换为 PIL。如果像 skimage 或 sklearn 中有一个函数可以用不同的标签“自动标记”我矩阵的所有不同封闭区域(它可以是单调递增的整数或颜色),那就太好了。我不只要它代表其区域内相邻像素的正确分组,就不要在意)。

我已经花了很多时间尝试实现我自己的 floodfill,现在我只是想要一些可以为我开箱即用地标记图像的东西。

最佳答案

我假设您的矩阵是二进制的,其中非零值表示提取的段,零值是您不关心的值。 measure 模块中的 scikit-image label 函数可能会引起您的兴趣:http://scikit-image.org/docs/dev/api/skimage.measure.html#skimage.measure.label

它主要执行连通分量分析,并用整数标记所有单独闭合的分量。不过,您需要小心指定连接的方式。有 4-connectedness 和 8-connectedness,前者仅使用北、南、东和西方向找到连接区域,而 8-connectedness 使用所有 8 个方向(北、南、东、西、东北、东南、西北、西南) ).您将使用 connectivity 选项并指定 1 用于 4 连接,2 用于 8 连接。

但是,默认连接将是完全连接,因此对于 2D 的情况,它将是 2 选项。我怀疑你会这样。矩阵中任何为零的 Blob 都将被标记为零。事不宜迟,这是一个非常简单的可重现示例:

In [1]: from skimage.measure import label

In [2]: import numpy as np

In [3]: x = np.zeros((8,8))

In [4]: x[0:4,0:4] = 1

In [5]: x[6:8,6:8] = 1

In [6]: x
Out[6]:
array([[ 1., 1., 1., 1., 0., 0., 0., 0.],
[ 1., 1., 1., 1., 0., 0., 0., 0.],
[ 1., 1., 1., 1., 0., 0., 0., 0.],
[ 1., 1., 1., 1., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 1., 1.],
[ 0., 0., 0., 0., 0., 0., 1., 1.]])

In [7]: label(x)
Out[7]:
array([[1, 1, 1, 1, 0, 0, 0, 0],
[1, 1, 1, 1, 0, 0, 0, 0],
[1, 1, 1, 1, 0, 0, 0, 0],
[1, 1, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 2, 2],
[0, 0, 0, 0, 0, 0, 2, 2]], dtype=int64)

我们可以看到我在左上角和右下角创建了两个独立的岛。运行 label 函数后,它会返回一个标签矩阵,用于识别属于彼此的像素区域。具有相同 ID 的像素表示属于同一区域。

为了向您展示连通性如何发挥作用,这里是另一个简单的示例:

In [1]: import numpy as np

In [2]: from skimage.measure import label

In [3]: y = np.array([[0,1,0,0],[1,1,1,0],[0,1,0,1]])

In [4]: y
Out[4]:
array([[0, 1, 0, 0],
[1, 1, 1, 0],
[0, 1, 0, 1]])

In [5]: label(y, connectivity=1)
Out[5]:
array([[0, 1, 0, 0],
[1, 1, 1, 0],
[0, 1, 0, 2]], dtype=int64)

In [6]: label(y)
Out[6]:
array([[0, 1, 0, 0],
[1, 1, 1, 0],
[0, 1, 0, 1]], dtype=int64)

输入的左上角有一个十字图案,右下角有一个单独的非零值。如果我们使用 4-connectivity,右下角将被分类为不同的标签,但如果我们使用默认连接(full),每个像素将被分类为相同的标签。

关于python - numpy/python 中的 Floodfill 分割图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39173947/

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