1

Lately I have posted a question about this but in the end I solved it in a non-elegant manner.

I have 2 images that are numpy arrays and I would like to create a new array iterating the 2 images. I have 3 cases and I have done the following:

delta= np.empty((h, w, 3),int)
    for z in range (0,3):
      for i in range(0, (h-1)):
        for j in range(0, (w-1)):
         delta[i][j][z]=np.sqrt(((imgLlab[i][j][0]-imgRlab[i][j-disp[i][j]][0])**2) + ((imgLlab[i][j][1]-imgRlab[i][j-disp[i][j]][1])**2) + ((imgLlab[i][j][2]-imgRlab[i][j-disp[i][j]][2])**2) )


delta= np.empty((h, w, 3),int)
    for z in range (0,3):
     for i in range(0, (h-1)):
    for j in range(0, (w-1)):
       delta[i][j][z]=np.sqrt(((imgLlab[i][j][0]-imgRlab[i][j-disp[i][j]][0])**2)  )


for z in range (0,3):
 for i in range(0, (h-1)):
  for j in range(0, (w-1)):
    delta[i][j][z]=np.sqrt(((imgLlab[i][j][1]-imgRlab[i][j-disp[i][j]][1])**2) + ((imgLlab[i][j][2]-imgRlab[i][j-disp[i][j]][2])**2) )

I would like to not repeat iterating every time and do it as quickly as possible.

Is there another way to do this with numpy?

EDIT after Jaime help, i have changed my code like that:

disp= np.hstack([disp, disp, disp]).reshape(h,w,3).astype(np.int)
rows = np.arange(h).reshape(h, 1, 1)
cols = np.arange(w).reshape(1, w, 1)
planes = np.arange(3).reshape(1, 1, 3)
print rows.shape, cols.shape, planes.shape, disp.shape, h
data = imgLlab[rows, cols, planes] - imgRlab[rows ,cols - disp[rows, cols, planes], planes]
data = data**2
data = np.sum(data, axis=-1)
data = np.sqrt(data)

i had to reshape dist because it didn't have the same shape of imglLab and imgRLab, i mean imglLab is (288, 384,3) and disp was (288,384). Also if i print disp(288,384,1) i get the same error, its like there is no value there but the dimension is the same like the others ones. But now that the 3 arrays got the same dimension i get an indexError: index (384) out of range (0<=index(383) in dimension 1.

6
  • Are you excluding the last row and column of each image on purpose, i.e. why aren't you iterating as for j in range(h):? Also, your iteration over z is computing the same value every time, is that what you really want? Commented Jan 18, 2013 at 14:14
  • they are two images and h is the height and w is the width. I am iterating over z because i want that this array will be an image and if i don't have the 3 channel i can't save it (maybe yes). I am not excluding the last row and column on purpose because if i remove (h-1) i get an index out of bounds error. Did i answer to you? Commented Jan 18, 2013 at 15:30
  • Your stacking of the three copies of disp is what is giving you the problem. Using 'hstack would be consistent with a reshape(h, 3, w), for yours you would want to use np.dstack. Commented Jan 22, 2013 at 4:43
  • But you don't need to stack three copies of the same array: simply reshape it to (h, w, 1) and when you create datachange the indexing of ìmgRlab` to imgRlab[rows ,cols - disp[rows, cols, :], planes]. Commented Jan 22, 2013 at 4:46
  • I think 'disp' has some probllem with the last value, because if i create and array like that: 'arr=np.zeros_like(disp)' and i put arr in my formula it works fine. Is there a way to put a 0 at the end of 'disp'? maybe it gives me trouble because there is no value there or how can i change the shape of those images like '(h-1,w-1,3)' because i have tried with 'reshape' but it doesn't work Commented Jan 22, 2013 at 9:51

1 Answer 1

1

There are a few things you can improve in your code.

  1. Do not index your arrays as arr[a][b][c]. When doing that, you are effectively creating a python object arr[a], which is then used to create a new python object arr[a][b] from which your desired object, arr[a][b][c] is constructed. All that intermediate constructing and destructing is eliminated if you use numpy's tuple indexing as arr[a, b, c].

  2. Don't use loops when they are not needed! Instead of

    for j in xrange(len(a)) :
        a[j] = b[j]
    

    you can do

    a[:] = b[:]
    

    and this is actually the kind of stuff that makes numpy great, so use it!

As for speeding up your code... You should check that imgLlab.shape, imgRlab.shape and disp.shape are all the same, (h, w, 3). Your index error suggest that one of them is smaller. Anyway, to get what you are after we need to take advantage of broadcasting and fancy indexing. Read and digest those links, or the following will make little sense:

rows = np.arange(h).reshape(h, 1, 1)
cols = np.arange(w).reshape(1, w, 1)
planes = np.arange(3).reshape(1, 1, 3)
data = imgLlab[rows, cols, planes] - \ 
       imgRlab[planes, rows - disp[rows, cols, planes], planes]
# data is of shape (h, w, 3)
data = data**2
# data is of shape (h, w, 3)
data = np.sum(data, axis=-1)
# data is of shape (h, w)
data = np.sqrt(data)
# data is of shape (h, w)

If you really want to copy the exact same array to the three planes of your delta array, you can do it as:

delta[...] = data.reshape(h, w, 1) # equivalent to data.reshape(-1, 1)

This was only your first case, but the others should be easy to build from this first example, once you understand what is going on. If you have trouble, come back and ask!

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.