Flood 填充 NumPy 数组 `numpy.ndarray`,即为元素分配新值并更改相同值的相邻元素

fin*_*oot 3 python arrays numpy flood-fill scipy

另一篇名为Flood Fill in Python 的类似帖子是一个关于洪水填充的非常笼统的问题,答案仅包含一个广泛的伪代码示例。我正在寻找带有numpy或的显式解决方案scipy


我们以这个数组为例:

a = np.array([
    [0, 1, 1, 1, 1, 0],
    [0, 0, 1, 2, 1, 1],
    [0, 1, 1, 1, 1, 0]
])
Run Code Online (Sandbox Code Playgroud)

为了选择 element0, 0并用 value 填充3,我希望:

[
    [3, 1, 1, 1, 1, 0],
    [3, 3, 1, 2, 1, 1],
    [3, 1, 1, 1, 1, 0]
]
Run Code Online (Sandbox Code Playgroud)

为了选择 element0, 1并用 value 填充3,我希望:

[
    [0, 3, 3, 3, 3, 0],
    [0, 0, 3, 2, 3, 3],
    [0, 3, 3, 3, 3, 0]
]
Run Code Online (Sandbox Code Playgroud)

为了选择 element0, 5并用 value 填充3,我希望:

[
    [0, 1, 1, 1, 1, 3],
    [0, 0, 1, 2, 1, 1],
    [0, 1, 1, 1, 1, 0]
]
Run Code Online (Sandbox Code Playgroud)

这应该是一个相当基本的操作,不是吗?我忽略了哪个numpyscipy方法?

Div*_*kar 5

方法#1

模块scikit-image提供了内置的来做同样的事情skimage.segmentation.flood_fill-

from skimage.morphology import flood_fill

flood_fill(image, (x, y), newval)
Run Code Online (Sandbox Code Playgroud)

样品运行 -

In [17]: a
Out[17]: 
array([[0, 1, 1, 1, 1, 0],
       [0, 0, 1, 2, 1, 1],
       [0, 1, 1, 1, 1, 0]])

In [18]: flood_fill(a, (0, 0), 3)
Out[18]: 
array([[3, 1, 1, 1, 1, 0],
       [3, 3, 1, 2, 1, 1],
       [3, 1, 1, 1, 1, 0]])

In [19]: flood_fill(a, (0, 1), 3)
Out[19]: 
array([[0, 3, 3, 3, 3, 0],
       [0, 0, 3, 2, 3, 3],
       [0, 3, 3, 3, 3, 0]])

In [20]: flood_fill(a, (0, 5), 3)
Out[20]: 
array([[0, 1, 1, 1, 1, 3],
       [0, 0, 1, 2, 1, 1],
       [0, 1, 1, 1, 1, 0]])
Run Code Online (Sandbox Code Playgroud)

方法#2

我们可以使用skimage.measure.label一些array-masking-

from skimage.measure import label

def floodfill_by_xy(a,xy,newval):
    x,y = xy
    l = label(a==a[x,y])
    a[l==l[x,y]] = newval
    return a
Run Code Online (Sandbox Code Playgroud)

要使用基于 SciPy 的label函数 - scipy.ndimage.measurements.label,它大部分是相同的 -

from scipy.ndimage.measurements import label

def floodfill_by_xy_scipy(a,xy,newval):
    x,y = xy
    l = label(a==a[x,y])[0]
    a[l==l[x,y]] = newval
    return a
Run Code Online (Sandbox Code Playgroud)

注意:这些将作为原位编辑工作。

  • 请注意,它是“(y,x)”而不是“(x,y)” (3认同)