1

これは、このソリューションから生じるフォローアップの質問です。配列に複数のパッチがない限り、隣接するセルをカウントするソリューションは非常にうまく機能します。

したがって、今回は、たとえば配列は次のようになります。

import numpy
from scipy import ndimage

s = ndimage.generate_binary_structure(2,2)
a = numpy.zeros((6,6), dtype=numpy.int) # example array
a[1:3, 1:3] = 1;a[2:4,4:5] = 1
print a
[0 0 0 0 0 0]
[0 1 1 0 0 0]
[0 1 1 0 1 0]
[0 0 0 0 1 0]
[0 0 0 0 0 0]
[0 0 0 0 0 0]

# Number of nonoverlapping cells
c = ndimage.binary_dilation(a,s).astype(a.dtype)
b = c - a
numpy.sum(b) # returns 19
# However the correct number of non overlapping cells should be 22 (12+10)

ループを使用したり、アレイを反復処理したりせずに、このジレンマを解決するためのスマートなソリューションはありますか?その理由は、配列がかなり大きくなる可能性があるためです。

アイデア1:

それを考えてみて、それを行う方法は、反復構造内の複数のパッチをチェックすることかもしれません。合計カウント数が正しくなるためには、以下のセルが拡張時に2(またはそれ以上)に等しい必要があります。この考えをコードに変換する方法を誰かが知っていますか?

[1 1 1 1 0 0]
[1 0 0 2 1 1]
[1 0 0 2 0 1]
[1 1 1 2 0 1]
[0 0 0 1 1 1]
[0 0 0 0 0 0]
4

1 に答える 1

4

labelfromを使用しndimageて、1 の各パッチをセグメント化できます。

次に、返された配列が1、2、3などに等しい場所を尋ねて、それに対してアルゴリズムを実行します(または、ndimage.distance_transform_cdtラベル付きセグメントごとにフォアグラウンド/バックグラウンドを反転して使用します.

編集1:

このコードはあなたの配列を受け取り、あなたaが求めることを行います:

b, c = ndimage.label(a)
e = numpy.zeros(a.shape)
for i in xrange(c):

    e += ndimage.distance_transform_cdt((b == i + 1) == 0) == 1

print e

私はそれがすべての等号で少し醜いことを認識していますが、それは出力します:

In [41]: print e
[[ 1.  1.  1.  1.  0.  0.]
 [ 1.  0.  0.  2.  1.  1.]
 [ 1.  0.  0.  2.  0.  1.]
 [ 1.  1.  1.  2.  0.  1.]
 [ 0.  0.  0.  1.  1.  1.]
 [ 0.  0.  0.  0.  0.  0.]]

編集 2 (代替ソリューション):

このコードは同じことを行い、できればより高速に実行するはずです (ただし、2 つのパッチが角だけに接触する場所は見つかりません)

b = ndimage.binary_closing(a) - a
b = ndimage.binary_dilation(b.astype(bool))

c = ndimage.distance_transform_cdt(a == 0) == 1

e = c.astype(numpy.int) * b + c

print e
于 2012-10-12T19:16:48.137 に答える