参考和整理自如下两篇文章
自动驾驶环境感知:基于PSMNet的双目深度估计
双目深度估计Pyramid Stereo Matching Network
PSMNet网络原理详解
1 概述
1.1 目标
双目深度估计的目标是通过两个相机估计场景的深度信息,进而可以将图像上像素点以及其深度信息转换为点云,再通过点云目标检测/分割方法进行三维物体检测。
1.2 优势
- 不需要先验知识。
单目3D算法往往依赖于先验知识和几何约束,如地面是平的、车辆的高度为0等,但是在实际场景中,经常无法满足这些假设; - 适用复杂场景
基于深度学习的算法如PSMNet可以在大规模、高质量、高多样性的数据集上进行训练,提升算法在实际复杂多变场景下的鲁棒性; - 解决深度歧义性
通过计算“视差”可以恢复场景的深度信息,解决了单目系统中由于透视变换带来的深度歧义性; - 检测范围广
只要目标点出现在两个相机中,都可以得到该目标点的深度信息,不依赖于物体检测的结果,对场景中的任意障碍物(如未标注的路桩、路障等)均有效。
1.3 劣势
- 硬件层面
两个摄像头需要进行位置上的精确配准才能得到精确的深度估计结果,一般在出厂时配准精度是最高的,但在车辆行驶过程中,由于颠簸、震动等会使得摄像头的位置发生偏移,需要设计在线配准算法确保配准参数的精确,这带来了额外的计算量,此外在线配准算法的设计也非常具有挑战性; - 软件层面
算法需要同时处理两个摄像头的数据,计算复杂度较高,需要配备更大算力的芯片才能保证实时计算。
2 双目深度估计
2.1 原理
双目深度估计的模型如图所示。其中X轴是车辆的横向方向,Z轴是车辆的纵向方向,由于两个相机处于同一水平线(同一高度)上,因此不需要Y轴方向。
其中两个相机在X轴上的距离为基线长度,记为
B
B
B,两个相机有相同的焦距
f
f
f,一个目标点的坐标记为
(
x
,
z
)
(x,z)
(x,z),其在左右相机上成像后的在X轴方向上的坐标大小分别为
x
l
,
x
r
x_{l}, x_{r}
xl,xr。根据相似三角形可以得到如下方程组
{
f
z
=
x
l
x
f
z
=
x
r
x
−
B
\left\{\begin{matrix} \frac{f}{z}=\frac{x_{l}}{x}\\ \frac{f}{z}=\frac{x_{r}}{x-B} \end{matrix}\right.
{zf=xxlzf=x−Bxr
整理消掉
x
x
x得到:
z
=
f
B
x
l
−
x
r
=
f
B
d
z=\frac{fB}{x_{l}-x_{r}}=\frac{fB}{d}
z=xl−xrfB=dfB
其中
d
d
d叫做视差,它与深度
z
z
z成反比,在方程中只有视差未知。因此只要求出了目标点的在两幅图像上的视差
d
d
d,就能得到目标点的深度坐标
z
z
z。由此可见双目深度估计的关键就是估计视差,即对于左图中的每个像素点,都需要在右图中找到与其匹配的点。
如下图所示,实际情况中,同一个电线杆在两幅图像上的横坐标不同。
2.2 视差范围
在双目深度估计中,需要估计的场景的深度范围是有限的,进而可以得到视差的范围是有限的。例如最远深度为90m,最近深度为10m,我们可以转换为视差范围,如最大视差10像素,最小视差1像素,由此得到了10个视差等级,即每一个像素点都有10种视差选择,对于每一个可能的视差计算匹配误差。
图像数据是2维,加上视差等级这一维度构成一个三维数据叫做Cost Volume,这将在PSMNet网络中详细介绍。
举个例子,左侧输入图像上的一个点可能对应右侧输入图像上的3中视差选择,即对应了右侧输入图像上的三个点,于是可以对这3个可能的视差来计算匹配误差,得到Cost Volume。如下图所示。
2.3 计算匹配误差的方式
- 直接计算像素值之间的差异作为匹配误差
- 考虑像素点邻域的局部区域,比如对邻域内所有像素值的差进行求和作为匹配误差
- 通过神经网络自动学习像素点邻域内的有效特征,通过这些自动提取的视觉特征计算匹配误差
3 PSMNet网络详解
双目深度估计的关键是计算匹配误差,而计算匹配误差的关键在于特征提取,于是我们使用PSMNet网络来进行特征提取和视差计算。Pyramid Stereo Matching Network简称PSMNet,是2018年提出的一个非常经典的基于神经网络的双目深度估计方法。PSMNet的整体网络结构如下图所示。
PSMNet流程如下:
- 输入图像:来自左、右两个相机的图像
- 特征提取:采用参数共享的卷积网络进行特征提取,包含用于提取多分辨率特征的下采样和金字塔结构 ,也包括在扩大感受野的同时保持特征图分辨率不变的空洞卷积;
- Cost Volume构建:采用左、右两个图像经过卷积网络后得到的特征图构建Cost Volume;
- 特征融合:采用3D卷积提取左、右特征图及不同视差级别之间的信息,得到特征融合后的Cost Volume
- 视差计算:将特征融合后的Cost Volume上采样到原始分辨率,找到匹配误差最小的视差值。
感受野
- 定义
卷积神经网络每一层输出的特征图(feature map)上的像素点映射回输入图像上的区域大小。通俗点的解释是,特征图上一点相对于原图的大小,也是卷积神经网络特征所能看到输入图像的区域。- 举例
输入图像大小为5×5,kernal_size=3×3,stride=1,padding=0,卷积后的特征图大小为N=(W-F+2P)/S+1=(5-3+2×0)/1+1=3
输入图像大小为3×3,kernal_size=3×3,stride=1,padding=0,卷积后的特征图大小为N=(W-F+2P)/S+1=(3-3+2×0)/1+1=1,此时输出特征图上的一个像素相当于原图(5×5)的5×5,此时的感受野即为5×5- 作用
小尺寸的卷积代替大尺寸的卷积,可减少网络参数、增加网络深度、扩大感受野。网络深度越深,感受野越大,性能越好。
空洞卷积
- 提出背景
空洞卷积最初是为解决图像分割的问题而提出的。常见的图像分割算法通常使用池化层来增大感受野(所以如果去掉池化层会使得感受野变小,从而影响后面的卷积层),同时也缩小了特征图尺寸,然后再利用上采样还原图像尺寸。特征图缩小再放大的过程造成了精度上的损失,因此需要有一种操作可以在增加感受野的同时保持特征图的尺寸不变(要加padding),从而替代池化与上采样操作- 计算公式
假设空洞卷积的卷积核大小为k,空洞数为d,则其等效卷积核大小k’计算如下面所示- 举例
普通卷积,K=3,S=2,P=0
空洞卷积,K = 3 r = 2 (膨胀因子/间隙) P = 0 S = 1
- 作用
在不引入额外参数的前提下可以任意扩大感受野,同时保持特征图的分辨率不变
3.1 CNN模块
作用:初步特征提取
输入:原始图像,大小为H × W × 3
输出:初步特征提取后的特征图,大小为1/4H × 1/4W × 128
输入的图像经过CNN模型实现初步的特征提取,通过一系列的下采样和空洞卷积保证网络可以得到较大感受野的特征。
CNN模块的架构如下图所示。
- 前3层参数为:kernel_size=3*3,channel=32,stride=2。conv0_1的stride=2, 经过卷积,图像由H × W × 3变为1/2H × 1/2W × 32,即将分辨率下采样到原始分辨率的1/2。
- conv1_x和conv2_x采用Resnet中经典的网络结构residual blocks,分别重复了3次和16次。conv2_x的channel=64,conv2_1的stride=2,经过卷积,图像由1/2H × 1/2W × 32变为1/4H × 1/4W × 64,即将分辨率下采样到原始分辨率的1/4。
- conv3_x和conv4_x采用了residual blocks,都重复了3次,channel=128,将residual block中的常规cnn替换为了空洞卷积(膨胀率分别为2和4),用于在提升感受野的同时保持特征图分辨率不变。
conv3_x的channel=128,使用了空洞卷积,经过卷积,图像由1/4H × 1/4W × 64变为1/4H × 1/4W × 128,即图像分辨率没有发生变化
3.2 SPP模块
作用:提取像素点周围不同尺度的邻域信息
输入:经过CNN模块初步处理后特征图,大小为1/4 H×1/4 W×128
输出:减少通道数后的特征图,既包含了不同扩大倍数感受野的特征,也包含了具有不同尺度邻域信息的特征,大小为1/4 H×1/4 W×32
SPP模块的全称是Specail Pyramid Pooling,用于提取像素点周围不同尺度的邻域信息。具体结构如下图所示。
- SPP中包含4个分支,对应着大小为64×64、32×32、16×16、8×8的average pooling。经过四个池化得到的特征图大小为1/256H × 1/256W × 128, 1/128H × 1/128W × 128, 1/64H × 1/64W × 128, 1/32H × 1/32W × 128。
pooling的尺寸越大,对应着在原图中的感受野就越大,意味着获取到的特征更偏向于全局特征,
pooling的尺寸越小,对应着在原图中的感受野就越小,意味着获取到的特征更偏向于局部特征。
- 通过尺寸不同的pooling可以获取位于不同全局层次的邻域特征,这些特征会依次经过kernel_size=3×3, channel=32的卷积层,通过上采样(双线性插值)恢复到SPP的输入特征分辨率1/4H × 1/4W × 32,并与CNN模块在conv2_16(1/4H × 1/4W × 64)和conv4_3(1/4H × 1/4W × 128)的输出在channel上进行拼接,得到1/4H × 1/4W × 320(64+128+32*4)的特征图,作为SPP的输出。
- 为了减少特征图的通道数,依次采用了kernel_size=3×3, channel=128和kernel_size=1×1, channel=32的卷积将SPP的输出特征图大小变为1/4H × 1/4W × 32。
3.3 构建Cost Volume
作用:通过特征图合成Cost Volume
输入:左右相机的特征图,大小为1/4H × 1/4W × 32
输出:1/4D个大小为1/4H × 1/4W × 64的Cost Volume
经过CNN模块和SPP模块,左、右两个相机的输入图像(H×W×3)被转换为两个特征图(1/4 H×1/4 W×32),在这两个特征图上有着丰富的全局与局部的信息。该步骤就是通过这两个特征图构建Cost Volume,具体构建过程如下图所示。
其中橙色的部分是来自左侧的特征图(1/4H × 1/4W × 32),蓝色的是来自右侧的特征图(1/4H × 1/4 W × 32)。假设一共有D个视差等级,视差等级1对应着1个像素、视差等级2对应着2个像素······视差等级D对应着D个像素。
- 平移
我们以左侧特征图为基准,向左平移右侧特征图,分别移动1个像素,2个像素······D个像素,得到D个左右特征图的组合。 - 组合
将移动后的特征图在Channel上进行拼接,将右侧特征图多余的部分裁剪掉,空缺的部分补0。得到每一个等级的视差图,大小为1/4H × 1/4W × 64(32×2)。 - 由于当前特征图的下采样倍数是1/4,所以视差等级也会进行相应比例的下采样,即共有1/4D个大小为1/4H × 1/4W × 64的Cost Volume(可以视为4D Tensor)。
3.4 特征融合
作用:对4D Cost Volume信息融合,得到3D Cost Volume
输入:4D Cost Volume,大小为1/4D×1/4H×1/4W×64
输出:3D Cost Volume,大小为D×H×W
上一步得到的4D Tensor中既包含左右图像间的信息,也包含不同视差等级间的信息。本模块采用3维卷积对4D Cost Volume中的信息进一步融合和提取,得到3D Cost Volume。PSMNet网络提供了2种版本。如下图所示。
3.4.1 基础版本
- 卷积层
采用residual block的结构堆叠12个3×3×3的三维卷积 - 上采样层
最后一层三维卷积后面接入上采样层,将图像分辨率上采样(双线性插值)到H×W×D×C - 降维
采用kernel_size=3×3×3, channel=1的三维卷积将特征图的channel数变为1,由此得到3维 Tensor,大小为H×W×D
3.4.2 Stacked hourglass版本
使用了一个堆叠的沙漏(编码器-解码器)体系结构,由重复的自顶向下/自底向上处理以及中间监督组成。堆叠沙漏架构有三个主要的沙漏网络,每个网络生成一个视差图。即堆叠沙漏结构有三个输出和损耗(Loss 1, Loss 2, Loss 3),
-
先下采样后上采样
重复采用3次沙漏网络,在每个沙漏网络中特征图的分辨率都先下降至1/16H × 1/16W × 1/16D再上采样回1/4H × 1/4W × 1/4D。如下图所示。3DstackX_x表示沙漏网络。
-
降维和上采样回原尺寸
采用kernel_size=3×3×3, channel=1的三维卷积将特征图的channel数变为1,由此相当于得到了一个3个3维Tensor
3个沙漏网络的最后一层都接了上采样层(Bilinear interpolation)将特征图的分辨率上采样回H×W×D
3.5 视差计算
在上一步特征融合中,得到的大小为H×W×D的3维Tensor其实就是具有D个视差等级的Cost Volume(第2部分提到的Cost Volume),每个视差
d
d
d的概率由预测成本
c
d
c_{d}
cd通过softmax运算
σ
(
⋅
)
\sigma(·)
σ(⋅)计算,预测的视差
d
^
\hat{d}
d^是用每个视差
d
d
d的概率加权的和来计算的,具体公式如下:
d
^
=
∑
d
=
0
D
m
a
x
d
×
σ
(
−
c
d
)
\hat{d}=\sum_{d=0}^{D_{max}}d×\sigma(-c_{d})
d^=d=0∑Dmaxd×σ(−cd)
其中,
d
^
\hat{d}
d^是网络预测视差,
d
d
d是实际视差,
c
d
c_{d}
cd表示视差
d
d
d对应的像素匹配误差,
D
m
a
x
D_{max}
Dmax表示最大视差等级。
为什么使用softmax处理而不直接使用argmin
在传统视差计算中,只需要对于每个像素点,在视差等级这个维度上将具有最小匹配误差的视差作为该像素点的视差即可,相当于是对所有像素点在视差等级维度上进行Argmin操作。
但是Argmin这个操作是不可微的,无法采用BP训练,而且这个操作得到的视差都是整数,无法得到亚像素的视差估计。
因此PSMNet采用了End-to-End Learning of Geometry and Context for Deep Stereo Regression提出的Soft ArgMin来替代传统的ArgMin:
- 假设共有 0 − D m a x 0-D_{max} 0−Dmax个视差等级,视差 d d d对应的像素匹配误差为 c d c_{d} cd
- 采用softmax操作 σ ( − c d ) \sigma(-c_{d}) σ(−cd)将匹配误差转换为0-1之间的概率值。
当 c d c_{d} cd越大时,代表当前像素点在当前视差等级 d d d下的匹配误差越大,当前像素点属于当前视差等级的概率越小,因此概率值 σ ( − c d ) \sigma(-c_{d}) σ(−cd)越小;
当 c d c_{d} cd越小时,代表当前像素点在当前视差等级 d d d下的匹配误差越小,当前像素点属于当前视差等级的概率越大,因此概率值 σ ( − c d ) \sigma(-c_{d}) σ(−cd)越大
- 将 0 − D m a x 0-D_{max} 0−Dmax的每个视差 d d d乘以属于该视差等级的概率,最后进行求和即可得到soft版本的argmin
与ArgMin操作相比,这种Soft ArgMin是可微的,而且得到的值是连续的,Soft ArgMin的示意图如下图所示,横坐标为视差等级(单位是像素),纵坐标分别是匹配误差
c
d
c_{d}
cd、取负值后的
c
d
c_{d}
cd、概率
σ
(
−
c
d
)
\sigma(-c_{d})
σ(−cd)、视差等级以及视差等级×概率后的值,从图中可以看出Soft ArgMin和ArgMin的结果相差很小。
3.6 Loss
从上述视差计算过程可以看出,视差计算Soft ArgMin是一个回归问题,此PSMNet采用了SoomthL1 Loss。损失函数如下。
L
(
d
,
d
^
)
=
1
N
∑
i
=
1
N
s
m
o
o
t
h
L
1
(
d
i
−
d
i
^
)
L(d,\hat{d})=\frac{1}{N}\sum_{i=1}^{N}smooth_{L_{1}}(d_{i}-\hat{d_{i}})
L(d,d^)=N1i=1∑NsmoothL1(di−di^)
s
m
o
o
t
h
L
1
(
x
)
=
{
0.5
x
2
,
i
f
∣
x
∣
<
1
∣
x
∣
−
0.5
,
o
t
h
e
r
w
i
s
e
smooth_{L_{1}}(x)=\left\{\begin{matrix} 0.5x^{2}, & if\left | x\right|<1\\ \left | x\right | -0.5,& otherwise \end{matrix}\right.
smoothL1(x)={0.5x2,∣x∣−0.5,if∣x∣<1otherwise
其中,
N
N
N是像素点个数,
d
^
\hat{d}
d^是网络预测视差,
d
d
d是视差的真实标注。
在特征融合模块使用的时Stacked hourglass版本,其中包含3个漏斗网络,每个网络都会生成一个视差图,因此会输出3个Loss。论文经过实验将3个Loss的weight设置为0.5、0.7、1.0得到了最佳结果。从下图的消融实验可以看出,将前两个漏斗网络输出的视差图添加到训练过程的Loss计算和BP中,确实可以明显提升性能。
4 总结
PSMNet是一种端到端的双目深度估计方法,该网络的亮点在于在Backbone处添加了空洞卷积以增大感受野并采用pyramid pooling提取不同尺度的邻域信息生成初步的Cost Volume,然后采用stacked hourglass对Cost Volume中包含的左、右图像之间的信息和不同视差等级之间的信息进行进一步融合,PSMNet的消融实验也证实了这些方法对于性能提升确实是有效的。
PSMNet的效果图如下,在视差图中颜色越接近蓝色表示视差越大,深度越小;颜色越接近红色表示视差越小,深度越大。