目录
VSLAM学习(一) 三维运动、相机模型、SLAM模型
VSLAM学习(二) 非线性优化
VSLAM学习(三) 单目相机位姿估计
VSLAM学习(四) Bundle Adjustment
同一向量在不同坐标系下的坐标不同
假如有两组坐标系,他们的基分别为 ( 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
三维空间的刚体运动是由旋转与平移组成的,可以表示为
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~
除了可以用旋转矩阵 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×
由此可见,使用向量 ϕ = θ 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⎠ ⎞
针孔相机的成像原理就是小孔成像
(图片制作中…)
为了计算方便,一般把成像平面翻转到物体同一侧
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
(第一步和最后一步都隐含了齐次转换,等号并不严谨,理解意思即可)
图像畸变一般分为径向畸变和切向畸变
我们使用 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为参数,畸变越大的相机需要的参数越多。
沿用上面的符号
{ 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为参数
其实就是把两种畸变加起来即可
{ 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)
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(⋅)是观测函数
观测函数 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)
我们所使用的设备和所在的环境都是存在噪声的,所以为导致仪器的测量数据不准确,需要使用算法进行优化。
一般的优化方法有两种:
若 w k \boldsymbol w_k wk与 v k , j \boldsymbol v_{k,j} vk,j都是高斯白噪声,且观测方程 h ( ⋅ ) \boldsymbol h(·) h(⋅)是线性的,那么可以直接使用滤波器来进行优化。
现在平面SLAM很多使用的还是滤波器的原理,例如Gmapping
而三维的视觉SLAM,一般则需要使用非线性优化。