如何使用光流和 grid_sample 扭曲图像?
Posted
技术标签:
【中文标题】如何使用光流和 grid_sample 扭曲图像?【英文标题】:How to warp the image with optical flow and grid_sample? 【发布时间】:2020-02-29 13:37:05 【问题描述】:我有一些关于光流图像变形的问题。
我想通过 grid_sample 测试扭曲图像,并且我从 PWC-Net 获得了样本(两个带有流的图像),如下所示: 从 --> https://github.com/NVlabs/PWC-Net/tree/master/PyTorch/data 输入图像 来自 --> https://github.com/NVlabs/PWC-Net/tree/master/PyTorch/tmp
的流文件result image
input image 1
input image 2
import torch
import torch.nn as nn
import torch.nn.functional as F
import cv2
import numpy as np
from imageio import imread
def warp(x, flo):
“”"
warp an image/tensor (im2) back to im1, according to the optical flow
x: [B, C, H, W] (im2)
flo: [B, 2, H, W] flow
"""
B, C, H, W = x.size()
# mesh grid
xx = torch.arange(0, W).view(1 ,-1).repeat(H ,1)
yy = torch.arange(0, H).view(-1 ,1).repeat(1 ,W)
xx = xx.view(1 ,1 ,H ,W).repeat(B ,1 ,1 ,1)
yy = yy.view(1 ,1 ,H ,W).repeat(B ,1 ,1 ,1)
grid = torch.cat((xx ,yy) ,1).float()
if x.is_cuda:
grid = grid.cuda()
vgrid = Variable(grid) + flo
# scale grid to [-1,1]
vgrid[: ,0 ,: ,:] = 2.0 *vgrid[: ,0 ,: ,:].clone() / max( W -1 ,1 ) -1.0
vgrid[: ,1 ,: ,:] = 2.0 *vgrid[: ,1 ,: ,:].clone() / max( H -1 ,1 ) -1.0
vgrid = vgrid.permute(0 ,2 ,3 ,1)
flo = flo.permute(0 ,2 ,3 ,1)
output = F.grid_sample(x, vgrid)
mask = torch.autograd.Variable(torch.ones(x.size())).cuda()
mask = F.grid_sample(mask, vgrid)
mask[mask <0.9999] = 0
mask[mask >0] = 1
return output*mask
test = cv2.readOpticalFlow(‘reference_frame_0010.flo’)
test = torch.from_numpy(test)
test = test.view(1, 2, H, W)
test = Variable(test).cuda()
test_img2 = cv2.imread(‘frame_0011.png’)
test_img2 = torch.from_numpy(test_img2)
test_img2 = test_img2.view(1, 3, H, W)
test_img2 = Variable(test_img2).cuda()
out = warp(test_img2, test)
out = out.view(H, W, 3)
out = out.cpu()
out = np.float32(out)
cv2.imwrite(‘test3.png’, out*255)
我已经运行了上面的代码并得到了结果图像。正如你所看到的最后一张图片,这不是我所期望的。 看起来像带有网格的图像的几个部分。 使用光流获得扭曲的目标图像是否正确? 如果不是,我怎样才能让整个图像看起来像输入的彩色图像?
请帮我解决这个问题。
【问题讨论】:
【参考方案1】:用opencv加载图像时,它的形状为[height, width, 3]
。
当您尝试使用重塑它时
test_img2 = test_img2.view(1, 3, H, W)
它混合了所有的值,而不是仅仅交换尺寸。你需要的是torch.transpose
函数。
test_img2 = test_img2.transpose(2, 0, 1)[None]
这里[None]
添加了批次维度。
【讨论】:
以上是关于如何使用光流和 grid_sample 扭曲图像?的主要内容,如果未能解决你的问题,请参考以下文章
如何将光流场(浮点数)映射到像素数据(字符)以进行图像变形?