Reputation: 378
I'm dealing with a problem which I handle a lot of shapes such as:
These are represented as simple numpy arrays with 0 representing empty, and any other value representing not empty.
I need to fill the shapes which have empty interior spaces, such as the two squares above. But I haven't figured out any simple solution.
Any ideas or suggestions for packages?
Upvotes: 1
Views: 865
Reputation: 59741
You can use scipy.ndimage.binary_fill_holes
for that:
import scipy
a = np.array([
[0, 0, 1, 1, 1],
[0, 0, 1, 0, 1],
[0, 0, 1, 1, 1],
[0, 0, 0, 0, 0],
[2, 2, 2, 0, 0],
[2, 0, 2, 0, 0],
[2, 2, 2, 0, 0],
])
b = scipy.ndimage.binary_fill_holes(a)
print(b.astype(int))
# [[0 0 1 1 1]
# [0 0 1 1 1]
# [0 0 1 1 1]
# [0 0 0 0 0]
# [1 1 1 0 0]
# [1 1 1 0 0]
# [1 1 1 0 0]]
One problem with this is it does not maintain the shape id. If you want that, it may be a bit more complicated... If you don't have cases where one shape is inside another one, maybe this can work:
import scipy
a = np.array([
[0, 0, 1, 1, 1],
[0, 0, 1, 0, 1],
[0, 0, 1, 1, 1],
[0, 0, 0, 0, 0],
[2, 2, 2, 0, 0],
[2, 0, 2, 0, 0],
[2, 2, 2, 0, 0],
])
b = np.zeros_like(a)
for i in range(a.max()):
shape = i + 1
b += shape * scipy.ndimage.binary_fill_holes(a == shape)
print(b)
# [[0 0 1 1 1]
# [0 0 1 1 1]
# [0 0 1 1 1]
# [0 0 0 0 0]
# [2 2 2 0 0]
# [2 2 2 0 0]
# [2 2 2 0 0]]
There are still complicated cases. For example, the input:
1 1 1
1 0 2
2 2 2
Would produce all ones in the first snippet and no changes in the second one. Depending on what exactly you need you can tweak the code as necessary.
Upvotes: 2