python 形状多边形到二进制掩码

inkz8wg9  于 2023-02-21  发布在  Python
关注(0)|答案(2)|浏览(181)

我看到有人问这个问题,但还没有找到完整的答案。我有一个简单的形状多边形,称为polygon。我想提取这个多边形作为一个二进制掩码(理想情况下是一个numpy数组)。我该怎么做呢?
我还设法从shapely转换为geopandas,如here所示,所以从geopandas提取遮罩也可以,但不幸的是,我还没有真正找到这方面的线索。
编辑:需要说明的是,如果要使用坐标格网,则格网包含x和y笛卡尔坐标(无序的)对应于构成形状轮廓的点。这些是浮点数,所以需要int输入的解决方案不会很有效。理想情况下,我希望起始点是一个形状优美的多边形,而不是一组点,但是如果更好的话,我可以使用一个无序的点集(或者从一个形状优美的多边形中提取顺时针方向的顶点)
我试过Yusuke的方法描述here,但我得到的面具不太有意义.
雄介的方法:

#%% create grid and plot
nx, ny = 100, 100
poly_verts = Plane1verts #this is a list of tuples containing cartesian coordinate pairs of the shape contour in x and y
# 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))

plt.imshow(grid)
plt.title('Grid plot')
plt.show()

掩模的结果曲线是

这不是我所期望的。而如下所述从geopandas绘图显示了正确的形状。

#%% create shapely and plot for comparison
from shapely.geometry import Polygon
#convert the sets of points dict to a shapely object
polygon1_plane1=Polygon(Plane1vert_tuple)

p = gpd.GeoSeries(polygon1_plane1)
p.plot()
plt.show()

得到图

EDIT2:这是我用作元组列表的坐标网格的副本

[(-8.982, -12.535), (-7.478, -12.535), (-5.975, -12.535), (-4.471, -12.535), (-4.471, -12.535), (-2.967, -11.031), (-1.463, -11.031), (-1.463, -11.031), (0.041, -9.527), (0.041, -9.527), (1.544, -8.023), (3.048, -8.023), (4.552, -8.023), (4.552, -8.023), (6.056, -6.52), (7.559, -6.52), (7.559, -6.52), (7.559, -5.016), (9.063, -3.512), (10.567, -3.512), (10.567, -3.512), (10.567, -2.008), (10.567, -0.505), (10.567, 0.999), (10.567, 2.503), (10.567, 4.007), (10.567, 4.007), (9.063, 5.51), (9.063, 5.51), (7.559, 7.014), (7.559, 7.014), (6.056, 8.518), (6.056, 8.518), (4.552, 10.022), (4.552, 11.526), (4.552, 11.526), (3.048, 11.526), (1.544, 11.526), (1.544, 11.526), (1.544, 10.022), (0.041, 8.518), (0.041, 8.518), (0.041, 7.014), (-1.463, 5.51), (-2.967, 5.51), (-4.471, 5.51), (-4.471, 5.51), (-5.975, 4.007), (-7.478, 4.007), (-8.982, 4.007), (-10.486, 4.007), (-11.99, 4.007), (-13.493, 4.007), (-13.493, 4.007), (-14.997, 2.503), (-14.997, 2.503), (-16.501, 0.999), (-18.005, 0.999), (-18.005, 0.999), (-18.005, -0.505), (-19.508, -2.008), (-19.508, -2.008), (-19.508, -3.512), (-19.508, -5.016), (-19.508, -5.016), (-18.005, -6.52), (-18.005, -8.023), (-18.005, -8.023), (-16.501, -9.527), (-16.501, -9.527), (-14.997, -9.527), (-13.493, -11.031), (-13.493, -11.031), (-11.99, -11.031), (-10.486, -12.535), (-10.486, -12.535)]
pxiryf3j

pxiryf3j1#

rasterio.features.rasterize听起来正是你要找的。

from shapely.geometry import Polygon
import rasterio.features
import matplotlib.pyplot as plt

poly = Polygon([(0, 50), (10, 10), (30, 0), (45, 45), (0, 50)])
img = rasterio.features.rasterize([poly], out_shape=(60, 50))
plt.imshow(img)

yrdbyhpb

yrdbyhpb2#

您可以将OpenCV与cv2.fillPoly()配合使用
示例:

import numpy as np
import cv2
from shapely.geometry import box

mask = np.zeros([960, 1280])
# create an example bounding box polygon
x1, y1, x2, y2 = 480, 540, 780, 840
polygon = box(x1, y1, x2, y2)
points = [[x, y] for x, y in zip(*polygon.boundary.coords.xy)]

mask = cv2.fillPoly(mask, np.array([points]).astype(np.int32), color=1)

相关问题