1

I have three arrays, a src array of shape (width, height, 3) , a template array of shape (640, 480, 3) and an img_map array of shape (width, height, 2) .

img_map stores the x,y relationship between src and template, i.e. src[4, 5] = template[img_map[0,4,5], img_map[1,4,5]]. When index suggested by the mapping is out of bound, no value will be assigned.

How to achieve such value assignment without for loop using numpy in python?

Using for loop will be like this, but it is too slow.

for x in range(0, width): 
  for y in range(0, height):
    u = img_map[x,y,0]
    v = img_map[x,y,1]
    if (u >= 0) and (v >= 0) and (u < 640) and (v < 480):
      src[x,y,:] = template[u,v,:]
2
  • src[v, u] Whats (v, u) ? Commented Nov 9, 2020 at 11:01
  • if img_map.shape is (width, height, 2) then img_map[1,4,5] will always throw an error. please make sure your code is runnable before asking. Commented Nov 9, 2020 at 11:09

1 Answer 1

1

Here is a one liner version that should do the job:

src = template[img_map[:,:,0].ravel(),img_map[:,:,1].ravel(),:].reshape((width,height,3))

Here is a small code that verify the accuracy of results and evaluate the performance improvement:

import numpy as np
import time

# Preparation of testdata
(width, height, depth) = (1000, 1000, 3)
template = np.random.randint(0, 256, (640,480,depth))
img_map = np.concatenate((
    np.random.randint(0, template.shape[0], (width*height,1)),
    np.random.randint(0, template.shape[1], (width*height,1))
  ), axis=1
).reshape(width,height,2)

# For loop verion
t_start = time.time()
src = np.zeros((img_map.shape[0],img_map.shape[1],template.shape[2]))
for x in range(0, img_map.shape[0]): 
  for y in range(0, img_map.shape[1]):
    u = img_map[x,y,0]
    v = img_map[x,y,1]
    if (u >= 0) and (v >= 0) and (u < template.shape[0]) and (v < template.shape[1]):
      src[x,y,:] = template[u,v,:]
print(f'Timer 1: {time.time()-t_start}s')

# One line version
t_start = time.time()
src2 = template[img_map[:,:,0].ravel(),img_map[:,:,1].ravel(),:].reshape((width,height,depth))
print(f'Timer 2: {time.time()-t_start}s')

# Verify that both gives the same result
print('Results are equal' if np.linalg.norm(src-src2)==0 else 'Results differ')

The results are equal and the execution time is significantly improved:

% python3 script.py
Timer 1: 2.7333829402923584s
Timer 2: 0.0499570369720459s
Results are equal

Don't hesitate if you have questions.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.