pythonarraysnumpyopticalflow4d

How to add the indices (x,y) of array elements (u,v) to get an array of elements (x,y,u,v)?


I wrote a function that adds the indices of each element in the array to the elements.

Examples:

First element is [10,11], index is [0,0] -> Becomes [0,0,10,11]

Second element is [12,13], index is [1,0] -> Becomes [1,0,12,13]

How can I optimize this function? Is there a simpler way to write it? Any improvements/recommendations will be appreciated!

My project: I am using Optical Flow to get an array of magnitudes (u, v), which represent the optical flow vector components of each pixel. I would like to add the position (x,y) of the pixels to the array so that I get an array of (x, y, u, v). Note: (x,y) position is the same as the index value, which makes it a bit easier.

Here's my code:

def vec_4D (mag_2D):
    vec_4D = np.zeros((mag_2D.shape[0],mag_2D.shape[1],4))
    x = 0
    y = 0
    for row in vec_4D:
        for col in row:
            col[0] = x
            col[1] = y
            col[2] = mag_2D[y][x][0]
            col[3] = mag_2D[y][x][1]
            x += 1
        x=0
        y+=1
    return(vec_4D)

mag_2D = np.array([[[10,11], [12,13], [14,15]], [[16,17], [18,19], [20,21]]])
print(vec_4D(mag_2D))
Input array: 

[[[10 11]
  [12 13]
  [14 15]]

 [[16 17]
  [18 19]
  [20 21]]]



Output array: 

[[[ 0.  0. 10. 11.]
  [ 1.  0. 12. 13.]
  [ 2.  0. 14. 15.]]

 [[ 0.  1. 16. 17.]
  [ 1.  1. 18. 19.]
  [ 2.  1. 20. 21.]]]


Solution

  • Here's a "multi-liner", using np.indices(), and np.concatenate():

    y_indices,x_indices = np.indices(mag_2D.shape[0:2])
    vec_4D_result = np.concatenate((x_indices[:,:,None], 
                                    y_indices[:,:,None], 
                                    mag_2D[y_indices,x_indices]), axis = -1)
    

    Testing it out:

    import numpy as np
    
    mag_2D = np.array([[[10,11], [12,13], [14,15]], [[16,17], [18,19], [20,21]]])
    y_indices,x_indices = np.indices(mag_2D.shape[0:2])
    vec_4D_result = np.concatenate((x_indices[:,:,None], 
                                    y_indices[:,:,None], 
                                    mag_2D[y_indices,x_indices]), axis = -1)
    print (vec_4D_result)
    

    Output:

    [[[ 0  0 10 11]
      [ 1  0 12 13]
      [ 2  0 14 15]]
    
     [[ 0  1 16 17]
      [ 1  1 18 19]
      [ 2  1 20 21]]]