2017-09-04 13 views
2

私はskimage.measure.labelという名前の画像を表す2次元ブール値のnumpy配列を持ち、各セグメント化された領域にラベルを付け、int [0,500]の2D配列を与えます。この配列の各値は、そのピクセルの領域ラベルを表します。私は今、最も小さい地域を削除したいと思います。例えば、私の入力配列がshape(n、n)なら、私は< mピクセルのすべてのラベル付き領域をより大きな周囲の領域に包含させたいと思います。例えば、n = 10、M = 5、私の入力は、Pythonのnumpy配列 - 近い最小の領域

0, 0, 0, 0, 0, 0, 0, 1, 1, 1 
0, 0, 0, 0, 0, 0, 0, 1, 1, 1 
0, 0, 7, 8, 0, 0, 0, 1, 1, 1 
0, 0, 0, 0, 0, 0, 0, 1, 1, 1 
0, 0, 0, 0, 0, 2, 2, 2, 1, 1 
4, 4, 4, 4, 2, 2, 2, 2, 1, 1 
4, 6, 6, 4, 2, 2, 2, 3, 3, 3 
4, 6, 6, 4, 5, 5, 5, 3, 3, 5 
4, 4, 4, 4, 5, 5, 5, 5, 5, 5 
4, 4, 4, 4, 5, 5, 5, 5, 5, 5 

と出力があるかもしれない場合、

0, 0, 0, 0, 0, 0, 0, 1, 1, 1 
0, 0, 0, 0, 0, 0, 0, 1, 1, 1 
0, 0, 0, 0, 0, 0, 0, 1, 1, 1 # 7 and 8 are replaced by 0 
0, 0, 0, 0, 0, 0, 0, 1, 1, 1 
0, 0, 0, 0, 0, 2, 2, 2, 1, 1 
4, 4, 4, 4, 2, 2, 2, 2, 1, 1 
4, 4, 4, 4, 2, 2, 2, 3, 3, 3 # 6 is gone, but 3 remains 
4, 4, 4, 4, 5, 5, 5, 3, 3, 5 
4, 4, 4, 4, 5, 5, 5, 5, 5, 5 
4, 4, 4, 4, 5, 5, 5, 5, 5, 5 

Iはbinary closing含む、skimageモルフォロジー演算に見えないが、いずれまし私のユースケースではうまくいくようです。助言がありますか?

+0

どう '0 0 1 2 2 'のようなコーナーケースについてのコード例については

? –

+1

@JonasAdlerここで 'm = 1'とすると、このようなタイブレークは関係ありません。左右に実行される形態操作は、「0 0 0 2 2」を生じる可能性が高いが、「0 0 2 2 2」も同様である。 – BoltzmannBrain

+0

関連する質問:https://stackoverflow.com/questions/46126409/numpy-filter-to-smooth-out-zero-regions @JonasAdlerできるかどうかを見てください、ありがとう! – BoltzmannBrain

答えて

0

これは、各ラベルに対応するブール領域でバイナリ拡張を実行することで実行できます。これを行うことで、各地域の近隣人数がわかります。これを使用して、必要に応じて値を置き換えることができます。

import numpy as np 
import scipy.ndimage 

m = 5 

arr = [[0, 0, 0, 0, 0, 0, 0, 1, 1, 1], 
     [0, 0, 0, 0, 0, 0, 0, 1, 1, 1], 
     [0, 0, 7, 8, 0, 0, 0, 1, 1, 1], 
     [0, 0, 0, 0, 0, 0, 0, 1, 1, 1], 
     [0, 0, 0, 0, 0, 2, 2, 2, 1, 1], 
     [4, 4, 4, 4, 2, 2, 2, 2, 1, 1], 
     [4, 6, 6, 4, 2, 2, 2, 3, 3, 3], 
     [4, 6, 6, 4, 5, 5, 5, 3, 3, 5], 
     [4, 4, 4, 4, 5, 5, 5, 5, 5, 5], 
     [4, 4, 4, 4, 5, 5, 5, 5, 5, 5]] 
arr = np.array(arr) 
nval = np.max(arr) + 1 

# Compute number of occurances of each number 
counts, _ = np.histogram(arr, bins=range(nval + 1)) 

# Compute the set of neighbours for each number via binary dilation 
c = np.array([scipy.ndimage.morphology.binary_dilation(arr == i) 
       for i in range(nval)]) 

# Loop over the set of arrays with bad count and update them to the most common 
# neighbour 
for i in filter(lambda i: counts[i] < m, range(nval)): 
    arr[arr == i] = np.argmax(np.sum(c[:, arr == i], axis=1)) 

期待された結果得られます:

>>> arr.tolist() 
[[0, 0, 0, 0, 0, 0, 0, 1, 1, 1], 
[0, 0, 0, 0, 0, 0, 0, 1, 1, 1], 
[0, 0, 0, 0, 0, 0, 0, 1, 1, 1], 
[0, 0, 0, 0, 0, 0, 0, 1, 1, 1], 
[0, 0, 0, 0, 0, 2, 2, 2, 1, 1], 
[4, 4, 4, 4, 2, 2, 2, 2, 1, 1], 
[4, 4, 4, 4, 2, 2, 2, 3, 3, 3], 
[4, 4, 4, 4, 5, 5, 5, 3, 3, 5], 
[4, 4, 4, 4, 5, 5, 5, 5, 5, 5], 
[4, 4, 4, 4, 5, 5, 5, 5, 5, 5]] 
+0

これは魅力のように動作するようですが、ありがとう!一見すると、私が行う唯一の変更は、適用可能であればイテレータを使うことです - 'xrange'と' itertools.ifilter'。 – BoltzmannBrain

+0

また、実際には、より大きい配列では、収束がw/argの 'iterations = -1'になるまで実行すると拡張操作がうまく機能することがわかります。 – BoltzmannBrain

関連する問題