2016-09-21 10 views
1

私は、多くの領域(同じセル値を持つクラスタ化されたセル)を持つ2d(10000,10000)という大きいnumpyを持っています。私が望むのは、35%以上の境界が重なっている隣接領域をマージすることです。このオーバーラップは、共通ボーダーのサイズをネイバーと分割して、そのリージョンの合計ボーダーサイズで割ります。numpy 2d領域間の境界オーバーラップの測定

私は隣接領域(Look here)を検出する方法を知っていますが、境界の重なりをどのように測定するかはわかりません。

私は大きな配列を扱っているので、ベクトル化された解決法が最適です。


#input 
region_arr=np.array([[1,1,3,3],[1,2,2,3],[2,2,4,4],[5,5,4,4]]) 

enter image description here

ネイバー検出スクリプトの出力は、第1及び第2列の隣接する領域とnumpyの2次元アレイです。

#result of neighbour detection 
>>> region_neighbour=detect_neighbours(region_arr) 
>>> region_neighbour 
array([[1, 2], 
     [1, 3], 
     [2, 1], 
     [2, 3], 
     [2, 4], 
     [2, 5], 
     [3, 1], 
     [3, 2], 
     [3, 4], 
     [4, 2], 
     [4, 3], 
     [4, 5], 
     [5, 2], 
     [5, 4]]) 

この領域と近隣の間のパーセントオーバーラップを含む隣接検出の結果に列を追加したいとします。所望の出力は、このようになります。この例では領域1及び3 = 1/8 = 0.125 =共通の境界サイズ/領域1

の合計境界サイズとPercentualオーバーラップ:

#output 
>>> percentual_overlap=measure_border_overlap(region_arr,region_neighbour) 
>>> percentual_overlap 
array([[ 1.  , 3.  , 0.125 ], 
     [ 1.  , 2.  , 0.375 ], 
     [ 2.  , 1.  , 0.3  ], 
     [ 2.  , 3.  , 0.3  ], 
     [ 2.  , 4.  , 0.2  ], 
     [ 2.  , 5.  , 0.2  ], 
     [ 3.  , 1.  , 0.125 ], 
     [ 3.  , 2.  , 0.25 ], 
     [ 3.  , 4.  , 0.125 ], 
     [ 4.  , 2.  , 0.375 ], 
     [ 4.  , 3.  , 0.125 ], 
     [ 4.  , 5.  , 0.125 ], 
     [ 5.  , 2.  , 0.333333], 
     [ 5.  , 4.  , 0.166667]])  

とこの出力では、35%を超える領域(領域1と領域2、領域4と領域2)をマージするのは比較的簡単です。このようになります。新しい配列をマージ領域の後:

enter image description here

編集

あなたはpv.の機能を適用することにより、各領域の境界線を計算することができます。

答えて

1

このCount cells of adjacent numpy regionsをご覧ください。そのような情報に基づいてどのようにマージするかを決めることは、私が考える複数の答えの問題です。それはあなたが進む順序に応じて一意の解決策を持っていない可能性があります。

import numpy_indexed as npi 

neighbors = np.concatenate([x[:, :-1].flatten(), x[:, +1:].flatten(), x[+1:, :].flatten(), x[:-1, :].flatten()]) 
centers = np.concatenate([x[:, +1:].flatten(), x[:, :-1].flatten(), x[:-1, :].flatten(), x[+1:, :].flatten()]) 
border = neighbors != centers 

(neighbors, centers), counts = npi.count((neighbors[border], centers[border])) 
region_group = group_by(centers) 
regions, neighbors_per_region = region_group.sum(counts) 
fractions = counts/neighbors_per_region[region_group.inverse] 
for result in zip(centers, neighbors, fractions): 
    print(result) 
+0

ありがとうございます。出力はまったく同じではありませんが、私は自分のコードでこのアプローチを実装できます! –

+0

この回答の小さな間違いの1つは、返される分数が整数(すべて0)です。私はそれが次のようになるはずだと思います: 分数= counts/neighbors_per_region [region_group.inverse] .astype(float) –

+0

ええ;それはpython3の下で動作しますが、実際には私は2で異なっていたと思います –

関連する問題