1

Numpyに16x16x4のアレイがあります。

寸法1:水平位置[0,15]

寸法2:垂直位置[0,15]

次元3:RGB値0-255 [0,3]

16x16を2048x1285に置き換えて:

for x in range(0,15):
    for y in range(0,15):

それをカットしません(これを行うために7分以上、各興味深いポイントで洪水がいっぱいになります)。PILイメージの反復処理は非常に高速ですが、配列が乱雑になります(つまり、7分以上)。

numpy.where(bitmap == [red, green, blue, alpha])

それが私が探しているものではないようです。これを実行するための合理的に速い方法は何ですか?

編集:

bitmap == [red, green, blue, alpha]

実際にはほとんど便利です。16x16x4配列から16x16x1配列に移行するにはどうすればよいですか。ここで、array [x、y]はz = [True、True、True、True]の場合は1、それ以外の場合は0です。

4

3 に答える 3

1

私はあなたの速度を再現することはできません.私の今や古代のノートブックでのブルートフォース反復でさえ、約14倍高速ですwhere.他の場所で費やされます(たとえば、あなたの塗りつぶしで)。ともかく:

z = [True,True,True,True] の場合、array[x,y] が 1 で、それ以外の場合は 0 である 16x16x4 配列から 16x16x1 配列に移動するにはどうすればよいですか?

私は...するだろう:

In [169]: m = numpy.random.randint(0, 16, size=(2048, 1285, 4))

In [170]: b = [4,5,6,7]

In [171]: matches = (m == b).all(axis=2)*1

In [172]: matches.shape
Out[172]: (2048, 1285)

そしてそれはかなり速いです:

In [173]: timeit matches = (m == b).all(axis=2)*1
10 loops, best of 3: 137 ms per loop
于 2012-08-31T02:51:06.287 に答える
0

私が説明したことは、

zip(*numpy.where(numpy.logical_and.reduce(image == [255,255,255])))

ドキュメントによると、これは明確ではありませんでしたが、そこにあります。(編集: アルファチャンネルの欠如は重要ではありません。)

私が興味を持っているテストは、実際には点との等価性ではなく、その点までのユークリッド距離がしきい値内にあることです。

numpy.apply_along_axis(distance_from_white ...

ここで、distance_from_white は白からのユークリッド距離を返す関数で、16x16 で機能しますが、2048x1245 では数分かかります。scipy.spatial.distance.pdist (または cdist?) が答えかもしれませんが、2 つの配列内のすべてのポイント間の距離ではなく、1 つのポイントに対する距離を計算する方法がわかりません (これは 16x16 で機能します。しかし、それは非常に無駄な計算なので、実際のサイズで試すことさえためらっています)。

于 2012-08-31T02:47:20.643 に答える
0

forお気づきのように、 a でループを反復するのはndarrayあまり効率的ではありません。条件を満たすエントリのインデックスを見つけたい場合は、実際に使用する必要があります

indices = np.where(bitmap == [R, G, B, A])

これは、1 番目、2 番目、3 番目の軸に沿って解のインデックスを与える 3 要素のタプルを返します。最初の 2 つのディメンションのみに関心があるため、3 番目の項目を削除できます。のような一連のインデックスが必要な(x,y)場合は、次のようなものを使用するだけです

zip(*indices[:2])

2番目の可能性は、(N,M,4)標準の整数ndarray(N,M)構造化された配列に表示するdtype=[[('',int)]*4]ことです(フィールド名を気にしないでください。それらは自動的に次のように拡張され'f0', 'f1', ...ます:

alt_bitmap = bitmap.view([('',int)'*4).squeeze()

(は、配列を配列squeezeに折りたたむために導入されます)(N,M,1)(N,M)

その後、関数を使用できnp.whereますが、テストする値も次のようにする必要がありnp.arrayます。

indices = np.where(bitmap==np.array((R, G, B, A), dtype=bitmap.dtype))

今回は2タプルのみで、先に提示したものとのペアをindices入手できます。(x,y)zip(*indices)

于 2012-08-30T23:44:48.727 に答える