系列文章目录
提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
前言
Droid-SLAM个人笔记,无参考价值
3 Approach
Droid-SLAM系统将视频作为输入,有两个目标:估计相机的轨迹和构建环境的3D地图。首先描述单目设置;在第3.4节中,再描述如何将系统推广到立体声和RGB-D视频。
Representation: Droid-SLAM的网络运行在有序的图像集合上,
{
I
t
}
t
=
0
N
\{I_t\}_{t=0}^N
{It}t=0N。对于每个图像t,有两个状态变量:相机姿态
G
t
∈
S
E
(
3
)
G_t\in SE(3)
Gt∈SE(3) 和逆深度
d
t
∈
R
+
H
×
W
d_t\in R_+^{H×W}
dt∈R+H×W。相机位姿序列集
{
G
t
}
t
=
0
N
\{G_t\}^N_{t=0}
{Gt}t=0N 和逆深度集
{
d
t
}
t
=
0
N
\{d_t\}^N_{t=0}
{dt}t=0N 是未知的状态变量,在推理过程中随着新帧的处理而迭代更新。后续提到深度时,请注意使用的是逆深度。
Droid-SLAM 采用 帧图
(
ν
,
ε
)
(\nu,\varepsilon)
(ν,ε) 来表示帧之间的共视性。一条边
(
i
,
j
)
∈
ε
(i,j) \in \varepsilon
(i,j)∈ε 的表示图像
I
i
I_i
Ii 和
I
j
I_j
Ij 具有重叠的视场,这些视场共享点云。帧图是在训练和推理过程中动态构建的。每次相机位姿或图像深度更新后,可以重新计算可见性来更新帧图。如果相机返回到先前映射的区域,可以在图中添加远距离连接来执行闭环。
帧图(frame-graph)
Frame-Graph ( ν , ε ) (\nu,\varepsilon) (ν,ε):这是一个图结构,其中:
- ν \nu ν 是节点(Nodes)的集合,每个节点代表一帧图像(Frame)。
- ε \varepsilon ε 是边(Edges)的集合,每条边代表两帧图像之间的关系。
边 e d g e ( i , j ) ∈ ε edge(i,j) \in \varepsilon edge(i,j)∈ε
图中的一条边 ( i , j ) (i,j) (i,j) 连接节点 i i i 和节点 j j j,表示帧 I i I_i Ii 和帧 I j I_j Ij之间存在某种关系。视野有重叠,并且它们共享一些观测点。
3.1 Feature Extraction and Correlation
对添加到系统中的每个图像提取特征,得到 密集特征图。这里借用了RAFT(具体阅读这篇)。
3.1.1 Feature Extraction
每个输入图像都由一个特征提取网络进行处理。该网络由6个残差块和3个下采样层组成,以输入图像分辨率的1/8产生密集的特征图。像RAFT一样,使用两个独立的网络:一个特征网络和一个上下文网络。特征网络用于构建相关性体积,而上下文特征在更新算子的每次应用过程中被注入网络。
3.1.2 Correlation Pyramid
对于帧图中的每条边
(
i
,
j
)
∈
ε
(i, j)\in \varepsilon
(i,j)∈ε,通过取
g
θ
(
I
i
)
g_θ(I_i)
gθ(Ii) 和
g
θ
(
I
j
)
g_θ(I_j)
gθ(Ij) 中所有特征向量对之间的点积来计算4D相关性体积。
C
u
1
v
1
u
2
v
2
i
j
⟨
g
θ
(
I
i
)
u
1
v
1
,
g
θ
(
I
i
)
u
2
v
2
⟩
C_{u_1v_1u_2v_2}^{ij} \langle g_θ(I_i)_{u_1v_1}, g_θ(I_i)_{u_2v_2} \rangle
Cu1v1u2v2ij⟨gθ(Ii)u1v1,gθ(Ii)u2v2⟩
然后,在RAFT之后对相关体积的最后两个维度进行平均池化,以形成4级相关性体积金字塔。
3.1.3 Correlation Lookup
定义了一个查找运算符,它使用半径为
r
r
r 的网格对相关量进行索引。
L
r
:
R
H
×
W
×
H
×
W
×
R
H
×
W
×
2
↦
R
H
×
W
×
(
r
+
1
)
2
L_r:R^{H\times W\times H\times W} \times R^{H\times W \times 2} \mapsto R^{H\times W \times (r+1)^2}
Lr:RH×W×H×W×RH×W×2↦RH×W×(r+1)2
查找算子以
H
×
W
H×W
H×W 坐标网格为输入,使用双线性插值从相关体中检索值。该算子应用于金字塔中的每个相关体,并通过连接每个级别的结果来计算最终的特征向量,得到相关特征向量集合。
3.2 Update Operator
Droid-SLAM系统的核心组件是一个可学习的更新运算符,如图所示。
更新运算符是具有隐藏状态h的3×3卷积GRU。运算符的每个应用程序都会更新隐藏状态,并额外生成姿势更新量
Δ
ξ
(
k
)
Δ\xi^{(k)}
Δξ(k) 和深度更新量
Δ
d
(
k
)
Δd^{(k)}
Δd(k)。姿态和深度更新量分别通过
S
E
3
SE3
SE3 流形上的回缩和矢量加法对当前深度和姿态估计进行更新。
G
(
k
+
1
)
=
E
x
p
(
Δ
ξ
(
k
)
)
∘
G
(
k
)
,
d
(
k
+
1
)
=
Δ
d
(
k
)
+
d
(
k
)
G^{(k+1)}=Exp(\Delta \xi^{(k)}) \circ G^{(k)}, d^{(k+1)}=\Delta d^{(k)} + d^{(k)}
G(k+1)=Exp(Δξ(k))∘G(k),d(k+1)=Δd(k)+d(k)
更新算子的迭代应用产生一系列姿势和深度,期望收敛到固定点以反映真实的重建。
G
(
k
)
→
G
∗
,
d
(
k
)
→
d
∗
{G^{(k)}}→G^*,{d^{(k)}}→d^*
G(k)→G∗,d(k)→d∗
3.2.0 ConvGRU
GRU(Gated Recurrent Unit,门控循环单元) 是一种用于处理序列数据的循环神经网络(RNN) 变体。它由 Cho et al. (2014) 提出,旨在解决传统 RNN 的梯度消失问题,并简化 LSTM(长短期记忆网络) 的结构。GRU 通过引入门控机制,能够更好地捕捉序列数据中的长期依赖关系。
1. GRU 的核心思想
GRU 的核心思想是通过门控机制控制信息的流动,从而决定哪些信息需要保留,哪些信息需要丢弃。GRU 包含两个门:
- 重置门(Reset Gate):控制前一时刻的隐藏状态对当前时刻的影响。
- 更新门(Update Gate):控制当前时刻的隐藏状态如何更新。
2. GRU 的结构
GRU 的每个时间步的计算过程如下:
(1) 重置门(Reset Gate)
重置门决定前一时刻的隐藏状态
h
t
−
1
h_{t-1}
ht−1 对当前时刻的影响。计算公式:
r
t
=
σ
(
W
r
⋅
[
h
t
−
1
,
x
t
]
)
r_t=\sigma(W_r \cdot [h_{t-1},x_t])
rt=σ(Wr⋅[ht−1,xt])
其中,
r
t
r_t
rt是重置门的输出,
σ
σ
σ 是 Sigmoid 激活函数,
W
r
W_r
Wr是重置门的权重矩阵,
h
t
−
1
h_{t-1}
ht−1是前一时刻的隐藏状态,
x
t
x_t
xt是当前时刻的输入。
(2) 更新门(Update Gate)
更新门决定当前时刻的隐藏状态如何更新。计算公式:
z
t
=
σ
(
W
z
⋅
[
h
t
−
1
,
x
t
]
)
z_t=\sigma(W_z \cdot [h_{t-1},x_t])
zt=σ(Wz⋅[ht−1,xt])
其中,
z
t
z_t
zt 是更新门的输出。
W
z
W_z
Wz是更新门的权重矩阵。
(3) 候选隐藏状态(Candidate Hidden State)
候选隐藏状态是基于重置门和当前输入计算的临时隐藏状态。计算公式:
h
~
t
=
t
a
n
h
(
W
⋅
[
r
t
⊙
h
t
−
1
,
x
t
]
)
\widetilde{h}_t=tanh(W\cdot [r_t \odot h_{t-1},x_t])
h
t=tanh(W⋅[rt⊙ht−1,xt])
其中:
h
~
t
\widetilde{h}_t
h
t是候选隐藏状态, $\odot
是逐元素乘法(
H
a
d
a
m
a
r
d
积),
是逐元素乘法(Hadamard 积),
是逐元素乘法(Hadamard积),tanh$ 是双曲正切激活函数。
(4) 最终隐藏状态(Final Hidden State)
最终隐藏状态是更新门和候选隐藏状态的加权组合。计算公式:
h
t
=
(
1
−
z
t
)
⊙
h
t
−
1
+
z
t
⊙
h
~
t
h_t=(1-z_t)\odot h_{t-1} + z_t \odot \widetilde{h}_t
ht=(1−zt)⊙ht−1+zt⊙h
t
其中:
h
t
h_t
ht是当前时刻的隐藏状态
3. ConvGRU
在GRU的基层上进行修改,用卷基层替换了全连接层。公式变为:
r
t
=
σ
(
C
o
n
v
3
×
3
(
[
h
t
−
1
,
x
t
]
,
W
r
)
)
z
t
=
σ
(
C
o
n
v
3
×
3
(
[
h
t
−
1
,
x
t
]
,
W
z
)
)
h
~
t
=
t
a
n
h
(
C
o
n
v
3
×
3
(
[
r
t
⊙
h
t
−
1
,
x
t
]
,
W
h
)
)
h
t
=
(
1
−
z
t
)
⊙
h
t
−
1
+
z
t
⊙
h
~
t
r_t=\sigma(Conv_{3\times 3}([h_{t-1},x_t],W_r))\\ z_t=\sigma(Conv_{3\times 3}([h_{t-1},x_t],W_z))\\ \widetilde{h}_t=tanh(Conv_{3\times 3}([r_t \odot h_{t-1},x_t],W_h)) \\ h_t=(1-z_t)\odot h_{t-1} + z_t \odot \widetilde{h}_t
rt=σ(Conv3×3([ht−1,xt],Wr))zt=σ(Conv3×3([ht−1,xt],Wz))h
t=tanh(Conv3×3([rt⊙ht−1,xt],Wh))ht=(1−zt)⊙ht−1+zt⊙h
t
3.2.1 Correspondence
orrespondence(对应关系)是指 两帧图像之间 或 图像与地图之间 的 特征点的匹配关系。在每次迭代开始时,先使用姿势和深度的当前估计来估计两帧图像之间的对应关系。在第
i
i
i帧的图像坐标
p
i
∈
R
H
×
W
×
2
p_i\in R^{H\times W\times 2}
pi∈RH×W×2,可以先计算出密集的对应关系场(Correspondence Field):
p
i
j
pij
pij
p
i
j
=
Π
c
(
G
i
j
∘
Π
c
−
1
(
p
i
,
d
i
)
)
,
p
i
j
∈
R
H
×
W
×
2
,
G
i
j
=
G
j
∘
G
i
−
1
p_{ij}=\Pi_c(G_{ij} \circ \Pi_c^{-1}(p_i,d_i)), \ \ \ \ p_{ij}\in R^{H\times W\times 2},\ \ \ \ G_{ij}=G_j \circ G_i^{-1}
pij=Πc(Gij∘Πc−1(pi,di)), pij∈RH×W×2, Gij=Gj∘Gi−1
- Π c \Pi_c Πc: 将一组3D点映射到图像上的相机模型
- Π c − 1 \Pi_c^{-1} Πc−1: 是逆投影函数,利用逆深度图 d i d_i di 和像素坐标 p i p_i pi 生成相机坐标系下的3D点云
- G i j G_{ij} Gij: 是两帧的相对位姿变换矩阵,可以将帧 i i i相机坐标系下的3D点云,变换到帧 j j j相机坐标系下
- p i j p_{ij} pij: 是一个二维场,表示从图像 i i i 中的每个像素到图像 j j j 中对应像素的映射关系。 P i j : R 2 → R 2 P_{ij}: R^2\rightarrow R^2 Pij:R2→R2
3.2.2 Input
使用对应关系场
p
i
j
p _{ij}
pij(Correspondence Field)来索引相关性体积
C
i
j
C_{ij}
Cij(correlation volumes)。对于每一个
e
d
g
e
(
i
,
j
)
∈
ε
edge (i, j) ∈ \varepsilon
edge(i,j)∈ε,使用
p
i
j
p_{ij}
pij 从相关体积
C
i
j
C_{ij}
Cij 执行查找以得到相关性特征图(这一点与RAFT
不同)。此外,使用对应关系场导出相机运动引起的光流为:
p
i
j
−
p
j
p_{ij}−p_j
pij−pj。
- p i j p _{ij} pij:从图像 i i i中的像素到图像 j j j中对应像素的映射。
- p j p_j pj:图像 j j j中的像素坐标。
- p i j − p i p_{ij}−p_i pij−pi:表示图像 i i i中的像素在图像 j j j中的位移,即光流。表示的是像素 p i p_i pi 在图像 j j j 中的位移
此外,Droid-SLAM系统还将上一轮 BA 的残差 与 光流进行拼接(Concatenate),从而使网络能够利用到上一轮迭代的反馈信息。
相关特征提供了关于
p
i
j
pij
pij 邻域视觉相似性的信息,允许网络学习对齐视觉上相似的图像区域。然而,对应关系
p
i
j
p_{ij}
pij 有时是模糊的,光流就提供了一个互补的信息源,允许网络利用运动场中的平滑性来获得鲁棒性。
3.2.3 Update
相关特征和流特征在注入GRU之前分别先通过两个卷积层进行卷积。此外,通过元素加法将上下文网络提取的上下文特征注入GRU。
ConvGRU是一种局部操作,具有较小的感受野。通过在图像的空间维度上平均化隐藏状态来提取全局上下文,并使用此特征向量作为GRU的附加输入。全局上下文在SLAM中很重要,因为不正确的对应关系(correspondences),例如由大型移动物体引起的不正确的对应关系,会降低系统的准确性。网络识别和拒绝错误的通信非常重要。网络能够识别和拒绝错误的对因关系是非常重要的。
GRU产生更新的隐藏状态
h
(
k
+
1
)
h^{(k+1)}
h(k+1)。网络不直接预测深度或相机位姿的更新,而是预测密集流场空间的更新。我们通过两个额外的卷积层映射隐藏状态以产生两个输出:
- 用于更新对应关系的 r i j ∈ R H × W × 2 r_{ij}\in R^{H×W×2} rij∈RH×W×2,更新公式: p i j ∗ = r i j + p i j p^*_{ij}=r_{ij}+p_{ij} pij∗=rij+pij
- 关联置信度图 w i j ∈ R + H × W × 2 w_{ij}\in R^{H×W×2}_+ wij∈R+H×W×2
然后,对于所有 共享同一源视图 I I I的特征,对它们的隐藏状态进行池化,使用池化后的隐藏状态,预测一个像素阻尼因子 λ λ λ。使用softplus运算符来确保阻尼项是正的。此外,使用池化特征来预测 8 × 8 8\times 8 8×8的掩模,该掩模可用于对逆深度估计进行上采样。
3.2.4 Dense Bundle Adjustment Layer (DBA)
Dense Bundle Adjustment Layer (DBA) 的作用,即将 光流修正(Flow Revisions) 映射为相机位姿更新(Pose Updates)和像素级深度更新(Pixel-wise Depth Updates)。定义代价函数为:
E
(
G
′
,
d
′
)
=
∑
(
i
,
j
)
∈
ε
∥
p
i
j
∗
−
Π
c
(
G
i
j
′
∘
Π
c
−
1
(
p
i
,
d
i
′
)
)
∥
Σ
i
j
2
,
Σ
i
j
=
d
i
a
g
w
i
j
E(G',d')=\sum _{(i,j)\in \varepsilon} \| p^*_{ij} - \Pi_c(G'_{ij} \circ \Pi_c^{-1}(p_i,d'_i))\|^2_{\Sigma_{ij}}, \ \ \ \ \Sigma_{ij} = diag\ w_{ij}
E(G′,d′)=(i,j)∈ε∑∥pij∗−Πc(Gij′∘Πc−1(pi,di′))∥Σij2, Σij=diag wij
其中,
∥
⋅
∥
Σ
\|\cdot\|_{\Sigma}
∥⋅∥Σ 是基于置信度权重
w
i
j
w_{ij}
wij对误差项进行加权的马氏距离。公式表所想得到一个更新的姿势
G
′
G'
G′ 和深度
d
′
d'
d′,使得重新投影的点与更新运算符预测的修改后的对应关系
p
i
j
∗
p^*_{ij}
pij∗相匹配。
3.3 Training
3.3.1 Removing gauge freedom
在单目 SLAM 中,网络只能恢复相机轨迹的相似变换(即存在规范自由度)。这会导致以下问题:
- 训练不稳定:规范自由度会影响线性系统的条件数和梯度的稳定性。
- 优化困难:规范自由度会导致优化过程难以收敛。
为了解决规范自由度的问题,文中提出固定前两个位姿的方法:
- 将每个训练序列的前两个相机位姿固定为真实值(Ground-Truth)。
- 固定第一个位姿:移除 6-DoF 自由度(平移和旋转)。
- 固定第二个位姿:解决尺度自由度。
3.3.2 Constructing training video
每个训练样本由一个 7 帧的视频序列 组成,并且需要确保这些视频序列的难度适中,既不太简单也不太困难。训练集由一组视频组成。通过预计算的 距离矩阵(Distance Matrix) 动态生成训练视频序列。对于每一个视频,预先计算了存储每对帧之间平均光流辐值(the average Optical Flow Magnitude) 的 N i × N i N_i\times N_i Ni×Ni距离矩阵。然而,并非所有帧都是共视的;重叠小于50%的帧对被分配了无限远的距离。在训练过程中,我们通过距离矩阵中的采样路径(Sampling Paths) 动态生成视频,使得相邻视频帧之间的平均流量在8px到96px之间。
关键术语解释
- Distance Matrix(距离矩阵)
- 定义:距离矩阵是一个 N i × N i N_i \times N_i Ni×Ni 的矩阵,其中 N i N_i Ni是视频的长度(帧数)。
- 作用:存储每对帧之间的平均光流幅值(Average Optical Flow Magnitude),用于衡量帧之间的运动距离
- Optical Flow Magnitude(光流幅值)
- 定义:光流幅值是光流向量的长度,表示像素从一帧到另一帧的位移大小。
- 作用:用于衡量帧之间的运动强度。
- Covisible Frames(共视帧)
- 定义:共视帧是指两帧图像之间有足够的重叠区域(如超过 50% 的重叠)。
- 作用:只有共视帧才能建立有效的对应关系。
- Sampling Paths(采样路径)
- 定义:在距离矩阵中,采样路径是指从一帧到另一帧的序列。
- 作用:通过采样路径,可以动态生成训练视频序列。
3.3.3 Supervision
使用位姿损失和流量损失的组合来监督我们的网络。
-
流量损失应用于相邻帧对。使用预测的深度和位姿,计算两帧图像之间的光流,再使用真实深度和位姿,计算两帧图像之间的光流,然后比较预测光流和真实光流,损失取两个流场之间的平均 L 2 L2 L2损失。
-
给定一组真值位姿和对应预测位姿,位姿损失取为两者之间的距离, L p o s e = ∑ i ∥ L o g S E 3 ( T i − 1 ⋅ G i ) ∥ 2 L_{pose} = \sum_i\| Log_{SE3}(T^{-1}_i \cdot G_i)\|_2 Lpose=∑i∥LogSE3(Ti−1⋅Gi)∥2。使用γ=0.9将损失应用于每次迭代的输出权重呈指数增加。
3.4 SLAM
在推理过程中,将网络组成一个完整的SLAM系统。SLAM系统以视频流为输入,实时执行重建和定位。系统包含两个异步运行的线程。前端线程接收新帧,提取特征,选择关键帧,并执行本地捆绑调整(local bundle adjustment)。后端线程对系统整个过程的关键帧序列的进行全局捆绑调整(global bundle adjustment)。
3.4.1 Initialization
使用DROID-SLAM初始化很简单。收集帧,直到累积到 12 帧。在累积帧的过程中,只保留光流大于 16px 的帧。在累积到 12 帧后,构建初始的帧图。在帧图中,为时间间隔不超过 3 个时间步的关键帧之间创建边。运行 10 次更新算子,优化帧图中的相机位姿和地图点。
3.4.2 Frontend
前端直接对传入的视频流进行操作。它维护关键帧的集合和一个帧图,存储可视kefyrames之间的边缘。关键帧姿势和深度正在积极优化。
首先从传入的帧中提取特征。然后将新帧添加到帧图中,添加边缘及其3个最接近的邻居,边的权重通过平均光流幅值来衡量。使用线性运动模型初始化新帧的相机位姿。运行多次更新算子,优化关键帧的相机位姿和深度。固定前两个位姿,以移除规范自由度。
对于每一对关键帧,计算它们之间的平均光流幅值。平均光流幅值越小,表示两帧之间的内容越相似。如果某对关键帧之间的平均光流幅值小于某个阈值,则认为它们是冗余的。选择其中一个关键帧进行移除。如果没有找到合适的冗余帧,则移除最旧的关键帧。
3.4.3 Backend
使用所有关键帧之间的光流幅值构建距离矩阵。首先为时间相邻的关键帧之间创建边。按照光流幅值从小到大的顺序,从距离矩阵中采样新边。对于每个选中的边,抑制其切比雪夫距离为 2 以内的邻近边。使用重建的帧图,运行全局 Bundle Adjustment,优化所有关键帧的位姿和地图点。
然后,将更新运算符应用于整个帧图,通常由数千个帧和边组成。存储完整的相关卷集将很快超过显存。相反,使用RAFT[49]中提出的内存高效实现。
在训练过程中,Droid-SLAM在PyTorch中实现了密集束调整以利用自动微分引擎。在推理时,使用自定义CUDA内核,该内核利用问题的块稀疏结构,然后对简化的相机块进行稀疏乔莱斯基分解。
只对关键帧图像进行全束调整。为了恢复非关键帧的姿势,通过迭代估计每个关键帧与其相邻非关键帧之间的流来执行仅运动束调整(motion-only bundle adjustment)。在测试期间,评估整个相机轨迹,而不仅仅是关键帧。
3.4.4 Stereo and RGB-D
对于Stereo和RGB-D视频,系统可以很容易地修改。在RGB-D的情况下,仍然将深度视为一个变量,因为传感器深度可能会很嘈杂,并且会丢失观察结果,并且只需在优化目标中添加一个项,该项惩罚测量和预测深度之间的平方距离。对于Stereo,使用与上述完全相同的系统,仅使用两倍的帧,并在DBA层中固定左右帧之间的相对姿势。图中的交叉相机边缘允许我们利用Stereo信息。