SciPy 创建二维多边形掩码
我需要用标准的Python库创建一个numpy的二维数组,这个数组要表示一个多边形的二进制掩码。
- 输入:多边形的顶点,图像的尺寸
- 输出:多边形的二进制掩码(numpy二维数组)
(更大的背景:我想用scipy.ndimage.morphology.distance_transform_edt来获取这个多边形的距离变换。)
有没有人能教我怎么做这个?
7 个回答
27
关于乔的评论,有个更新。自从那条评论发布以来,Matplotlib的接口发生了变化,现在你需要使用一个叫做 matplotlib.path
的子模块提供的方法。
下面是可以正常工作的代码。
import numpy as np
from matplotlib.path import Path
nx, ny = 10, 10
poly_verts = [(1,1), (5,1), (5,9),(3,2),(1,1)]
# Create vertex coordinates for each grid cell...
# (<0,0> is at the top left of the grid in this system)
x, y = np.meshgrid(np.arange(nx), np.arange(ny))
x, y = x.flatten(), y.flatten()
points = np.vstack((x,y)).T
path = Path(poly_verts)
grid = path.contains_points(points)
grid = grid.reshape((ny,nx))
print grid
30
作为对@Anil回答的一个更直接的替代方案,matplotlib有一个叫做 matplotlib.nxutils.points_inside_poly
的功能,可以用来快速处理任意形状的多边形。例如:
import numpy as np
from matplotlib.nxutils import points_inside_poly
nx, ny = 10, 10
poly_verts = [(1,1), (5,1), (5,9),(3,2),(1,1)]
# Create vertex coordinates for each grid cell...
# (<0,0> is at the top left of the grid in this system)
x, y = np.meshgrid(np.arange(nx), np.arange(ny))
x, y = x.flatten(), y.flatten()
points = np.vstack((x,y)).T
grid = points_inside_poly(points, poly_verts)
grid = grid.reshape((ny,nx))
print grid
这个操作会得到一个布尔类型的numpy数组:
[[False False False False False False False False False False]
[False True True True True False False False False False]
[False False False True True False False False False False]
[False False False False True False False False False False]
[False False False False True False False False False False]
[False False False False True False False False False False]
[False False False False False False False False False False]
[False False False False False False False False False False]
[False False False False False False False False False False]
[False False False False False False False False False False]]
你应该可以很顺利地将 grid
传递给任何 scipy.ndimage.morphology 的函数。
98
答案其实很简单:
import numpy
from PIL import Image, ImageDraw
# polygon = [(x1,y1),(x2,y2),...] or [x1,y1,x2,y2,...]
# width = ?
# height = ?
img = Image.new('L', (width, height), 0)
ImageDraw.Draw(img).polygon(polygon, outline=1, fill=1)
mask = numpy.array(img)