利用UE4生成的运动矢量(Motion Vector)在Python下对渲染图像进行前向与后向Warping

UE4产生的motion vector是后向运动矢量,具体来说,第 i i i帧的运动矢量 M V i MV_i MVi表示第 i i i帧(当前帧)到第 i − 1 i-1 i1帧(前一帧)的运动关系,换句话说,对于像素 p p p M V i [ p ] = π i → i − 1 ( p ) MV_i[p]=\pi_{i\rightarrow i-1}(p) MVi[p]=πii1(p),其中 π i → i − 1 ( p ) \pi_{i\rightarrow i-1}(p) πii1(p)表示像素 p p p从当前帧 i i i位置到前一帧 i − 1 i-1 i1的运动变换值。

使用产生的后向运动矢量,分别给出帧 i − 1 → i i-1\rightarrow i i1i的图像扭曲(forwardWarping()),与帧 i → i − 1 i\rightarrow i-1 ii1的图像扭曲(backwardWarping()),其中后者写法并不优美,进行了一定的舍入而造成像素错位。

还有就是numpy与UE4产生/处理图像时均以从左向右为y轴(图宽width);而原点方面,UE4在图像左下角,numpy在图像左上角,因此UE4以从下到上为x轴(图长height),而numpy则是从上到下,所以在计算时需要注意x坐标的正负转化。

import cv2 as cv
import numpy as np
def forwardWarping(img,mv):#img[i-1],mv[i]->img[i]
    h,w,c= img.shape    
    ch=np.arange(0,h*w).reshape(h,w)//w+mv[...,0]
    cw=np.arange(0,h*w).reshape(h,w)%w-mv[...,1]
    ch=ch.astype(np.float32)
    cw=cw.astype(np.float32)
    res=cv.remap(img,cw,ch,cv.INTER_LINEAR)
    return res
def backWarping(img,mv,depth):#img[i],mv[i],depth[i]->img[i-1]
    h,w,c=img.shape
    res=np.zeros_like(img)
    mv_oneaxis=mv.reshape(-1,2)
    I=np.arange(0,h*w)//w
    J=np.arange(0,h*w)%w
    #很粗的写法,直接进行四舍五入,会造成微小的错位
    II=(I+mv_oneaxis[:,0]+0.5).clip(0,h)
    JJ=(J-mv_oneaxis[:,1]+0.5).clip(0,w)
    II=II.astype(np.int32)
    JJ=JJ.astype(np.int32)
    id=np.argsort(-depth.reshape(-1))#考虑深度测试,当后一帧有多个位置映射到前一帧的相同位置时,选择最靠近相机(深度最小)的那个
    res[II[id],JJ[id]]=img[I[id],J[id]]
    return res

你可能感兴趣的:(python,ue4,开发语言)