目录
VSLAM学习(一) 三维运动、相机模型、SLAM模型
VSLAM学习(二) 非线性优化
VSLAM学习(三) 单目相机位姿估计
VSLAM学习(四) Bundle Adjustment
一、三维空间刚体运动
1.1 旋转矩阵
同一向量在不同坐标系下的坐标不同
假如有两组坐标系,他们的基分别为
(
e
1
,
e
2
,
e
3
)
(\boldsymbol e_1,\boldsymbol e_2,\boldsymbol e_3)
(e1,e2,e3)和
(
e
1
′
,
e
2
′
,
e
3
′
)
(\boldsymbol e_1',\boldsymbol e_2',\boldsymbol e_3')
(e1′,e2′,e3′),向量
a
\boldsymbol a
a在这两组坐标系下的坐标分别为
(
a
1
,
a
2
,
a
3
)
T
(a_1,a_2,a_3)^{\mathrm T}
(a1,a2,a3)T和
(
a
1
′
,
a
2
′
,
a
3
′
)
T
(a_1',a_2',a_3')^{\mathrm T}
(a1′,a2′,a3′)T,那么他们满足
( e 1 , e 2 , e 3 ) ( a 1 a 2 a 3 ) = ( e 1 ′ , e 2 ′ , e 3 ′ ) ( a 1 ′ a 2 ′ a 3 ′ ) (\boldsymbol e_1,\boldsymbol e_2,\boldsymbol e_3) \begin{pmatrix} a_1 \\ a_2 \\ a_3 \end{pmatrix}= (\boldsymbol e_1',\boldsymbol e_2',\boldsymbol e_3') \begin{pmatrix} a_1' \\ a_2' \\ a_3' \end{pmatrix} (e1,e2,e3)⎝ ⎛a1a2a3⎠ ⎞=(e1′,e2′,e3′)⎝ ⎛a1′a2′a3′⎠ ⎞
即
a = ( a 1 a 2 a 3 ) = ( e 1 T e 2 T e 3 T ) ( e 1 ′ , e 2 ′ , e 3 ′ ) ( a 1 ′ a 2 ′ a 3 ′ ) = ( e 1 T e 1 ′ e 1 T e 2 ′ e 1 T e 3 ′ e 2 T e 1 ′ e 2 T e 2 ′ e 2 T e 3 ′ e 3 T e 1 ′ e 3 T e 2 ′ e 3 T e 3 ′ ) a ′ = d e f R a ′ \begin{aligned} \boldsymbol a= \begin{pmatrix} a_1 \\ a_2 \\ a_3 \end{pmatrix}&= \begin{pmatrix} \boldsymbol e_1^{\mathrm T} \\ \boldsymbol e_2^{\mathrm T} \\ \boldsymbol e_3^{\mathrm T} \end{pmatrix} (\boldsymbol e_1',\boldsymbol e_2',\boldsymbol e_3') \begin{pmatrix} a_1' \\ a_2' \\ a_3' \end{pmatrix} \\ &=\begin{pmatrix} \boldsymbol e_1^{\mathrm T}\boldsymbol e_1' & \boldsymbol e_1^{\mathrm T}\boldsymbol e_2' & \boldsymbol e_1^{\mathrm T}\boldsymbol e_3' \\ \boldsymbol e_2^{\mathrm T}\boldsymbol e_1' & \boldsymbol e_2^{\mathrm T}\boldsymbol e_2' & \boldsymbol e_2^{\mathrm T}\boldsymbol e_3' \\ \boldsymbol e_3^{\mathrm T}\boldsymbol e_1' & \boldsymbol e_3^{\mathrm T}\boldsymbol e_2' & \boldsymbol e_3^{\mathrm T}\boldsymbol e_3' \end{pmatrix} \boldsymbol a'\overset{\mathrm{def}}{=}\boldsymbol{Ra}' \end{aligned} a=⎝ ⎛a1a2a3⎠ ⎞=⎝ ⎛e1Te2Te3T⎠ ⎞(e1′,e2′,e3′)⎝ ⎛a1′a2′a3′⎠ ⎞=⎝ ⎛e1Te1′e2Te1′e3Te1′e1Te2′e2Te2′e3Te2′e1Te3′e2Te3′e3Te3′⎠ ⎞a′=defRa′
此处的
R
\boldsymbol R
R即为
a
′
\boldsymbol a'
a′坐标系到
a
\boldsymbol a
a坐标系的旋转矩阵
可以看出
R
R
T
=
I
\boldsymbol R\boldsymbol R^{\mathrm T}=\boldsymbol I
RRT=I且
d
e
t
(
R
)
=
1
\mathrm{det}(\boldsymbol R)=1
det(R)=1
1.2 空间坐标变换
三维空间的刚体运动是由旋转与平移组成的,可以表示为
b = R 1 a + t 1 \boldsymbol{b}=\boldsymbol R_1\boldsymbol a+\boldsymbol t_1 b=R1a+t1
其中
R
1
∈
R
3
×
3
\boldsymbol R_1\in \mathbb{R}^{3\times3}
R1∈R3×3是旋转矩阵,
t
1
∈
R
3
\boldsymbol t_1\in \mathbb{R}^{3}
t1∈R3为平移量
但是这种表示方法在多坐标系转换时会很复杂:
b = R 1 a + t 1 , c = R 2 b + t 2 ⇒ c = R 2 ( R 1 a + t 1 ) + t 2 \boldsymbol{b}=\boldsymbol R_1\boldsymbol a+\boldsymbol t_1,\quad\quad \boldsymbol{c}=\boldsymbol R_2\boldsymbol b+\boldsymbol t_2 \\ \Rightarrow \boldsymbol{c}=\boldsymbol R_2(\boldsymbol R_1\boldsymbol a+\boldsymbol t_1)+\boldsymbol t_2 b=R1a+t1,c=R2b+t2⇒c=R2(R1a+t1)+t2
因此为了避免麻烦,可引入齐次坐标和变换矩阵
b = R 1 a + t 1 ⇒ ( b 1 ) = ( R 1 t 1 0 T 1 ) ( a 1 ) = d e f T 1 ( a 1 ) ⇒ b ~ = T 1 a ~ \boldsymbol{b}=\boldsymbol R_1\boldsymbol a+\boldsymbol t_1 \\ \Rightarrow \begin{pmatrix} \boldsymbol{b} \\ 1 \end{pmatrix}= \begin{pmatrix} \boldsymbol{R_1} & \boldsymbol{t_1} \\ \boldsymbol{0}^{\mathrm T} & 1 \end{pmatrix} \begin{pmatrix} \boldsymbol{a} \\ 1 \end{pmatrix} \overset{\mathrm{def}}{=} \boldsymbol{T}_1\begin{pmatrix} \boldsymbol{a} \\ 1 \end{pmatrix} \\ \Rightarrow \tilde{\boldsymbol b}=\boldsymbol{T}_1\tilde{\boldsymbol a} b=R1a+t1⇒(b1)=(R10Tt11)(a1)=defT1(a1)⇒b~=T1a~
那么连续转换就可以表示成
c ~ = T 2 b ~ = T 2 T 1 a ~ \tilde{\boldsymbol c}=\boldsymbol{T}_2\tilde{\boldsymbol b} =\boldsymbol{T}_2\boldsymbol{T}_1\tilde{\boldsymbol a} c~=T2b~=T2T1a~
1.3 旋转向量 与 罗德里格斯公式
除了可以用旋转矩阵
R
\boldsymbol R
R来表示一个旋转以外
还可以用一个旋转轴和一个旋转角来表示一个旋转
旋转轴、角与旋转向量的关系可以由罗德里格斯公式(Rodrigues’s Formula)来表达:
R = cos θ I + ( 1 − cos θ ) n n T + sin θ n ∧ o r R = I + ( 1 − cos θ ) ( n ∧ ) 2 + sin θ n ∧ \boldsymbol R=\cos\theta\boldsymbol I+(1-\cos\theta)\boldsymbol n\boldsymbol n^{\mathrm T}+\sin\theta\boldsymbol n^{\land} \\ or \\ \boldsymbol R=\boldsymbol I+(1-\cos\theta)(\boldsymbol n^{\land})^2+\sin\theta\boldsymbol n^{\land} R=cosθI+(1−cosθ)nnT+sinθn∧orR=I+(1−cosθ)(n∧)2+sinθn∧
其中
θ
\theta
θ表示旋转角,
n
\boldsymbol n
n表示旋转轴单位向量,
n
∧
\boldsymbol n^{\land}
n∧表示向量
n
\boldsymbol n
n的反对称矩阵(skew-symmetric matrix)或叉积矩阵
也有很多其他地方将反对称矩阵记为
n
×
\boldsymbol n_\times
n×
- 补充知识点:叉积矩阵
a × b = ( i j k a 1 a 2 a 3 b 1 b 2 b 3 ) = ( a 2 b 3 − a 3 b 2 a 3 b 1 − a 1 b 3 a 1 b 2 − a 2 b 1 ) = ( 0 − a 3 a 2 a 3 0 − a 1 − a 2 a 1 0 ) b = d e f a ∧ ⋅ b \begin{aligned} \boldsymbol a\times\boldsymbol b&= \begin{pmatrix} \boldsymbol{i} & \boldsymbol{j} & \boldsymbol{k} \\ a_1 & a_2 & a_3 \\ b_1 & b_2 & b_3 \end{pmatrix}= \begin{pmatrix} a_2b_3-a_3b_2 \\ a_3b_1-a_1b_3 \\ a_1b_2-a_2b_1 \end{pmatrix} \\ &= \begin{pmatrix} 0 & -a_3 & a_2 \\ a_3 & 0 & -a_1 \\ -a_2 & a_1 & 0 \end{pmatrix}\boldsymbol b \\ &\overset{\mathrm{def}}{=} \boldsymbol a^{\wedge}\cdot\boldsymbol b \end{aligned} a×b=⎝ ⎛ia1b1ja2b2ka3b3⎠ ⎞=⎝ ⎛a2b3−a3b2a3b1−a1b3a1b2−a2b1⎠ ⎞=⎝ ⎛0a3−a2−a30a1a2−a10⎠ ⎞b=defa∧⋅b
这里 ( 0 − a 3 a 2 a 3 0 − a 1 − a 2 a 1 0 ) \displaystyle\begin{pmatrix} 0 & -a_3 & a_2 \\ a_3 & 0 & -a_1 \\ -a_2 & a_1 & 0 \end{pmatrix} ⎝ ⎛0a3−a2−a30a1a2−a10⎠ ⎞称为向量 a \boldsymbol a a 的叉积矩阵,或者反对称矩阵,记为 a ∧ \boldsymbol a^{\wedge} a∧ 或者 a × \boldsymbol a_\times a×
同时我们可以看出叉积矩阵的性质: ( a ∧ ) 2 = a a T − I , ( a ∧ ) 3 = − a ∧ (\boldsymbol a^{\land})^2=\boldsymbol a\boldsymbol a^T-\boldsymbol I,\quad(\boldsymbol a^{\land})^3=-\boldsymbol a^{\land} (a∧)2=aaT−I,(a∧)3=−a∧
由此可见,使用向量
ϕ
=
θ
n
\boldsymbol \phi=\theta\boldsymbol n
ϕ=θn同样可以描述一个三维旋转
R
\boldsymbol R
R
ϕ
\boldsymbol \phi
ϕ 与
R
\boldsymbol R
R 的具体关系可以学习李代数与李群
特殊地,
当
θ
\theta
θ 很小的时候,
sin
θ
∼
θ
,
1
−
cos
θ
∼
o
(
θ
)
\sin\theta\sim\theta,~~1-\cos\theta\sim o(\theta)
sinθ∼θ, 1−cosθ∼o(θ)
那么罗德里格斯公式可以表示为:
R
≈
I
+
θ
n
∧
=
(
1
−
ϕ
3
ϕ
2
ϕ
3
1
−
ϕ
1
−
ϕ
2
ϕ
1
1
)
\boldsymbol R\approx\boldsymbol I+\theta\boldsymbol n^{\land}= \begin{pmatrix} 1 & -\phi_3 & \phi_2 \\ \phi_3 & 1 & -\phi_1 \\ -\phi_2 & \phi_1 & 1 \end{pmatrix}
R≈I+θn∧=⎝
⎛1ϕ3−ϕ2−ϕ31ϕ1ϕ2−ϕ11⎠
⎞
二、相机模型
2.1 针孔相机模型
针孔相机的成像原理就是小孔成像
(图片制作中…)
为了计算方便,一般把成像平面翻转到物体同一侧
Z f = X X ′ = Y Y ′ \frac{Z}{f}=\frac{X}{X'}=\frac{Y}{Y'} fZ=X′X=Y′Y
我们将成像的像素坐标记为
(
x
,
y
)
T
(x,y)^T
(x,y)T
图片中心的像素坐标记为
(
c
x
,
c
y
)
T
(c_x,c_y)^T
(cx,cy)T
成像图片的像素与实际世界长度的比例记为横轴比例:
α
\alpha
α,纵轴比例:
β
\beta
β
那么有
{ x = α X ′ + c x y = β Y ′ + c y \left\{ \begin{array}{l} x=\alpha X'+c_x \\ y=\beta Y'+c_y \end{array} \right. {x=αX′+cxy=βY′+cy
整合之前关系式,记 f x = α f , f y = β f f_x=\alpha f,\quad f_y=\beta f fx=αf,fy=βf
{ x = f x X Z + c x y = f y Y Z + c y \left\{ \begin{array}{l} x=f_x\frac{X}{Z}+c_x \\ y=f_y\frac{Y}{Z}+c_y \end{array} \right. {x=fxZX+cxy=fyZY+cy
整理为齐次坐标
( x y 1 ) = 1 Z ( f x 0 c x 0 f y c y 0 0 1 ) ( X Y Z ) \begin{pmatrix} x \\ y \\ 1 \end{pmatrix} =\frac{1}{Z} \begin{pmatrix} f_x & 0 & c_x \\ 0 & f_y & c_y \\ 0 & 0 & 1 \end{pmatrix} \begin{pmatrix} X \\ Y \\ Z \end{pmatrix} ⎝ ⎛xy1⎠ ⎞=Z1⎝ ⎛fx000fy0cxcy1⎠ ⎞⎝ ⎛XYZ⎠ ⎞
矩阵 ( f x 0 c x 0 f y c y 0 0 1 ) \begin{pmatrix} f_x & 0 & c_x \\ 0 & f_y & c_y \\ 0 & 0 & 1 \end{pmatrix} ⎝ ⎛fx000fy0cxcy1⎠ ⎞叫做相机内参矩阵,暂记为 K \boldsymbol K K,即
Z p p i x e l = K p c a m e r a = K ( R p w o r l d + t ) = K T c w p w o r l d Z\boldsymbol p_{pixel}=\boldsymbol K\boldsymbol p_{camera}=\boldsymbol K(\boldsymbol R\boldsymbol p_{world}+\boldsymbol t)=\boldsymbol K\boldsymbol T_{cw}\boldsymbol p_{world} Zppixel=Kpcamera=K(Rpworld+t)=KTcwpworld
(第一步和最后一步都隐含了齐次转换,等号并不严谨,理解意思即可)
2.2 图像畸变
图像畸变一般分为径向畸变和切向畸变
2.2.1 径向畸变
我们使用
p
′
=
(
x
′
,
y
′
)
T
\boldsymbol p'=(x',y')^{\mathrm T}
p′=(x′,y′)T表示发生畸变以后图片上的坐标
用
p
=
(
x
,
y
)
T
\boldsymbol p=(x,y)^{\mathrm T}
p=(x,y)T表示真实应该在的图片上的位置坐标
则
{ x = x ′ ( 1 + k 1 r 2 + k 2 r 4 + k 3 r 6 + … ) y = y ′ ( 1 + k 1 r 2 + k 2 r 4 + k 3 r 6 + … ) \left\{ \begin{aligned} x&=x'(1+k_1r^2+k_2r^4+k_3r^6+\dots) \\ y&=y'(1+k_1r^2+k_2r^4+k_3r^6+\dots) \end{aligned} \right. {xy=x′(1+k1r2+k2r4+k3r6+…)=y′(1+k1r2+k2r4+k3r6+…)
其中
r
=
∥
p
′
∥
2
=
x
′
2
+
y
′
2
r=\|\boldsymbol p'\|_2=\sqrt{x'^2+y'^2}
r=∥p′∥2=x′2+y′2
k
k
k为参数,畸变越大的相机需要的参数越多。
2.2.2 切向畸变
沿用上面的符号
{
x
=
x
′
+
2
p
1
x
′
y
′
+
p
2
(
r
2
+
2
x
′
2
)
y
=
y
′
+
2
p
2
x
′
y
′
+
p
1
(
r
2
+
2
y
′
2
)
\left\{ \begin{aligned} x&=x'+2p_1x'y'+p_2(r^2+2x'^2) \\ y&=y'+2p_2x'y'+p_1(r^2+2y'^2) \end{aligned} \right.
{xy=x′+2p1x′y′+p2(r2+2x′2)=y′+2p2x′y′+p1(r2+2y′2)
p
1
,
p
2
p_1,p_2
p1,p2为参数
2.2.3 混合畸变
其实就是把两种畸变加起来即可
{
x
=
x
′
(
1
+
k
1
r
2
+
k
2
r
4
+
k
3
r
6
+
…
)
+
2
p
1
x
′
y
′
+
p
2
(
r
2
+
2
x
′
2
)
y
=
y
′
(
1
+
k
1
r
2
+
k
2
r
4
+
k
3
r
6
+
…
)
+
2
p
2
x
′
y
′
+
p
1
(
r
2
+
2
y
′
2
)
\left\{ \begin{aligned} x&=x'(1+k_1r^2+k_2r^4+k_3r^6+\dots)+2p_1x'y'+p_2(r^2+2x'^2) \\ y&=y'(1+k_1r^2+k_2r^4+k_3r^6+\dots)+2p_2x'y'+p_1(r^2+2y'^2) \end{aligned} \right.
{xy=x′(1+k1r2+k2r4+k3r6+…)+2p1x′y′+p2(r2+2x′2)=y′(1+k1r2+k2r4+k3r6+…)+2p2x′y′+p1(r2+2y′2)
三、SLAM模型
3.1 运动观测方程
x
k
\boldsymbol x_k
xk是指
k
k
k时刻的机器人位姿(VSLAM中一般是相机的位姿)
z
k
,
j
\boldsymbol z_{k,j}
zk,j是指
k
k
k时刻对第
j
j
j个路标点的观测值(VSLAM中一般是特征点在照片上的像素点坐标)
{
x
k
=
f
(
x
k
−
1
,
u
k
)
+
w
k
⋅
⋅
⋅
运动方程
z
k
,
j
=
h
(
y
j
,
x
k
)
+
v
k
,
j
⋅
⋅
⋅
观测方程
\left \{ \begin{aligned} \boldsymbol x_k&=f(\boldsymbol x_{k-1},\boldsymbol u_k)+\boldsymbol w_k ~~~~~~~~~&···运动方程\\ \boldsymbol z_{k,j}&=h(\boldsymbol y_j,\boldsymbol x_k)+\boldsymbol v_{k,j} &···观测方程 \end{aligned} \right.
{xkzk,j=f(xk−1,uk)+wk =h(yj,xk)+vk,j⋅⋅⋅运动方程⋅⋅⋅观测方程
其中,
u
k
\boldsymbol u_k
uk是指
k
k
k时刻的运动传感器的读数或者输入
w
k
\boldsymbol w_k
wk是指
k
k
k时刻的运动噪声
y
j
\boldsymbol y_j
yj表示第
j
j
j个路标点
v
k
,
j
\boldsymbol v_{k,j}
vk,j表示
k
k
k时刻第
j
j
j个路标点的观测噪声
f
(
⋅
)
f(·)
f(⋅)是运动函数
h
(
⋅
)
h(·)
h(⋅)是观测函数
3.2 投影模型
观测函数 h ( ⋅ ) h(·) h(⋅)是一个物体从世界到相机图片的投影过程,该过程分为以下几步:
我们先记某一物体在世界坐标系下的坐标为
P
w
\boldsymbol P_w
Pw,现在我们要将其投影到相机图片中的像素位置。
再记该物体在相机坐标系下的坐标和归一化坐标分别为
P
c
′
\boldsymbol P_c'
Pc′和
P
c
\boldsymbol P_c
Pc
根据三维空间旋转,我们知道
P c ′ = R w c P w + t = ( X c Y c Z c ) \boldsymbol P_c'=\boldsymbol R_{wc}\boldsymbol P_w+\boldsymbol t= \begin{pmatrix} X_c \\ Y_c \\ Z_c \end{pmatrix} Pc′=RwcPw+t=⎝ ⎛XcYcZc⎠ ⎞
对相机坐标归一化
P c = ( u c v c 1 ) = ( X c / Z c Y c / Z c 1 ) \boldsymbol P_c= \begin{pmatrix} u_c \\ v_c \\ 1 \end{pmatrix}= \begin{pmatrix} X_c/Z_c \\ Y_c/Z_c \\ 1 \end{pmatrix} Pc=⎝ ⎛ucvc1⎠ ⎞=⎝ ⎛Xc/ZcYc/Zc1⎠ ⎞
在对相机的畸变进行处理(这里以镜像畸变为例)
{ u c ′ = u c ( 1 + k 1 r c 2 + k 2 r c 4 ) v c ′ = v c ( 1 + k 1 r c 2 + k 2 r c 4 ) \left\{ \begin{aligned} u_c'=u_c(1+k_1r_c^2+k_2r_c^4) \\ v_c'=v_c(1+k_1r_c^2+k_2r_c^4) \end{aligned} \right. {uc′=uc(1+k1rc2+k2rc4)vc′=vc(1+k1rc2+k2rc4)
最后在根据相机内参算出函数
h
(
⋅
)
h(·)
h(⋅)最终结果(齐次变换最后一行的1我省去了):
(
u
v
)
=
K
(
u
c
′
v
c
′
)
=
(
f
x
u
c
′
+
c
x
f
y
v
c
′
+
c
y
)
\begin{pmatrix} u \\ v \end{pmatrix}= \boldsymbol K \begin{pmatrix} u_c' \\ v_c' \end{pmatrix}= \begin{pmatrix} f_xu_c'+c_x \\ f_yv_c'+c_y \end{pmatrix}
(uv)=K(uc′vc′)=(fxuc′+cxfyvc′+cy)
3.3 优化
我们所使用的设备和所在的环境都是存在噪声的,所以为导致仪器的测量数据不准确,需要使用算法进行优化。
一般的优化方法有两种:
- 滤波器
- 非线性优化
若
w
k
\boldsymbol w_k
wk与
v
k
,
j
\boldsymbol v_{k,j}
vk,j都是高斯白噪声,且观测方程
h
(
⋅
)
\boldsymbol h(·)
h(⋅)是线性的,那么可以直接使用滤波器来进行优化。
现在平面SLAM很多使用的还是滤波器的原理,例如Gmapping
而三维的视觉SLAM,一般则需要使用非线性优化。