论文
End-to-End Learning of Geometry and Context for Deep Stereo Regression
摘要
传统问题转化成”end2end"的“可微问题”是很多三维视觉论文讨论的核心,在这篇文章中就展示了如何将SGM可微化。另外,这篇文章的作者估计也很讨厌黑盒子式的端到端,所以整篇文章都在强调网络结构设计的合理性与原理。
网络结构
上图展示了GC-Net的整个网络结构,不难发现,其虽然是一个端到端的网络;但是仍旧被显著的分成了四个模块,分别是“特征提取”、“代价计算”、“代价聚合”和“视差生成”。对于理解SGM算法的人来说,这个网络就是一个标准的深度学习版本。所以这里不得不佩服这个作者对传统方法和深度学习深刻的理解。
同时作者也看出了详细的网络参数,如下
1. 特征提取
特征提取没啥好说的,就是用一些卷积层从图片上提取稳健的特征用于后续匹配。但是这里必须要提一下这里的缺陷,就是特征显然感受野太小了,这也是PSMNet改进的主要方向。
2. 代价计算
在将代价计算之前,读者首先要对3D卷积有一定的了解,这里就不做介绍了。对于从两幅图片上提取到的特征,之前的方法都是再扔到一个decoder里,直接用一个黑盒子把视差估计出来。作者认为这种方法不科学,完全没有利用到多年来大家在双目立体匹配上的经验。所以作者参考SGM方法,进行了初步的代价计算。
假设左图提取的特征为
L
f
L_f
Lf,维度为
C
∗
H
∗
W
C*H*W
C∗H∗W;右图为
R
f
R_f
Rf,维度为
C
∗
H
∗
W
C*H*W
C∗H∗W;视差为
D
D
D。在GC-Net这篇文章里,代价计算很直接,即按照视差直接拼起来就行。
即新建一个维度为
D
∗
2
C
∗
H
∗
W
D*2C*H*W
D∗2C∗H∗W的特征,其中每一个
1
∗
2
C
∗
H
∗
W
1*2C*H*W
1∗2C∗H∗W的特征由
L
f
L_f
Lf和对应经过视差偏移的
R
f
(
d
)
R_f(d)
Rf(d)直接拼接得到;这里所说的视差偏移就是简单的tensor切片,空余出来的地方用padding补0。
这个比较容易懂的实现的是三维视觉工作室的博客:
def cost_volume(self,imgl,imgr):
B, C, H, W = imgl.size()
cost_vol = torch.zeros(B, C * 2, self.maxdisp , H, W).type_as(imgl)
for i in range(self.maxdisp):
if i > 0:
cost_vol[:, :C, i, :, i:] = imgl[:, :, :, i:]
cost_vol[:, C:, i, :, i:] = imgr[:, :, :, :-i]
else:
cost_vol[:, :C, i, :, :] = imgl
cost_vol[:, C:, i, :, :] = imgr
return cost_vol
3 代价聚合
代价聚合在传统SGM里非常重要的一步。在本篇文章里作者也意识到这一部分的重要性,所以用了最为复杂的3D卷积;并且为了保证质量,还使用了3D-UNet这种结构,尽可能提高聚合的质量。
4 可微视差生成
在传统SGM方法的最后一步,通常使用WTA(winner takes all)这种策略来获取最终视差。但是这种方法的问题很明显,即不可微。在这篇文中里,作者对最后一步做了一些修正,提出了可微的视差生成方法;其思路也非常简单,即用
−
c
o
s
t
-cost
−cost表示当前深度值为正确值的概率,最后用所有深度值的概率加权得到最终结果,如下(其中
σ
\sigma
σ表示的是归一化方式,这里是softmax):
当然这个公式也是有一些问题的,即当最佳视差并不是特别显著的时候(即文章中的多峰分布),其精度非常容易受到附近其他结果的干扰,导致最终视差的结果有所偏离。为了解决这个问题,作者说由两个方法,一个是对
c
o
s
t
cost
cost进行尺度缩放,增加最佳视差的显著性;另一个就是在最后一层做Batch Norm,使得分布均匀。(不过,我个人感觉应该不处理问题不大??后续实践的时候,再看看)
损失函数
损失函数直接了当,没啥好说的。
结果
总的来说,GC-Net效果不错,而且终于有一个比较合理的端到端策略。但是参数量真的是太大了。。。