Python 如何从位于数组顶部的多边形内的NumPy二维数组中提取值?

Python 如何从位于数组顶部的多边形内的NumPy二维数组中提取值?,python,arrays,algorithm,python-3.x,numpy,Python,Arrays,Algorithm,Python 3.x,Numpy,我的目标如下:给定一个2-D数组和一个可以放置在数组顶部的多边形,我想提取多边形内的值(包括边界)并求和 假设我有这样一个二维数组: 1 6 8 4 2 3 5 4 1 3 7 9 1 0 2 3 4 8 6 7 0 5 7 4 0 1 2 5 4 2 假设有一个具有以下顶点的多边形: (1, 2) (2, 3) (3, 3) (4, 2) (4, 1) (3, 1) (2, 1) (1, 2) 将多边形放置在阵列顶部将产生以下结果: _ _ _ _ _ _ _ _ 1 _ _ _ _ 0

我的目标如下:给定一个2-D数组和一个可以放置在数组顶部的多边形,我想提取多边形内的值(包括边界)并求和

假设我有这样一个二维数组:

1 6 8 4 2 3
5 4 1 3 7 9
1 0 2 3 4 8
6 7 0 5 7 4
0 1 2 5 4 2
假设有一个具有以下顶点的多边形:

(1, 2)
(2, 3)
(3, 3)
(4, 2)
(4, 1)
(3, 1)
(2, 1)
(1, 2)
将多边形放置在阵列顶部将产生以下结果:

_ _ _ _ _ _
_ _ 1 _ _ _
_ 0 2 3 _ _
_ 7 0 5 _ _
_ 1 2 _ _ _
最后,我想对这些值求和。因此,最终输出为21

最有效的方法是什么?我看到了对
matplotlib.path
和Shapely的引用,但我没有找到任何适合我需要的东西,除非我只是缺少了一些东西(这当然是可能的)。看起来这个功能应该内置到NumPy中,但如果是的话,我还没有遇到过

为什么我需要这个:我有一个代表全世界人口的ASCII网格,我有政治边界。我想在人口网格上覆盖政治边界,以确定该位置的总人口数。

涉及的步骤-

  • 创建与图像数组形状相同的布尔数组

  • 使用给定的轮廓点填充轮廓

  • 通过填充由轮廓点创建的孔来创建多边形水滴

  • 使用填充的掩码将布尔索引到图像数组中,并获得总和

实施-

from scipy.ndimage.morphology import binary_fill_holes as imfill

mask = np.zeros(img.shape,dtype=bool)
mask[idx[:,0], idx[:,1]] = 1
out = img[imfill(mask)].sum()
样本运行-

1) 输入图像和多边形轮廓点:

In [107]: img
Out[107]: 
array([[1, 6, 8, 4, 2, 3],
       [5, 4, 1, 3, 7, 9],
       [1, 0, 2, 3, 4, 8],
       [6, 7, 0, 5, 7, 4],
       [0, 1, 2, 5, 4, 2]])

In [108]: idx
Out[108]: 
array([[1, 2],
       [2, 3],
       [3, 3],
       [4, 2],
       [4, 1],
       [3, 1],
       [2, 1],
       [1, 2]])
2) 拟议守则:

In [109]: mask = np.zeros(img.shape,dtype=bool)
     ...: mask[idx[:,0], idx[:,1]] = 1
     ...: out = img[imfill(mask)].sum()
     ...: 
3) 分析结果:

In [134]: imfill(mask) # Polygon mask
Out[134]: 
array([[False, False, False, False, False, False],
       [False, False,  True, False, False, False],
       [False,  True,  True,  True, False, False],
       [False,  True,  True,  True, False, False],
       [False,  True,  True, False, False, False]], dtype=bool)

In [135]: img[imfill(mask)]
Out[135]: array([1, 0, 2, 3, 7, 0, 5, 1, 2])

In [136]: img[imfill(mask)].sum()
Out[136]: 21
涉及的步骤-

  • 创建与图像数组形状相同的布尔数组

  • 使用给定的轮廓点填充轮廓

  • 通过填充由轮廓点创建的孔来创建多边形水滴

  • 使用填充的掩码将布尔索引到图像数组中,并获得总和

实施-

from scipy.ndimage.morphology import binary_fill_holes as imfill

mask = np.zeros(img.shape,dtype=bool)
mask[idx[:,0], idx[:,1]] = 1
out = img[imfill(mask)].sum()
样本运行-

1) 输入图像和多边形轮廓点:

In [107]: img
Out[107]: 
array([[1, 6, 8, 4, 2, 3],
       [5, 4, 1, 3, 7, 9],
       [1, 0, 2, 3, 4, 8],
       [6, 7, 0, 5, 7, 4],
       [0, 1, 2, 5, 4, 2]])

In [108]: idx
Out[108]: 
array([[1, 2],
       [2, 3],
       [3, 3],
       [4, 2],
       [4, 1],
       [3, 1],
       [2, 1],
       [1, 2]])
2) 拟议守则:

In [109]: mask = np.zeros(img.shape,dtype=bool)
     ...: mask[idx[:,0], idx[:,1]] = 1
     ...: out = img[imfill(mask)].sum()
     ...: 
3) 分析结果:

In [134]: imfill(mask) # Polygon mask
Out[134]: 
array([[False, False, False, False, False, False],
       [False, False,  True, False, False, False],
       [False,  True,  True,  True, False, False],
       [False,  True,  True,  True, False, False],
       [False,  True,  True, False, False, False]], dtype=bool)

In [135]: img[imfill(mask)]
Out[135]: array([1, 0, 2, 3, 7, 0, 5, 1, 2])

In [136]: img[imfill(mask)].sum()
Out[136]: 21

我不知道它是否是最有效的(很可能不是),但它是矢量化的,而且很有效
a
是“图片”
b
是多边形

i, k = np.indices(a.shape)
z = i+k*1j
p = b[:,0]+b[:,1]*1j
m = np.unwrap(np.angle(z[..., None]-p), axis=-1)
m = ~np.isclose (m[...,-1], m[...,0]) | np.any(np.isclose(z[..., None], p), axis=-1)
res = np.sum(a[m])
# 21 -> res

我不知道它是否是最有效的(很可能不是),但它是矢量化的,而且很有效
a
是“图片”
b
是多边形

i, k = np.indices(a.shape)
z = i+k*1j
p = b[:,0]+b[:,1]*1j
m = np.unwrap(np.angle(z[..., None]-p), axis=-1)
m = ~np.isclose (m[...,-1], m[...,0]) | np.any(np.isclose(z[..., None], p), axis=-1)
res = np.sum(a[m])
# 21 -> res

我建议将numpy数组转换为图像,然后使用图像处理工具(OpenCV?)我建议将numpy数组转换为图像,然后使用图像处理工具(OpenCV?)漂亮!这和我希望的一样简单。谢谢为什么不干脆
img[idx[:,0],idx[:,1]].sum()
?@P-robot猜测在之前的示例运行中不清楚。我们也需要多边形内部的pts,而不仅仅是由
idx
表示的多边形轮廓上的pts。因此,我们需要所有的工作来填充blob,并调用
ndimage
的帮助:)漂亮!这和我希望的一样简单。谢谢为什么不干脆
img[idx[:,0],idx[:,1]].sum()
?@P-robot猜测在之前的示例运行中不清楚。我们也需要多边形内部的pts,而不仅仅是由
idx
表示的多边形轮廓上的pts。因此,我们需要所有的工作来填充blob并调用
ndimage
的帮助:)