Bundle Adjustment主要应用在从视觉重建中中恢复出最优的3D模型(路标)和相机参数(外参的位姿和内参矩阵)。属于从离散非线性非高斯系统中批量式最大后验估计最优状态问题。
投影模型
相机成像可以分为四个步骤:
!
(1)刚体变换只改变物体的空间位置(平移)和朝向(旋转),而不改变其形状,可用两个变量来描述:旋转矩阵R和平移向量t
R
,
t
R,t
R,t称为相机的外参(Extrinsic),相机外参决定了空间点从世界坐标系转换到相机坐标系的变换,也可以说外参描述了相机在世界坐标系中的位置和朝向。
P
′
=
R
p
+
t
=
[
X
′
,
Y
′
,
Z
′
]
T
P^{'}=Rp+t=[X^{'},Y^{'},Z^{'}]^T
P′=Rp+t=[X′,Y′,Z′]T
[
X
Y
Z
1
]
=
[
R
t
0
1
]
[
X
′
Y
′
Z
′
1
]
\begin{bmatrix} X \\ Y \\Z \\ 1\end{bmatrix} =\begin{bmatrix} R&t \\ 0&1\end{bmatrix} \begin{bmatrix} X^{'} \\ Y^{'} \\Z^{'} \\ 1\end{bmatrix}
⎣⎢⎢⎡XYZ1⎦⎥⎥⎤=[R0t1]⎣⎢⎢⎡X′Y′Z′1⎦⎥⎥⎤
(2)透视投影
我们可以将透镜的成像简单地抽象成下图所示:
!
设 f = O B f=OB f=OB表示相机的焦距, n = O A n=OA n=OA表示物距, m = O C m=OC m=OC表示像距,有
1 f = 1 m + 1 n \frac{1}{f}=\frac{1}{m}+\frac{1}{n} f1=m1+n1
一般由于物距远大于焦距, n > > f n>>f n>>f,所以 m ≈ f m \approx f m≈f,可以用小孔模型代替透镜成像模型(后面假设所有的相机模型为小孔成像模型,实际上):
!
根据相似三角形(现在你需要把上面的图想象成一个立体的形状)可以得到:
{ X X ′ = Z f Y Y ′ = Z f \begin{cases} \frac {X}{X^{'}}=\frac{Z}{f} \\ \frac {Y}{Y^{'}}=\frac{Z}{f} \end{cases} {X′X=fZY′Y=fZ
进一步简化便于写成矩阵形式(大家都爱写矩阵形式):
{ X ′ = f X Z Y ′ = f Y Z \begin{cases} {X^{'}}=f\frac{X}{Z} \\ {Y^{'}}=f\frac{Y}{Z} \end{cases} {X′=fZXY′=fZY
写为矩阵形式为:
Z [ X ′ Y ′ 1 ] = [ f 0 0 0 f 0 0 0 1 ] [ X Y Z ] Z \begin{bmatrix} X^{'} \\ Y^{'} \\1 \end{bmatrix} =\begin{bmatrix} f & 0& 0\\ 0&f&0 \\0&0&1 \end{bmatrix}\begin{bmatrix} X \\ Y \\Z \end{bmatrix} Z⎣⎡X′Y′1⎦⎤=⎣⎡f000f0001⎦⎤⎣⎡XYZ⎦⎤
至此,用
[
u
c
,
v
c
]
[{u_c},{v_c}]
[uc,vc]代替
[
X
′
,
Y
′
]
[X^{'},Y^{'}]
[X′,Y′]表示在相机归一化平面的坐标。(c表示camera)
(3)在相机坐标系进行畸变校正
通过切向畸变参数
p
1
,
p
2
p_1,p_2
p1,p2和径向畸变参数
k
1
,
k
2
k_1,k_2
k1,k2进行去畸变。
{
u
′
c
=
u
c
(
1
+
k
1
r
c
2
+
k
2
r
c
4
)
+
2
p
1
u
c
v
c
+
p
2
(
r
2
+
2
u
c
2
)
v
′
c
=
v
c
(
1
+
k
1
r
c
2
+
k
2
r
c
4
)
+
2
p
1
(
r
2
+
2
v
c
2
)
+
p
2
u
c
v
c
\begin{cases} {u^{'}}_c= u_c(1+k_1{r_c}^2+k_2 {r_c}^4) +2p_1u_cv_c+p_2(r^2+2{u_c}^2) \\ {v^{'}}_c= v_c(1+k_1{r_c}^2+k_2 {r_c}^4)+2p_1(r^2+2{v_c}^2)+p_2u_cv_c \end{cases}
{u′c=uc(1+k1rc2+k2rc4)+2p1ucvc+p2(r2+2uc2)v′c=vc(1+k1rc2+k2rc4)+2p1(r2+2vc2)+p2ucvc
其中:
r
=
u
c
2
+
v
c
2
r=\sqrt{{u_c}^2+{v_c}^2}
r=uc2+vc2
(4)矫正后的点可以通过内参矩阵投影到像素平面上
数字化图像:
[
u
i
,
v
i
]
[{u_i},{v_i}]
[ui,vi]表示图像上的一个点的像素坐标(i表示image)
PS:这里的
f
x
,
f
y
,
c
x
,
c
y
,
k
1
,
K
2
,
k
3
,
p
1
,
p
2
f_x,f_y,c_x,c_y,k_1,K_2,k_3,p_1,p_2
fx,fy,cx,cy,k1,K2,k3,p1,p2表示相机内部参数。是我们需要标定的。一旦相机结构固定,包括镜头结构固定,对焦距离固定,我们就可以用这9个的参数去近似这个相机。这里说的「镜头结构固定」,按我个人的理解,除了焦距固定之外,也应当包含光圈固定,因为改变光圈的大小,除了景深之外,是有可能改变针孔相机模型中的光心位置,但是影响并不是很大。这意味着标定好的相机如果改变光圈大小,会使得标定误差变大但应该不会大到难以接受的地步。
{
u
i
=
f
x
u
′
c
+
c
x
v
i
=
f
y
v
′
c
+
c
y
\begin{cases} {u}_i= f_x{u^{'}}_c +c_x\\ {v}_i= f_y{v^{'}}_c+c_y \end{cases}
{ui=fxu′c+cxvi=fyv′c+cy
BA求解
相机模型和路标的优化表示
现在我们把:
外参
R
,
t
R,t
R,t用李代数
ξ
\xi
ξ表示,
像素坐标
(
u
i
,
v
i
)
(u_i,v_i)
(ui,vi)用
z
z
z表示,
三维世界的路标点
[
X
,
Y
,
Z
]
T
[X,Y,Z]^T
[X,Y,Z]T用
p
p
p表示,
观测误差可以表示为:
e
=
z
−
h
(
ξ
,
p
)
e=z-h(\xi,p)
e=z−h(ξ,p)
其中
h
(
)
h()
h()为上面介绍的相机观测模型函数。
代价函数表示为:
1
2
∑
i
=
1
m
∑
j
=
1
n
e
i
j
2
=
1
2
∑
i
=
1
m
∑
j
=
1
n
[
z
i
j
−
h
(
ξ
i
,
p
j
)
]
2
\frac{1}{2}\sum_{i=1}^m \sum_{j=1}^ne_{ij}^2 =\frac{1}{2}\sum_{i=1}^m \sum_{j=1}^n [z_{ij}-h(\xi_i,p_j)]^2
21i=1∑mj=1∑neij2=21i=1∑mj=1∑n[zij−h(ξi,pj)]2
上面式子的物理意义是在
ξ
i
\xi_i
ξi处观察路标
p
j
p_j
pj得到的数据为
z
i
j
z_{ij}
zij
我们的目标是优化
[
ξ
,
p
]
[\xi ,p]
[ξ,p],使得满足如下关系:
[
ξ
^
,
p
^
]
T
=
a
r
g
min
ξ
,
p
1
2
∑
i
=
1
m
∑
j
=
1
n
[
z
i
j
−
h
(
ξ
i
,
p
j
)
]
2
[\hat\xi,\hat p]^T=arg\min_{\xi,p}\frac{1}{2}\sum_{i=1}^m \sum_{j=1}^n [z_{ij}-h(\xi_i,p_j)]^2
[ξ^,p^]T=argξ,pmin21i=1∑mj=1∑n[zij−h(ξi,pj)]2
在实际的slam过程中,我们需要优化局部的轨迹里面的多个位姿和局部地图点,所以这里进一步将
[
ξ
,
p
]
[\xi, p]
[ξ,p]表示为如下:
x
=
[
ξ
1
,
.
.
.
ξ
m
,
,
p
i
,
.
.
.
p
n
]
T
x=[\xi_1,...\xi_m,,p_i,...p_n]^T
x=[ξ1,...ξm,,pi,...pn]T
相应的增量方程表示为
1
2
∥
f
(
x
+
Δ
x
)
∥
2
≈
∥
e
i
j
+
F
i
j
Δ
ξ
i
+
E
i
j
Δ
p
i
∥
2
\frac{1}{2}{\parallel f(x+\Delta x)\parallel }^2 \approx \parallel e_{ij}+ F_{ij} \Delta \xi_i +E_{ij}\Delta p_i\parallel ^2
21∥f(x+Δx)∥2≈∥eij+FijΔξi+EijΔpi∥2
令
x
c
=
[
ξ
1
,
ξ
2
,
.
.
.
,
ξ
m
]
T
,
x
p
=
[
p
1
,
p
2
,
.
.
.
,
p
n
]
T
x_c=[\xi_1,\xi_2,...,\xi_m]^T,x_p=[p_1,p_2,...,p_n]^T
xc=[ξ1,ξ2,...,ξm]T,xp=[p1,p2,...,pn]T,
1
2
∥
f
(
x
+
Δ
x
)
∥
2
=
1
2
∥
e
+
F
Δ
x
c
+
E
Δ
x
p
∥
2
\frac{1}{2}\parallel f(x+\Delta x)\parallel ^2= \frac{1}{2}\parallel e+F\Delta x_c+E\Delta x_p\parallel ^2
21∥f(x+Δx)∥2=21∥e+FΔxc+EΔxp∥2
令雅克比矩阵
J
=
[
F
E
]
J= \begin{bmatrix} F &E \end{bmatrix}
J=[FE]
以高斯牛顿法为例子,H矩阵为
H
=
J
T
J
=
[
F
T
F
F
T
E
E
T
F
E
T
E
]
H=J^TJ= \begin{bmatrix} F^TF&F^TE\\E^TF &E^TE\end{bmatrix}
H=JTJ=[FTFETFFTEETE]
当需要优化很多位姿和地图点时,我们需要计算每一个雅克比子矩阵,即
J
i
j
J_{ij}
Jij,这里我们讨论一下每一个雅克比的子矩阵的数学推算。
J
i
j
(
x
)
=
(
0
2
×
6
,
.
.
.
,
0
2
×
6
,
∂
e
i
j
∂
ξ
i
,
0
2
×
6
,
.
.
.
,
0
2
×
3
,
∂
e
i
j
∂
p
j
,
.
.
.
,
0
2
×
3
,
.
.
.
)
J_{ij}(x)=(0_{2\times 6},...,0_{2\times 6},\frac{\partial e_{ij}}{\partial \xi_{i}},0_{2 \times 6},...,0_{2 \times 3},\frac{\partial e_{ij}}{\partial p_j},...,0_{2\times 3},...)
Jij(x)=(02×6,...,02×6,∂ξi∂eij,02×6,...,02×3,∂pj∂eij,...,02×3,...)
上式的物理含义为第i个相机位姿观测到第j个路标点。其余部分的导数都为0。
接下来我们具体介绍雅克比矩阵的推导。
雅克比矩阵推导方法
从前面的相机模型我们可以已知世界坐标系下的坐标P,相机坐标系下的坐标
P
′
P^{'}
P′,对应图像像素坐标系的点
(
u
,
v
)
(u,v)
(u,v),优化相机位姿
ξ
i
\xi_i
ξi和世界坐标系下的路标
P
j
P_j
Pj。
这里已有的公式有
s
[
u
v
1
]
=
[
f
x
0
c
x
0
f
y
c
y
0
0
1
]
[
X
′
Y
′
Z
′
]
s\begin{bmatrix} u\\v\\1\end{bmatrix}=\begin{bmatrix} f_x&0&c_x\\0&f_y&c_y\\0&0&1\end{bmatrix}\begin{bmatrix}X^{'}\\Y^{'}\\Z^{'} \end{bmatrix}
s⎣⎡uv1⎦⎤=⎣⎡fx000fy0cxcy1⎦⎤⎣⎡X′Y′Z′⎦⎤
简化得到:
u
=
f
x
X
′
Z
′
+
c
x
v
=
f
y
Y
′
Z
′
+
c
y
u=f_x\frac{X^{'}}{Z^{'}}+c_x \quad \quad\quad v_=f_y\frac{Y^{'}}{Z^{'}}+c_y
u=fxZ′X′+cxv=fyZ′Y′+cy
首先我们求
∂
e
i
j
∂
ξ
i
\frac{\partial e_{ij}}{\partial \xi_{i}}
∂ξi∂eij,当我们求误差时,可以把
u
,
v
u,v
u,v与实际的测量值相互比较,求差,其中误差
e
e
e是二维向量,定义了中间变量后,对
ξ
∧
\xi^{\wedge}
ξ∧求左乘扰动
δ
ξ
\delta\xi
δξ,然后考虑误差的变化对扰动量的导数。
∂
e
∂
δ
ξ
=
∂
e
∂
P
′
∂
P
′
∂
δ
ξ
\frac{\partial e}{\partial \delta\xi}=\frac{\partial e}{\partial P^{'}}\frac{\partial P^{'}}{\partial \delta\xi}
∂δξ∂e=∂P′∂e∂δξ∂P′
根据:
s
u
=
K
P
′
su=KP^{'}
su=KP′得
∂
e
∂
P
′
=
−
[
∂
u
∂
X
′
∂
u
∂
Y
′
∂
u
∂
Z
′
∂
v
∂
X
′
∂
v
v
∂
Y
′
∂
v
∂
Z
′
]
=
−
[
f
x
Z
′
0
−
f
x
X
′
Z
′
2
0
f
y
Z
′
−
f
y
Y
′
Z
′
2
]
\frac{\partial e}{\partial P^{'}}=-\begin{bmatrix} \frac{\partial u}{\partial X^{'}}&\frac{\partial u}{\partial Y^{'}}&\frac{\partial u}{\partial Z^{'}}\\ \frac{\partial v}{\partial X^{'}}&\frac{\partial vv}{\partial Y^{'}}&\frac{\partial v}{\partial Z^{'}} \end{bmatrix}=-\begin{bmatrix} \frac{f_x}{Z^{'}}&0&-\frac{f_x X^{'}}{Z^{'2}}\\ 0&\frac{f_y}{ Z^{'}}&-\frac{f_yY^{'}}{Z^{'2}} \end{bmatrix}
∂P′∂e=−[∂X′∂u∂X′∂v∂Y′∂u∂Y′∂vv∂Z′∂u∂Z′∂v]=−⎣⎡Z′fx00Z′fy−Z′2fxX′−Z′2fyY′⎦⎤
∂
T
P
∂
δ
ξ
=
[
I
−
P
′
∧
0
T
0
T
]
\frac{\partial TP}{\partial \delta \xi}=\begin{bmatrix}I&-P^{'\wedge}\\0^T&0^T \end{bmatrix}
∂δξ∂TP=[I0T−P′∧0T]
第一项是一个2x3的矩阵,第二项是一个3*6的矩阵,最后乘起来是一个2x6矩阵。
∂
e
∂
δ
ξ
=
−
[
f
x
Z
′
0
−
f
x
X
′
Z
′
2
−
f
x
X
′
Y
′
Z
′
2
f
x
(
1
+
X
′
2
Z
′
2
)
−
f
x
Y
′
Z
′
0
f
y
Z
′
−
f
y
Y
′
Z
′
2
−
f
y
−
f
y
Y
′
2
Z
′
2
f
y
X
′
Y
′
Z
′
2
f
y
X
′
Z
′
]
\frac{\partial e}{\partial \delta\xi}=-\begin{bmatrix}\frac{f_x}{Z^{'} } & 0 & -\frac{f_xX^{'}}{Z^{'2}} & -\frac{f_xX^{'}Y^{'}}{Z^{'2}}& f_x(1+\frac{X^{'2}}{Z^{'2}}) & -\frac{f_xY^{'}}{Z^{'}} \\ 0& \frac{f_y}{Z^{'}} & -\frac{f_yY_{'}}{Z^{'2}}& -f_y-\frac{f_yY^{'2}}{Z^{'2}} & \frac{f_yX^{'}Y^{'}}{Z^{'2}}& \frac{f_yX^{'}}{Z^{'}}\end{bmatrix}
∂δξ∂e=−⎣⎡Z′fx00Z′fy−Z′2fxX′−Z′2fyY′−Z′2fxX′Y′−fy−Z′2fyY′2fx(1+Z′2X′2)Z′2fyX′Y′−Z′fxY′Z′fyX′⎦⎤
除了位姿优化外,还需要得到特征点的空间位置的优化,
∂
e
∂
P
=
∂
e
∂
P
′
∂
P
′
∂
P
\frac{\partial e}{\partial P}=\frac{\partial e}{\partial P^{'}}\frac{\partial P^{'}}{\partial P}
∂P∂e=∂P′∂e∂P∂P′
第一项已经推导出来了,第二项为:
P
′
=
e
x
p
(
ξ
∧
)
P
=
R
P
+
t
P^{'}=exp(\xi^{\wedge})P=RP+t
P′=exp(ξ∧)P=RP+t所以:
∂
P
′
∂
P
=
R
\frac{\partial P^{'}}{\partial P}=R
∂P∂P′=R
∂
e
∂
P
=
−
[
f
x
Z
′
0
−
f
x
X
′
Z
′
2
0
f
y
Z
′
−
f
y
Y
′
Z
′
2
]
R
\frac{\partial e}{\partial P}=-\begin{bmatrix} \frac{f_x}{Z^{'}}&0&-\frac{f_x X^{'}}{Z^{'2}}\\ 0&\frac{f_y}{ Z^{'}}&-\frac{f_yY^{'}}{Z^{'2}} \end{bmatrix}R
∂P∂e=−⎣⎡Z′fx00Z′fy−Z′2fxX′−Z′2fyY′⎦⎤R
如果使用g2o的话上面已经全部写好了。区别就是g2o
对应的C++代码如下:
PS:上面是高博的视觉十四讲的内容(书上第169页)
_jacobianOplusXi是误差到空间点的导数,
_jacobianOplusXj是误差到相机位姿的导数。
和前面公式的区别就是这里面采用
f
f
f来统一描述
f
x
,
f
y
f_x,f_y
fx,fy,并且李代数的定义顺序也不同(g2o是旋转在前,平移在后)
我把每行对应的元素都写在了后面。
至此,把雅克比矩阵中每个子矩阵的表示方法就讲完了。
稀疏性和边缘化实现
H
=
J
T
J
=
[
F
T
F
F
T
E
E
T
F
E
T
E
]
=
∑
i
,
j
J
i
j
T
J
i
j
H=J^TJ=\begin{bmatrix}F^TF&F^TE\\E^TF&E^TE\end{bmatrix}=\sum_{i,j}J_{ij}^TJ_{ij}
H=JTJ=[FTFETFFTEETE]=i,j∑JijTJij
把H矩阵进行分块,H矩阵还可以表示为:
H
=
[
H
11
H
12
H
21
H
22
]
H=\begin{bmatrix}H_{11}&H_{12}\\H_{21}&H_{22}\end{bmatrix}
H=[H11H21H12H22]
高博十四讲的P251页的图很好的表示了这个矩阵对应的相机位姿和路标点之间的关系。
我的总结是:
- H 11 H_{11} H11的对角线的每个矩阵块(注意不是元素)是误差关于相机位姿的雅克比矩阵的平方,为6x6的矩阵块,矩阵块的个数为相机位姿的数量。对应图中的相机顶点。是一个对角矩阵。
- H 21 H_{21} H21和 H 12 H_{12} H12每个子矩阵对应的是误差关于路标 P P P的雅克比矩阵(2x3大小)的转置矩阵(3x2大小)与误差关于相机位姿的雅克比矩阵(2x3大小)的乘积得到的矩阵(3x6大小)。并且他们之间互为转置矩阵。对应到图中的话是位姿顶点到路标顶点的边。
- H 22 H_{22} H22对角线每个子矩阵对应的是误差关于路标的雅克比矩阵的平方(3x2与2x3矩阵的乘积为3x3的矩阵)。对应到图中的话是路标的顶点。是一个对角矩阵。
- 通过上面的每个子矩阵块以及图中顶点与边的表示,可以得到 H H H矩阵。
高博的十四讲P252页 把这四个矩阵用
B
,
E
,
E
T
,
C
B,E,E^T,C
B,E,ET,C来分别表示
H
H
H的每个大块。(这里面很多的矩阵块很容易搞晕~)
可以表示为如下:
[
B
E
E
T
C
]
=
[
Δ
x
c
Δ
x
p
]
=
[
v
w
]
\begin{bmatrix}B&E\\E^T&C\end{bmatrix}=\begin{bmatrix}\Delta x_c\\ \Delta x_p\end{bmatrix}=\begin{bmatrix}v\\w \end{bmatrix}
[BETEC]=[ΔxcΔxp]=[vw]
接下来的指导思想是:
矩阵求逆的计算量比较大,所以尽量避免矩阵求逆,而且对角块矩阵求逆相对容易一些。所以可以采用高斯消元的思想去把
H
12
H_{12}
H12或
H
21
H_{21}
H21某一个消去,然后回来求解
Δ
x
c
\Delta x_c
Δxc,
Δ
x
p
\Delta x_p
Δxp。这个过程就叫做Marginalizetion或者Schur消元。下面是边缘化的数学推理过程:
[
I
−
E
C
−
1
0
I
]
[
B
E
E
T
C
]
=
[
Δ
x
c
Δ
x
p
]
=
[
I
−
E
C
−
1
0
I
]
[
v
w
]
\begin{bmatrix}I&-EC^{-1}\\0&I\end{bmatrix} \begin{bmatrix}B&E\\E^T&C\end{bmatrix}=\begin{bmatrix}\Delta x_c\\ \Delta x_p\end{bmatrix}=\begin{bmatrix}I&-EC^{-1}\\0&I\end{bmatrix}\begin{bmatrix}v\\w \end{bmatrix}
[I0−EC−1I][BETEC]=[ΔxcΔxp]=[I0−EC−1I][vw]
[ B − E C − 1 E T 0 E T C ] [ Δ x c Δ x p ] = [ v − E C − 1 w w ] \begin{bmatrix}B-EC^{-1}E^T&0\\E^T&C\end{bmatrix}\begin{bmatrix}\Delta x_c\\ \Delta x_p\end{bmatrix}=\begin{bmatrix}v-EC^{-1}w\\ w\end{bmatrix} [B−EC−1ETET0C][ΔxcΔxp]=[v−EC−1ww]
{
[
B
−
E
C
−
1
E
T
]
Δ
x
c
=
v
−
E
C
−
1
w
Δ
x
p
=
c
−
1
(
w
−
E
T
Δ
x
c
)
\begin{cases} \begin{bmatrix}B-EC^{-1}E^T\end{bmatrix}\Delta x_c= v-EC^{-1}w\\ \Delta x_p= c^{-1}(w-E^T \Delta x_c ) \end{cases}
{[B−EC−1ET]Δxc=v−EC−1wΔxp=c−1(w−ETΔxc)
高博的十四讲在P254和P255页还讨论了
Δ
x
c
\Delta x_c
Δxc的系数
S
S
S矩阵的稀疏性在不同slam实践当中的区别以及S矩阵中共视的物理意义,总体来说第十讲讲的非常具体。