从 numpy 布尔网格获取多边形的外部坐标
Get external coordinates of a polygon from a numpy boolean grid
我正在尝试从 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
的结果将创建外环。我的方法会创建错误的多边形轮廓,例如:
但是,我无法想出解决此问题的通用方法。我欢迎任何关于如何解决这个问题的建议。提前致谢。
也许你可以把问题移到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
多边形。
谨防正确测试陌生人案例。我试图构建一个多边形,库将每个连接的组件作为多边形返回。幸运的是,它 returns 为每个多边形关联了值,因此您可以 post 随意处理。
不过,带有内环的多边形似乎处理得很好。
我不知道在这些情况下您期望的行为是什么。
我会使用 ConvexHull,它会尝试找到包含所有点的最小包络线,即多边形轮廓:ConvexHull with Scipy
我正在尝试从 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
的结果将创建外环。我的方法会创建错误的多边形轮廓,例如:
但是,我无法想出解决此问题的通用方法。我欢迎任何关于如何解决这个问题的建议。提前致谢。
也许你可以把问题移到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
多边形。
谨防正确测试陌生人案例。我试图构建一个多边形,库将每个连接的组件作为多边形返回。幸运的是,它 returns 为每个多边形关联了值,因此您可以 post 随意处理。 不过,带有内环的多边形似乎处理得很好。 我不知道在这些情况下您期望的行为是什么。
我会使用 ConvexHull,它会尝试找到包含所有点的最小包络线,即多边形轮廓:ConvexHull with Scipy