How to get list of points inside a polygon in python?
I suggest to use matplotlib contains_points()
from matplotlib.path import PathtupVerts=[(86, 52), (85, 52), (81, 53), (80, 52), (79, 48), (81, 49), (86, 53), (85, 51), (82, 54), (84, 54), (83, 49), (81, 52), (80, 50), (81, 48), (85, 50), (86, 54), (85, 54), (80, 48), (79, 50), (85, 49), (80, 51), (85, 53), (82, 49), (83, 54), (82, 53), (84, 49), (79, 49)]x, y = np.meshgrid(np.arange(300), np.arange(300)) # make a canvas with coordinatesx, y = x.flatten(), y.flatten()points = np.vstack((x,y)).T p = Path(tupVerts) # make a polygongrid = p.contains_points(points)mask = grid.reshape(300,300) # now you have a mask with points inside a polygon
Building upon RemcoGerlich's answer here's a validated function:
import numpy as npimport mahotasdef render(poly): """Return polygon as grid of points inside polygon. Input : poly (list of lists) Output : output (list of lists) """ xs, ys = zip(*poly) minx, maxx = min(xs), max(xs) miny, maxy = min(ys), max(ys) newPoly = [(int(x - minx), int(y - miny)) for (x, y) in poly] X = maxx - minx + 1 Y = maxy - miny + 1 grid = np.zeros((X, Y), dtype=np.int8) mahotas.polygon.fill_polygon(newPoly, grid) return [(x + minx, y + miny) for (x, y) in zip(*np.nonzero(grid))]
Example:
poly = [ [0, 0], [0, 10], [10, 10], [10, 0]]plt.figure(None, (5, 5))x, y = zip(*render(poly))plt.scatter(x, y)x, y = zip(*poly)plt.plot(x, y, c="r")plt.show()
I think drawing the polygon and filling it is a good start, you're going to need something like that anyway and those algorithms are usually fine tuned in C. But don't use a RGB image, use a black/white image, and use numpy.where()
to find the pixels where it's 1.
According to this question, the mahotas
library has a fill_polygon
function that works with numpy arrays.
I'm starting the following code from your function (I would subtract the minx
and maxx
too) but note that I can't test it at all, I'm not on my dev machine.
import numpy as npimport mahotasdef render(poly): # removed parameter 'z' xs = [i[0] for i in poly] ys = [i[1] for i in poly] minx, maxx = min(xs), max(xs) miny, maxy = min(ys), max(ys) X = maxx - minx + 1 Y = maxy - miny + 1 newPoly = [(x - minx, y - miny) for (x, y) in poly] grid = np.zeros((X, Y), dtype=np.int8) mahotas.polygon.fill_polygon(newPoly, grid) return [(x + minx, y + miny) for (x, y) in np.where(grid)]