【问题标题】:Get external coordinates of a polygon from a numpy boolean grid从 numpy 布尔网格中获取多边形的外部坐标
【发布时间】:2018-04-02 21:03:19
【问题描述】:

我正在尝试从 numpy 布尔网格中获取多边形的外部坐标。例如,从一个 (16, 16) ndarray 如下一个

[
    [False False False False False False  True  True  True  True False False False False False False],
    [False False False False False  True  True  True  True  True  True False False False False False],
    [False False False False False False False False False False  True  True False False False False],
    [False False 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 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 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 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],
    [False False False False False False False False False False False False False False False False]
]

如果我们绘制 ndarray 它将如下所示:

我想按顺序获取以下坐标,以便我们可以绘制此类多边形的外环,例如[(5 1), (6 0), (7 0), (8 0), (9 0), (10 1), (11 2), (11 3), (10 2), (9 1), (8 1), (7 1), (6 1)]。到目前为止,我有以下内容:

# Consider that the boolean ndarray above is called 'prediction'

import numpy as np
from shapely.geometry import Polygon, Point
import matplotlib.pyplot as plt

# Get the coordinates that match the boolean polygon
(y, x) = np.where(prediction == True)

# Iterate on each of the coordinates, however my problem is that it is not aware of the contour order as it should be :/
coordinates = [Point(x_coordinate, y_coordinate) for x_coordinate, y_coordinate in itertools.izip(x, y)]
# Build the polygon out of the points
polygon = Polygon([[coordinate.x, coordinate.y] for coordinate in coordinates])

exterior_x, exterior_y = polygon.exterior.xy

# Plotting

fig = plt.figure(1, figsize=(5, 5))
ax = fig.add_subplot(1, 2, 1)
ax.plot(exterior_x, exterior_y, color='#6699cc')
ax.invert_yaxis()

plt.subplot(1, 2, 2)
plt.imshow(prediction)
plt.show()

问题是我正在构建多边形而不考虑顺序,因此polygon.exterior.xy 的结果将创建外部环。我的方法会创建错误的多边形轮廓,例如:

但是,我无法为这个问题想出一个通用的方法。我欢迎任何关于如何解决这个问题的建议。提前致谢。

【问题讨论】:

    标签: python numpy shapely


    【解决方案1】:

    也许您可以将问题移至GIS stack exchange site。在那里你可能会得到更多的帮助。

    无论如何,快速搜索显示this anwer,建议使用rasterio 库,我知道这是您需要的。

    适应你的情况,它可以是:

    import numpy as np
    import rasterio.features
    
    # Convert your array to 0-1 integers
    myarray = [[1 if t else 0 for t in row] for row in myarray]
    # Build a numpy array
    myarray = np.array(myarray)
    # Convert the type (don't even know why this was needed in my computer, but raised exception if not converted.
    myarray = myarray.astype(np.int32)
    
    # Let the library do the magic. You should take a look at the rasterio.features.shapes output
    mypols = [p[0]['coordinates'] 
                       for p in  rasterio.features.shapes(myarray)]
    

    mypols 现在是一个坐标数组,您可以轻松地将其转换为shapely 多边形。

    注意正确测试陌生案例。我尝试构建一个多面体,该库将每个连接的组件返回为一个多边形。幸运的是,它为每个多边形返回相关值,因此您可以随意发布处理。 不过,带有内环的多边形似乎处理得很好。 我不知道在这些情况下您会期望什么行为。

    【讨论】:

    • 此答案仅链接,因此可能会被删除。请参阅here。请解决这个问题。
    • 好的,我会完成的。
    • 效果很好,谢谢。我还尝试了在 coordinates 周围的 alpha 形状(凹壳),但与您提出的解决方案相比,它在较大的图像上太慢了。
    • 很高兴听到它奏效了。在这类复杂的问题中,总是值得在网络上进行全面搜索。请记住,堆栈交换还有其他几个更具体地满足其他需求的站点,尽管在 SO 中您总是会得到更快的答案。
    【解决方案2】:

    我会使用 ConvexHull,它会尝试找到包含所有点的最小包络,即多边形轮廓:ConvexHull with Scipy

    【讨论】:

    • 凹形外壳会复制边界。在这种特殊情况下,凸包不会,因为它不是凸多边形。
    猜你喜欢
    • 2013-09-20
    • 1970-01-01
    • 2021-02-19
    • 1970-01-01
    • 1970-01-01
    • 2011-12-05
    • 2015-08-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多