利用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产生/处理图像时均以从左向右为x轴(图宽width);而原点方面,UE4在图像左下角,numpy在图像左上角,因此UE4以从下到上为y轴(图长height),而numpy则是从上到下,所以在计算时需要注意y坐标的正负转化。并且opencv读入图片是BGR通道,而motion vector文件中R通道存储x轴(宽width)上的偏移,G通道存储y轴(高height)上的偏移,故还要注意通道交换。

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

在UE中修改增加x,y均为正值的jitter offset时,渲染得到的画面会向左下角移动,此时jx,jy>0
而画面往左下角移动时,新画面(同时也是LR)的左上角原点实际在老画面(同时也是HR)坐标系的-x,+y处,
因此对老画面重建时,采样的坐标系是基于新画面的,故应该减去(+jx,-jy)

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值