Reputation: 1817
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
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()
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