Reputation: 381
I'm doing some image signal processing in python and I'm still new to the numpy functions and how to do it in the best way.
Scenario: I have four matrices g1,g2,g3,g4 they all have the same shape W,H.
I need to make a result matrix max_g where every max_g[i, j] = max(gk[i,j])
I was looping the entire image and doing:
max_g = np.zeros(Y_channel.shape)
grads = np.array([np.abs(signal.fftconvolve(Y_channel, g_filter, mode='same')/16.0) for g_filter in g_filters])
for i in range(W):
for j in range(H):
max_g[i, j] = np.max([grad[i, j] for grad in grads])
It's okay for 512x512 images but it is too slow for bigger images like 1280x720, is there a more efficient way of doing it? I mean better then 0(WxH)
Upvotes: 1
Views: 64
Reputation: 51165
You have a list containing your arrays, just stack
them and take the max along the first axis.
Setup
np.random.seed(1)
H = 5
W = 5
grads = [np.random.randint(1, 10, (W, H)) for _ in range(4)]
stack
+ max
np.stack(grads).max(0)
array([[6, 9, 9, 6, 9],
[9, 8, 9, 8, 8],
[8, 8, 9, 4, 8],
[9, 8, 9, 8, 5],
[7, 9, 9, 9, 7]])
Validation
max_g = np.empty((W, H))
for i in range(W):
for j in range(H):
max_g[i, j] = np.max([grad[i, j] for grad in grads])
np.array_equal(max_g, np.stack(grads).max(0))
True
Timings
H = 720
W = 1280
grads = [np.random.randint(1, 10, (W, H)) for _ in range(4)]
%timeit np.stack(grads).max(0)
14.8 ms ± 190 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%%timeit
max_g = np.empty((W, H))
for i in range(W):
for j in range(H):
max_g[i, j] = np.max([grad[i, j] for grad in grads])
10.2 s ± 98.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
As you can see, quite a speedup.
Upvotes: 2