【问题标题】:Shapely polygon to binary mask匀称多边形到二进制掩码
【发布时间】:2021-08-14 21:25:50
【问题描述】:

我看到有人问过这个问题,但还没有真正找到完整的答案。我有一个简单的形状多边形,称为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()

导致剧情

编辑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 Create 2D Polygon Mask
  • 我已经看到了该线程,但不幸的是,因为我的坐标网格是浮点数而不是整数|(包括负 x 和 y 方向的坐标)。我有一组笛卡尔坐标,而不是像素坐标,因此建议的解决方案似乎不起作用。我使用 Yusuke 的方法与直接用 shapely 绘图的情节不同意。由于某种原因,我得到了一个非常不同的形状。
  • 你在使用 geopandas 吗?
  • 我是,虽然目前我这样做只是为了绘制我的轮廓并验证它的行为是否正常。

标签: python mask geopandas shapely


【解决方案1】:

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 的方法相同。
  • 我也尝试过直接输入多边形以进行光栅化,但我从原始帖子的第一个图中得到了相同的奇怪形状。
  • 您可以尝试将.convex_hull 应用于多边形/点集?
  • 试一试,形状有点变化,但我仍然遇到同样的问题,它只占用左上角输出的一小部分,而且形状与 geopandas 上的形状不匹配。奇怪的! (顺便感谢到目前为止的建议)
  • 您可以尝试使用rasterize()transform 参数将多边形转换为图像坐标范围。栅格化的多边形出现在左上角,因为这是多边形顶点坐标所在的位置。
猜你喜欢
  • 1970-01-01
  • 2020-03-12
  • 2021-05-29
  • 1970-01-01
  • 2022-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-13
相关资源
最近更新 更多