sobel フィルターを使用して for ループを回避する方法は次のとおりです。
import numpy as np
from scipy.ndimage import sobel
def sobHypot_vec(rec):
r = np.abs(rec)
x = sobel(r, 0, mode='constant')
y = sobel(r, 1, mode='constant')
h = np.hypot(x, y)
h = np.apply_over_axes(np.mean, h, [0,1])
return h.argmax()
アプリケーションで sobel フィルターが特に必要かどうかはわかりません。特定の 20 レイヤーの「イメージ」がないとテストするのは難しいですがnp.gradient
、sobel を 2 回実行する代わりに使用してみてください。利点はgradient
、3 次元で実行されることです。3 番目のコンポーネントを無視して、最初の 2 つのみの仮説を立てることができます。これは無駄に思えますが、実際には私のテストではまだ高速です。
ランダムに生成されたさまざまな画像に対してr = np.random.rand(1024,1024,20) + np.random.rand(1024,1024,20)*1j
、これはコードと同じ答えを返しますが、確実にテストして、おそらくのdx, dy
引数をいじりますnp.gradient
def grad_max(rec):
g = np.gradient(np.abs(rec))[:2] # ignore derivative in third dimension
h = np.hypot(*g)
h = np.apply_over_axes(np.mean, h, [0,1]) # mean along first and second dimension
return h.argmax()
タイミングのためにこのコードを使用します。
def sobHypot_clean(rec):
rs = rec.shape
hype = np.ones(rs)
r = np.abs(rec)
for i in xrange(rs[-1]):
ri = r[...,i]
x = sobel(ri, 0, mode='constant')
y = sobel(ri, 1, mode='constant')
hype[...,i] = np.hypot(x,y).mean()
return hype.argmax()
タイミング:
In [1]: r = np.random.rand(1024,1024,20) + np.random.rand(1024,1024,20)*1j
# Original Post
In [2]: timeit sobHypot(r)
1 loops, best of 3: 9.85 s per loop
#cleaned up a bit:
In [3]: timeit sobHypot_clean(r)
1 loops, best of 3: 7.64 s per loop
# vectorized:
In [4]: timeit sobHypot_vec(r)
1 loops, best of 3: 5.98 s per loop
# using np.gradient:
In [5]: timeit grad_max(r)
1 loops, best of 3: 4.12 s per loop
これらの関数を自分の画像でテストして、目的の出力が得られることを確認してください。配列の種類が異なると、私が行った単純なランダム テストとは異なる反応を示す可能性があるためです。