schapke
schapke

Reputation: 378

Fill the interior of shapes

I'm dealing with a problem which I handle a lot of shapes such as:

enter image description here enter image description here enter image description here enter image description here

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

Answers (1)

javidcf
javidcf

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

Related Questions