【光流】——RAFT: 稠密的光流场估计(代码浅析)

转载自:RAFT: 稠密的光流场估计
代码:https://github.com/princeton-vl/RAFT
尊重原创,请读原文

一、摘要

本文提出了Recurrent All-Pairs Field Transforms(RAFT), 一个光流估计的深度神经网络. RAFT 提取像素级的特征, 为所有像素建立多尺度 4D 关联信息, 通过查找4D关联信息, 循环迭代的更新光流场. 本文算法在KITTI、Sintel数据集上取得了state-of-the-art的表现. 同时, RAFT在多个数据集上有很强的泛化能力, 并且在训练速度、参数数量、推理时间上都有很高的效率.

二、网络结构

在这里插入图片描述
RAFT网络由三部分组成:

(1) 特征编码层: 逐像素的提取特征;

(2) 特征关联层: 为所有像素产生WxHxWxH的4D关联信息。视觉相似性(Visual Similarity):视觉相似度计算为所有特征图对的内积。因此,我们将得到一个称为相关体积的四维张量,它提供了关于大小像素位移的关键信息。

(3) 循环更新算子: 基于GRU的循环更新算子查找4D关联信息, 然后迭代的更新光流场, 光流场初始值为0;

三、特征采集模块

在这里插入图片描述
对2张图片采用同一个网络进行特征提取。

image1 = 2 * (image1 / 255.0) - 1.0
image2 = 2 * (image2 / 255.0) - 1.0

image1 = image1.contiguous()
image2 = image2.contiguous()

hdim = self.hidden_dim
cdim = self.context_dim

# run the feature network
with autocast(enabled=self.args.mixed_precision):
    fmap1, fmap2 = self.fnet([image1, image2])   

4. 视觉相似模块

上一步得到两幅图像的特征​张量 g g g , [公式] ​, correlation volume ​ [公式] 的计算方法:
在这里插入图片描述
这样就得到了image1和image2的关系特征矩阵。同时这里采用了类似金字塔的思想。这样一个相关信息张量 C C C​是非常大的, 因此在 C C C的最后两个维度上采用maxpooling进行降维, 产生4个相关信息​ { C 1 , C 2 , C 3 , C 4 , } \left \{ C^{1}, C^{2}, C^{3}, C^{4}, \right \} {C1,C2,C3,C4,},每个​的维度为 H ∗ W ∗ H / 2 k ∗ W / 2 k H*W*H/2^{k}*W/2^{k} HWH/2kW/2k ​. 保持前两个维度不变, 这种相关信息张量可以保证同时捕捉到较大和较小的像素位移.
在这里插入图片描述
不同尺度的关系矩阵

self.corr_pyramid.append(corr)
for i in range(self.num_levels-1):
    corr = F.avg_pool2d(corr, 2, stride=2)
    self.corr_pyramid.append(corr)

5. 迭代更新

迭代更新类似是一个门控循环单元(GRU)序列,但是因为图像特征是2维的,所以这里是分别在水平和竖直两个方向做的GRU
公式
在这里插入图片描述
代码:

def forward(self, h, x):
        # horizontal
        hx = torch.cat([h, x], dim=1)
        z = torch.sigmoid(self.convz1(hx))
        r = torch.sigmoid(self.convr1(hx))
        q = torch.tanh(self.convq1(torch.cat([r*h, x], dim=1)))        
        h = (1-z) * h + z * q

        # vertical
        hx = torch.cat([h, x], dim=1)
        z = torch.sigmoid(self.convz2(hx))
        r = torch.sigmoid(self.convr2(hx))
        q = torch.tanh(self.convq2(torch.cat([r*h, x], dim=1)))       
        h = (1-z) * h + z * q

        return h

6. 上采样模块

转载自:https://blog.csdn.net/weixin_43229348/article/details/120500861
GRU单元输出的光流分辨率为初始图像的1/8,因此作者提出了两种不同的上采样方法来匹配真值分辨率。第一种是光流的双线性插值。它是一种简单快速的方法,但这种方法的质量不如一个可学习名叫Convex Upsampling的上采样模块:
在这里插入图片描述
凸上采样(Convex Upsampling)方法表明,全分辨率光流是GRU单元预测的3x3加权网格的凸组合。8 倍图像上采样意味着必须将 1 个像素扩展为 64(8x8) 个像素。凸上采样模块由两个卷积层和末端的softmax激活来预测上采样光流预测中每个新像素的H / 8 × W / 8 × ( 8 × 8 × 9 ) H/8 掩码。现在,上采样图像上的每个像素都是之前粗糙分辨率像素的凸组合,由预测掩码加权,系数为w1 , w2, w3, … w9
在这里插入图片描述
code

def upsample_flow(self, flow, mask):
        """ Upsample flow field [H/8, W/8, 2] -> [H, W, 2] using convex combination """
        N, _, H, W = flow.shape
        mask = mask.view(N, 1, 9, 8, 8, H, W)
        mask = torch.softmax(mask, dim=2)

        up_flow = F.unfold(8 * flow, [3,3], padding=1)
        up_flow = up_flow.view(N, 2, 9, 1, 1, H, W)

        up_flow = torch.sum(mask * up_flow, dim=2)
        up_flow = up_flow.permute(0, 1, 4, 2, 5, 3)
        return up_flow.reshape(N, 2, 8*H, 8*W)

7. 整体流程

  • 提取image1,image2的特征
    fmap1, fmap2 = self.fnet([image1, image2])
  • 对fmap1,fmap2计算4D相关性矩阵 C C C
    corr_fn = CorrBlock(fmap1, fmap2, radius=self.args.corr_radius)
  • 对image1在提取特征,并在通道上上分解为:GRU的初始状态与feature特征
with autocast(enabled=self.args.mixed_precision):
      cnet = self.cnet(image1)
      net, inp = torch.split(cnet, [hdim, cdim], dim=1)
      net = torch.tanh(net)
      inp = torch.relu(inp)
  • 对image1的特征(H/8 * W/8)中的每个点,从4D相关性矩阵 C C C中采样81个点。4层C,共有4 * 81=324个关联特征,
  • 关联特征和初始的flow,concat之后经过几个conv后,得到motion feature。
  • motion feature在和image1的图像特征concat之后送入二维GRU模块
motion_features = self.encoder(flow, corr)
inp = torch.cat([inp, motion_features], dim=1)
  • 用GRU的隐藏状态+conv做输出
net = self.gru(net, inp)
delta_flow = self.flow_head(net)
  • 用GRU的隐藏状态+conv输出Convex Upsampling上采样的权重
  • 最后,对GRU进行一定 I T E R ITER ITER的迭代。

总结

总体,创新点:

  • 引入了motion feature,而motion feature的计算通过金字塔4D关系矩阵均匀采样得来。
  • 引入了GRU概念进行迭代优化

缺点

  • 推理流程多,存在迭代过程

reference

  • 7
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值