【问题标题】:Floodfill segmented image in numpy/python在 numpy/python 中填充分段图像
【发布时间】:2017-01-03 13:52:18
【问题描述】:

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

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

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

【问题讨论】:

    标签: python image numpy image-processing image-segmentation


    【解决方案1】:

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

    它本质上是执行连通分量分析,并用一个整数标记所有单独闭合的分量。不过,您需要注意如何指定连接性。有 4 连通性和 8 连通性,前者仅使用北、南、东和西方向找到连通区域,而 8 连通性使用所有 8 个方向(北、南、东、西、东北、东南、西北、西南)。您将使用 connectivity 选项并为 4 连接指定 1 并为 8 连接指定 2

    但是,默认连接将是完全连接,因此对于 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),每个像素都会被归类为相同的标签。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-07
      • 1970-01-01
      • 1970-01-01
      • 2019-11-29
      • 2021-02-21
      • 2011-02-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多