Reputation: 25631
import numpy as np
from matplotlib.path import Path
w, h = 300, 200
mask = np.zeros((h, w))
verts = [(0, h), (w/2, 0), (w, h), (0, h)]
codes = [Path.MOVETO, Path.LINETO, Path.LINETO, Path.CLOSEPOLY]
path = Path(verts, codes)
mask[path.contains_points(mask)] = 1
result:
Traceback (most recent call last):
File "test.py", line 13, in <module>
mask[path.contains_points(mask)] = 1
File "C:\Python27\lib\site-packages\matplotlib\path.py", line 488, in contains_points
result = _path.points_in_path(points, radius, self, transform)
TypeError: Argument 0 to points_in_path must be an Nx2 numpy array
So matplotlib.path.Path.contains_points()
does not expand array indexes which would be useful for mask creation.
How to mask numpy array with closed path (with matplotlib or without it if it's possible)
Upvotes: 3
Views: 655
Reputation: 23530
The problem here is that path.contains_points
expects to receive an array of coordinates (Nx2 array). Then it returns a vector with N points with True
or False
for each point.
So, you need to create an array of coordinates (e.g. [[0,0], [0,1], [0,2] ...]) for the area you want to search through. Then you can feed it to contains_points
to know which of the points are within the path.
There are several ways of accomplishing this, for example:
coordinates = np.dstack(np.meshgrid(np.arange(w), np.arange(h))).reshape(-1,2)
within = coordinates[path.contains_points(coordinates)]
mask = np.zeros((h,w))
mask[within[:,1], within[:,0]] = 1
Now you should have an array with size h x w and 1's inside the mask.
Btw, the use of matplotlib.path
is a nice trick!
Upvotes: 3