2014-02-05 33 views
0

我想使用numpy的標籤分割圖像,然後根據每個標籤中找到的索引數來移除符合我的標準的索引。例如,如果有,我會分割這樣的創建和分段使用它區域的圖像SciPy的的label爲圖像返回特定的numpy標籤索引

from numpy import ones, zeros 
from numpy.random import random_integers 
from scipy.ndimage import label 

image = zeros((512, 512), dtype='int') 
regionator = ones((11, 11), dtype='int') 
xs = random_integers(5, 506, size=500) 
ys = random_integers(5, 506, size=500) 

for x, y in zip(xs, ys): 
    image[x-5:x+6, y-5:y+6] = regionator 

labels, n_labels = label(image) 

現在我想找回指數具有大小各區域大於121像素(或一個區域大小)。然後,我想要將這些索引設置爲零,以便它們不再是標記圖像的一部分。什麼是最有效的方式來完成這項任務?

本質上類似於MATLAB的regionprops或利用其直方圖函數的輸出IDL的reverse_indices輸出。

回答

2

我會用bincount和門檻的結果做一個查找表:

import numpy as np 

threshold = 121 

size = np.bincount(labels.ravel()) 
keep_labels = size <= threshold 
# Make sure the background is left as 0/False 
keep_labels[0] = 0 
filtered_labels = keep_labels[labels] 

在最後上面我使用數組labels爲數組keep_labels編制索引。這在numpy中被稱爲advanced indexing,它要求labels是一個整數數組。 Numpy然後使用labels的元素作爲keep_labels的索引,並生成與labels相同形狀的數組。

+0

因此,要得到最終答案,您必須執行類似於filtered_labels =(1 - filtered_labels)*標籤 – NanoBennett

+0

這個wizardry是如何工作的?使用輸入數組索引索引? – NanoBennett

+1

對不起,我誤解了你的問題,我以爲你想保持大區域。我看到你想保留小的。你可以用'<='替換'>'(注意0標籤,因爲這是背景)。我已經在答案中做出了改變。我還添加了一個關於使用數組索引數組的註釋。 –

1

下面是我發現迄今爲止對我而言的工作,即使對於大型數據集也具有良好的性能。

運用here採取的GET指數過程中,我已經來到這個:

from numpy import argsort, histogram, reshape, where 
import bisect 

h = histogram(labels, bins=n_labels) 
h_inds = where(h[0] > 121)[0] 

labels_f = labels.flatten() 
sortedind = argsort(labels_f) 
sorted_labels_f = labels_f[sortedind] 
inds = [] 
for i in range(1, len(h_inds)): 
    i1 = bisect.bisect_left(sorted_labels_f, h[1][h_inds[i]]) 
    i2 = bisect.bisect_right(sorted_labels_f, h[1][h_inds[i]]) 
    inds.extend(sortedind[i1:i2]) 

# Now get rid of all of those indices that were part of a label 
# larger than 121 pixels 
labels_f[inds] = 0 
filtered_labels = reshape(labels_f, (512, 512)) 
+0

'np.searchsorted'可能會比使用'bisect'快得多 –

相關問題