Flood fill NumPy Array `numpy.ndarray`, i. e. assign new value to element and change neighboring elements of the same value, too

萝らか妹 提交于 2019-12-11 04:56:38

问题


Another, similar post called Flood Fill in Python is a very general question on flood fill and the answer only contains a broad pseudo code example. I'm look for an explicit solution with numpy or scipy.


Let's take this array for example:

a = np.array([
    [0, 1, 1, 1, 1, 0],
    [0, 0, 1, 2, 1, 1],
    [0, 1, 1, 1, 1, 0]
])

For selecting element 0, 0 and flood fill with value 3, I'd expect:

[
    [3, 1, 1, 1, 1, 0],
    [3, 3, 1, 2, 1, 1],
    [3, 1, 1, 1, 1, 0]
]

For selecting element 0, 1 and flood fill with value 3, I'd expect:

[
    [0, 3, 3, 3, 3, 0],
    [0, 0, 3, 2, 3, 3],
    [0, 3, 3, 3, 3, 0]
]

For selecting element 0, 5 and flood fill with value 3, I'd expect:

[
    [0, 1, 1, 1, 1, 3],
    [0, 0, 1, 2, 1, 1],
    [0, 1, 1, 1, 1, 0]
]

This should be a fairly basic operation, no? Which numpy or scipy method am I overlooking?


回答1:


Approach #1

Module scikit-image offers the built-in to do the same with skimage.segmentation.flood_fill -

from skimage.morphology import flood_fill

flood_fill(image, (x, y), newval)

Sample runs -

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]])

Approach #2

We can use skimage.measure.label with some 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

To make use of SciPy based label function - scipy.ndimage.measurements.label, it would mostly be the same -

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

Note : These would work as in-situ edits.



来源:https://stackoverflow.com/questions/56314718/flood-fill-numpy-array-numpy-ndarray-i-e-assign-new-value-to-element-and-ch

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!