2017-03-15 70 views
0

我的目標如下:給定一個二維數組和一個可以放置在數組頂部的多邊形,我想要拉出多邊形內的值(包含的邊界)並求和這些值。如何從位於數組頂部的多邊形內的NumPy 2-D數組中提取值?

假設我有一個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網格,我有政治邊界。我想覆蓋人口網格上的政治邊界,以確定該地點的總人口數量。

+0

我會建議將numpy數組轉換成圖像,然後使用圖像處理工具(OpenCV?) – DyZ

回答

2

步驟參與 -

  • 創建相同的形狀作爲圖像陣列的一個布爾值數組。

  • 使用給定的輪廓點填充輪廓。

  • 通過填充輪廓點創建的孔創建多邊形斑點。

  • 布爾索引到帶有填充掩碼的圖像數組中並獲得總和。

實現 -

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 
+0

美麗!這正如我所希望的那樣簡單。謝謝! – Geoff

+1

爲什麼不簡單地'img [idx [:,0],idx [:,1]]。sum()'? –

+2

@ P-robot猜測在之前的樣品運行中並不清楚。我們還需要多邊形內的點,而不僅僅是由'idx'表示的多邊形輪廓上的點。所以,我們需要所有的工作來填充blob並調用'ndimage'的幫助:) – Divakar

1

我不知道這是最有效的(最有可能沒有),但它的矢量化和它的作品。 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 
相關問題