生成一个多维 numpy 数组,使得 a[x,y] = [x,y](从密集光流计算基本矩阵)

generating a multidimensional numpy array such that a[x,y] = [x,y] (calculating essential matrix from dense optical flow)

我需要获取通过此计算的密集光流的输出 flow(形状为 (cols,rows,2)):

flow = cv2.calcOpticalFlowFarneback(im0, im1, None, 0.5, 3, 15, 3, 5, 1.2, 0)

并生成点 old_ptsnew_pts 的 2 个一维列表,使得:

两个列表的排序方式必须相同,这样 old_pts[i] 与 new_pts[i]
指的是同一像素 即 old_pts1 = [0,1] => new_pts1 = [0+flow0,1,1+flow[0,1][0]]

opencv docs reference

将它们喂给这个:
E,_ = cv2.findEssentialMat(old_pts,new_pts,ch.K)

我有以下可行的解决方案(但速度非常慢 [~15" 在 4k 图像上]):

    old_pts = []
    new_pts = []
    for y in range(cols):
        for x in range(rows):
            old_pts.append([y,x])
            new_pts.append([y+flow[y,x][1],x+flow[y,x][0]])
    
    old_pts = np.array(old_pts)
    new_pts = np.array(new_pts)

是否有更好的(numpythonic)方法来生成两个点列表?

我认为应该做的是:

我需要的示例:

this is `flow` (in real life is 3000x4000):  
| y,x |         0        |       1        |        2       |
|-----|------------------|----------------|----------------|
|   0 | [[[-0.81,-0.55], | [0.73,0.83],   | [-0.3,-0.86]], |
|   1 | [[-0.33,-0.71],  | [0.86,-0.27],  | [0.11,-0.03]], |
|   2 | [[0.46,-0.51],   | [-0.35,-0.88], | [0.4,-0.7]]]   |

this is what i need:  
| old_pts |        new_pts      |
|---------|---------------------|
| [[0,0], | [[0+-0.55,0+-0.81], |
| [1,0],  | [1+-0.71,0+-0.33],  |
| [2,0],  | [2+-0.51,0+0.46],   |
| [0,1],  | [0+0.83,1+0.73],    |
| [1,1],  | [1+-0.27,1+0.86],   |
| [2,1],  | [2+-0.88,1+-0.35],  |
| [0,2],  | [0+-0.86,2+-0.3],   |
| [1,2],  | [1+-0.03,2+0.11],   |
| [2,2]]  | [2+-0.7,2+0.4]]     |

找到一个更快的解决方案:

    xes = np.tile(np.arange(im0.shape[1]),(im0.shape[0],1))
    yes = np.tile(np.arange(im0.shape[0])[:,None],(1,im0.shape[1]))

    nxes = xes + flow[:,:,0]
    nyes = yes + flow[:,:,1]

    xy  = np.stack((yes,xes),axis = 2)
    nxy = np.stack((nyes,nxes),axis = 2)

    old_pts = np.reshape(xy,(-1, xy.shape[-1]))
    new_pts = np.reshape(nxy,(-1, nxy.shape[-1]))