2016-08-24 5 views
2

私は音楽認識プログラムを作成しており、その一部として、png(2200x1700ピクセル)からnumpy配列の最大接続領域を見つける必要があります。私の現在の解決策は次のとおりです。スピードアップ・ナンピ・フィルタリング

labels, nlabels = ndimage.label(blobs) 
cutoff = len(blobs)*len(blobs[0])/nlabels 
blobs_found = 0 
x = [] 
t1 = time() 
for n in range(1, nlabels+1): 
    squares = np.where(labels==n) 
    if len(squares[0]) < cutoff: 
     blobs[squares] = 0 
    else: 
     blobs_found += 1 
     blobs[squares] = blobs_found 
     x.append(squares - np.amin(squares, axis=0, keepdims=True)) 
nlabels = blobs_found 
print(time() - t1) 

これは動作しますが、実行には約6.5秒かかります。このコードからループを削除する方法がありますか?そうでなければ速度を上げますか?

+0

これは興味深い質問です。あなたはそれを[mcve](http://stackoverflow.com/help/mcve)にすることができますか? – BPL

答えて

2

あなたはとラベル付けされた各地域のサイズ(ピクセル単位)を取得することができます:最大その後になります

unique_labels = numpy.unique(labels) 
label_sizes = scipy.ndimage.measurement.sum(numpy.ones_like(blobs), labels, unique_labels) 

unique_labels[label_size == numpy.max(label_size)] 
+0

最後の行をn個の最大ラベルのリストにする簡単な方法はありますか? –

+0

はい、代わりに 'numpy.argsort'を使い、最初のnの値を取ってください。' unique_labels [numpy.argsort(label_size)[0:n-1]] ' – Benjamin

+0

' ndimage.measurement.sum'はndimageでなければなりません。新しいバージョンで合計? –

2

最速はおそらくnumpy.bincountを使用してから作業することですそこ。次のようなものがあります。

labels, nlabels = ndimage.label(blobs) 
cutoff = len(blobs)*len(blobs[0])/float(nlabels) 

label_counts = np.bincount(labels) 

# Re-label, taking the cutoff into account 
cutoff_mask = (label_counts >= cutoff) 
cutoff_mask[0] = False 
label_mapping = np.zeros_like(label_counts) 
label_mapping[cutoff_mask] = np.arange(cutoff_mask.sum()) + 1 

# Create an image-array with the updated labels 
blobs = label_mapping[labels].astype(blobs.dtype) 

これはもう少し速度を最適化することができましたが、わかりやすいものを目指しています。

関連する問題