Petr
Petr

Reputation: 1817

Convert Coordinates to a Binary Mask [python]

I am trying to convert image annotations given in a json file to a proper binary mask for further analysis.

I was trying to utilize CV2's polygon features. However, it was not able to obtain it.

Is there a simple way to get a binary mask? - using either simple numpy of scikitimage

consider this simple example:

import numpy as np
import matplotlib.pyplot as plt

np.random.seed(1)

x = np.random.uniform(-100, 100, 4)
y = np.random.uniform(-100, 100, 4)

plt.scatter(x, y)
plt.fill(x, y)

when plotting with plt.fill it is able to create a proper polygon. What I essentially want is to have the results of plt.fill as a full numpy array of size roughly - 35, 75 containing only 0 and 1.

Upvotes: 1

Views: 2785

Answers (1)

Juan
Juan

Reputation: 5758

You can use skimage.draw.polygon2mask:

import numpy as np
from skimage import draw

np.random.seed(1)
x = np.random.uniform(-100, 100, 4)
y = np.random.uniform(-100, 100, 4)
shape = tuple(
        int(np.ceil(np.ptp(arr)))
        for arr in [y, x]
        )
x_offset = x - np.min(x)
y_offset = np.max(y) - y
image = draw.polygon2mask(
        shape,
        np.stack((y_offset, x_offset), axis=1)
        )

fig, ax = plt.subplots(1, 2)
ax[0].scatter(x, y)
ax[0].fill(x, y)
ax[0].axis('equal')

ax[1].imshow(image, interpolation='nearest', cmap='gray')

plt.show()

plot result

Do note that this is a slightly pathological case because part of the polygon is so thin that it results in a discontinuous object.

Additionally, note that, since NumPy arrays can't have negative coordinates, the coordinates between the two images are no longer an exact match.

Upvotes: 2

Related Questions