murthaA
murthaA

Reputation: 381

Most efficient way to make a max result matrix from other matrices in numpy?

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

Answers (1)

user3483203
user3483203

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

Related Questions