Shapely多边形转二进制掩码

11
我看到过这个问题,但是没有找到完整的回答。我有一个简单的shapely多边形,称为“polygon”。我想提取出这个多边形作为二进制掩模(最好是numpy数组)。我该怎么做?
我也成功地将shapely转换为geopandas,如此处所示,因此从geopandas中提取掩模也可以工作,但不幸的是,我真的没有能够找到相关的线索。
编辑: 要明确一点,如果我使用坐标网格,我的网格包含x和y笛卡尔坐标(未排序),对应于构成形状轮廓的点。这些都是浮点数,因此需要int输入的解决方案不太适用。理想情况下,我希望起始点是一个shapely多边形,而不是一组点,但如果更喜欢这样做,我可以使用无序的点集(或者从shapely多边形中提取顺时针定点)。
我已经尝试了Yusuke的方法,但是我得到的掩模效果并不完全正确。
Yusuke's 方法:
#%% 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()

导致该图的结果为:enter image description here 编辑2: 这是我使用的坐标网格的元组列表副本。
[(-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)]

这个回答解决了你的问题吗?SciPy创建2D多边形掩模 - Georgy
我看过那个线程,但不幸的是我的坐标网格是浮点数而不是整数(包括负x和y方向的坐标)。我有一组笛卡尔坐标,而不是像素坐标,因此似乎建议的解决方案不起作用。使用Yusuke的方法绘制的图与直接使用shapely绘制的图不一致。由于某种原因,我得到了一个非常不同的形状。 - hex93
你正在使用 Geopandas 吗? - j-i-l
我目前只是为了绘制我的轮廓并验证其是否正常运行而这样做。 - hex93
2个回答

14

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)

栅格化图像


如果多边形上的点没有任何特定顺序,这个方法还有效吗?不幸的是,我的点是无序的,我遇到了与原帖中相同的问题,即gpd图看起来与使用Yusuke的方法相同。 - hex93
我也尝试过直接将多边形输入到光栅化函数中,但是我得到的结果与我原帖中第一张图像展示的奇怪形状相同。 - hex93
你可以尝试将.convex_hull应用于多边形/点集吗? - Martin Valgur
尝试了一下,形状有些改变,但仍然存在同样的问题,它只占据左上角的一小部分输出,并且形状与geopandas中的不匹配。奇怪!(顺便感谢迄今为止提出的建议) - hex93
你可以尝试使用rasterize()函数的transform参数将多边形转换为图像坐标范围。光栅化的多边形出现在左上角,因为你的多边形顶点的坐标位于那里。 - Martin Valgur
显示剩余2条评论

2

您可以使用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)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接