2017-07-18 139 views
0

閱讀scipy.ndimage.label(Variable area threshold for identifying objects - python)一個有趣的話題,我想包括在標籤的「誤差」。scipy.ndimage.label:包括誤差

在上面的鏈接討論中: 頂部的藍點怎麼能包含在內?(假設它與橙色,最大的物體錯誤地斷開了連接)?

我發現了結構屬性,它應該能夠通過改變陣列(從np.ones(3,3,3-),以任何更爲包括點(我想它是3D)。然而,不幸的是,將「結構」屬性調整爲更大的數組看起來並不奏效,它要麼給出了維數的錯誤(RuntimeError:結構和輸入必須具有相同的秩 ),或者它不會改變任何東西......

感謝

這是代碼:

labels, nshapes = ndimage.label(a, structure=np.ones((3,3,3))) 

其中a是3D陣列。

+0

'structure'的維數必須A'的'維數相匹配。 'structure'每個維度的長度必須是3.所以看起來你不能使用'structure'去做你想要的。 (這是不是一個答案評論,因爲最根本的問題是「如何在頂部的藍色圓點包括嗎?」) –

+0

通過他們的方式,任何簡單的方法,包括誤差很可能還合併這兩個形狀的反對左邊緣。 –

回答

0

這是一個使用scipy.ndimage.binary_dilation一種可能的方法。在2D示例中查看正在發生的事情更容易,但我會在最後展示如何推廣到3D。

In [103]: a 
Out[103]: 
array([[0, 0, 0, 1, 0, 0, 0], 
     [0, 0, 0, 0, 0, 0, 0], 
     [1, 1, 0, 0, 1, 0, 0], 
     [1, 1, 0, 0, 0, 1, 1], 
     [0, 0, 0, 0, 0, 1, 1], 
     [1, 1, 1, 0, 0, 0, 0]]) 

In [104]: from scipy.ndimage import label, binary_dilation 

一個像素延伸。每個 「形」 向下和向右:

In [105]: b = binary_dilation(a, structure=np.array([[0, 0, 0], [0, 1, 1], [0, 1, 1]])).astype(int) 

In [106]: b 
Out[106]: 
array([[0, 0, 0, 1, 1, 0, 0], 
     [0, 0, 0, 1, 1, 0, 0], 
     [1, 1, 1, 0, 1, 1, 0], 
     [1, 1, 1, 0, 1, 1, 1], 
     [1, 1, 1, 0, 0, 1, 1], 
     [1, 1, 1, 1, 0, 1, 1]]) 

應用label來填充的數組:

In [107]: labels, numlabels = label(b) 

In [108]: numlabels 
Out[108]: 2 

In [109]: labels 
Out[109]: 
array([[0, 0, 0, 1, 1, 0, 0], 
     [0, 0, 0, 1, 1, 0, 0], 
     [2, 2, 2, 0, 1, 1, 0], 
     [2, 2, 2, 0, 1, 1, 1], 
     [2, 2, 2, 0, 0, 1, 1], 
     [2, 2, 2, 2, 0, 1, 1]], dtype=int32) 

乘以a通過labels,我們得到標籤的期望陣列的a

In [110]: alab = labels*a 

In [111]: alab 
Out[111]: 
array([[0, 0, 0, 1, 0, 0, 0], 
     [0, 0, 0, 0, 0, 0, 0], 
     [2, 2, 0, 0, 1, 0, 0], 
     [2, 2, 0, 0, 0, 1, 1], 
     [0, 0, 0, 0, 0, 1, 1], 
     [2, 2, 2, 0, 0, 0, 0]]) 

(這假定在a的值是0或1。如果不是,則可以使用alab = labels * (a > 0)

對於3D輸入,則必須在參數structure更改爲binary_dilation

struct = np.zeros((3, 3, 3), dtype=int) 
struct[1:, 1:, 1:] = 1 
b = binary_dilation(a, structure=struct).astype(int) 
+0

這是一個聰明的做法,謝謝!然而,是否有你選擇不擴張的原因[1,1,0](上圖和左圖?)如果你已經說過了,是否會在左邊合併這兩個形狀?爲什麼? – Jules

+0

通過僅擴展每個維度的一側,誤差範圍是一個像素。如果您向各個方向展開,則會得到兩個像素的誤差範圍。 –

+0

輝煌。只是澄清一下:3D插件的第二行發生了什麼? – Jules