视觉SLAM十四讲第三讲笔记
这一讲主要是讲三维空间刚体运动:
主要是理解旋转矩阵,变换矩阵,欧拉角和四元数。
一、旋转矩阵
相机的位置是指相机在空间中的哪个地方,姿态是指相机的朝向。如何用数学语言表示呢?
1. 点和向量,坐标系
书中给出了内积和外积的公式:
内积:
a
⋅
b
=
a
T
b
=
∑
i
=
1
3
a
i
b
i
=
∣
a
∣
∣
b
∣
c
o
s
⟨
a
,
b
⟩
a \cdot b = a^Tb= \sum_{i=1}^3a_ib_i=|a||b|cos⟨a,b⟩
a⋅b=aTb=i=1∑3aibi=∣a∣∣b∣cos⟨a,b⟩
内积可以描述向量间的关系。
外积:
外积的方向垂直于这两个向量,大小为 ∣ a ∣ ∣ b ∣ s i n ⟨ a , b ⟩ |a||b|sin⟨a,b⟩ ∣a∣∣b∣sin⟨a,b⟩,是两个向量张成的四边形的有向面积对于外积,我们引入了 ∧ ∧ ∧符号,把 a a a写成一个矩阵。事实上是一个反对称矩阵(Skew-symmetric),你可以将 ∧ ∧ ∧记成一个反对称符号。这样就把外积 a × b a \times b a×b,写成了矩阵与向量的乘法 a ∧ b a∧b a∧b,把它变成了线性运算。我们还能用外积表示向量的旋转。
2.坐标系间的欧式变换
相机运动是一个刚体运动,它保证了同一个向量在各个坐标系下的长度和夹角都不会发生变化。这种变换称为欧氏变换。欧式变换由一个旋转和一个平移两部分组成。
(1) 旋转
首先来考虑旋转。 我们设某个单位正交基 ( e 1 , e 2 , e 3 ) (e_1,e_2,e_3) (e1,e2,e3)经过一次旋转变成了 ( e 1 ′ , e 2 ′ , e 3 ′ ) (e_1',e_2',e_3') (e1′,e2′,e3′)。那么对于同一个向量 a a a,它在两个坐标系下的坐标为 [ a 1 , a 2 , a 3 ] T [a_1, a_2, a_3]^T [a1,a2,a3]T和 [ a 1 ′ , a 2 ′ , a 3 ′ ] [a_1',a_2',a_3'] [a1′,a2′,a3′]。根据坐标的定义:
[
e
1
,
e
2
,
e
3
]
[
a
1
a
2
a
3
]
=
[
e
1
′
,
e
2
′
,
e
3
′
]
[
a
1
′
a
2
′
a
3
′
]
[e_1,e_2,e_3]\bigg[ \begin{array}{c} a_1\\a_2\\a_3 \end{array}\bigg] = [e_1',e_2',e_3']\bigg[ \begin{array}{c} a_1'\\a_2'\\a_3' \end{array}\bigg]
[e1,e2,e3][a1a2a3]=[e1′,e2′,e3′][a1′a2′a3′]
同时左乘
[
e
1
T
e
2
T
e
3
T
]
\bigg[ \begin{array}{c} e_1^T\\e_2^T\\e_3^T \end{array}\bigg]
[e1Te2Te3T],就得到了:
中间的矩阵,定义为矩阵
R
R
R,描述了旋转本身。因此它又称为旋转矩阵。旋转矩阵有一些特别的性质。事实上,它是一个行列式为1的正交矩阵。反之,行列式为1的正交矩阵也是一个旋转矩阵。 所以,我们可以把旋转矩阵的集合定义如下:
S
O
(
n
)
=
{
R
∈
R
n
×
n
∣
R
R
T
=
I
,
d
e
t
(
R
)
=
1
}
SO(n)=\{R \in \R^{n \times n} | RR^T = I, det(R)=1 \}
SO(n)={R∈Rn×n∣RRT=I,det(R)=1}
S O ( n ) SO(n) SO(n)是特殊的正交群(special orthogonal group)。 这个集合由 n n n维空间的旋转矩阵组成,特别的,SO(3)就是三维空间的旋转了。 旋转矩阵可以描述相机的旋转 。
由于旋转矩阵为正交阵,它的逆(即转置)描述了一个相反的旋转。
a
′
=
R
−
1
a
=
R
T
a
a'=R^{-1}a = R^Ta
a′=R−1a=RTa
(2)平移
再来考虑平移。
a
′
=
R
a
+
t
a' = Ra + t
a′=Ra+t
这里的 向量
t
t
t就是平移向量。相比于旋转,平移部分只需把这个平移量加到旋转之后的坐标上。
二、变换矩阵
上面的式子完整的表达了欧式空间的旋转和平移,但是这里的变换关系不是线性关系。因此我们引入了齐次坐标和变换矩阵。
[
a
′
1
]
=
[
R
t
0
T
1
]
[
a
1
]
≜
T
[
a
1
]
\bigg[ \begin{array}{c} a'\\1 \end{array}\bigg] = \bigg[\begin{array}{c} R \quad t\\0^T \quad 1 \end{array}\bigg] \bigg[ \begin{array}{c} a\\1 \end{array}\bigg] \triangleq T\bigg[ \begin{array}{c} a\\1 \end{array}\bigg]
[a′1]=[Rt0T1][a1]≜T[a1]
我们把一个三维向量的末尾添加1,变成了四维向量,称为齐次坐标。 对于这个四维向量,我们可以把旋转和平移写在一个矩阵里面,使得整个关系变成了线性关系。该式中,矩阵
T
T
T称为变换矩阵(Transform Matrix)。我们暂时用
a
~
\tilde{a}
a~表示
a
a
a的齐次坐标。转换成齐次坐标:
x
~
=
[
x
,
y
,
z
,
w
]
T
=
[
x
/
w
,
y
/
w
,
z
/
w
,
1
]
T
\tilde{x} = [x,y,z,w]^T = [x/w,y/w,z/w,1]^T
x~=[x,y,z,w]T=[x/w,y/w,z/w,1]T
变换矩阵T,又称为特殊欧式群(special euclidean group)。
S E ( 3 ) = { T = [ R t 0 T 1 ] ∈ R 4 × 4 ∣ R ∈ S O ( 3 ) , t ∈ R 3 } SE(3) = \left\{ \begin{array}{c} T = \bigg[\begin{array}{c} R \quad t\\0^T \quad 1 \end{array}\bigg] \in \R^{4 \times 4} | R \in SO(3), t \in \R^3 \end{array} \right\} SE(3)={T=[Rt0T1]∈R4×4∣R∈SO(3),t∈R3}
T
T
T矩阵的逆表示一个反向变换:
T
−
1
=
[
R
T
−
R
T
t
0
T
1
]
T^{-1}=\bigg[\begin{array}{c} R^T \quad -R^Tt\\0^T \quad 1 \end{array}\bigg]
T−1=[RT−RTt0T1]
如果将平移和旋转放在一个矩阵中,就形成了变换矩阵SE(3)。
三、欧拉角
变换矩阵描述一个六自由度的三维刚体运动,但矩阵表示方式至少有以下几个缺点:
- SO (3) 的旋转矩阵有九个量, 但一次旋转只有三个自由度。 因此这种表达方式是冗余的。同理, 变换矩阵用十六个量表达了六自由度的变换。
- 旋转矩阵自身带有约束:它必须是个正交矩阵,且行列式为1。变换矩阵也是如此。当我们想要估计或优化一个旋转矩阵/变换矩阵时,这些约束会使得求解变得更困难。
任意旋转都可以用一个旋转轴和一个旋转角来刻画。于是,我们可以使用一个向量,其方向与旋转轴一致,而长度等于旋转角。这种向量,称为旋转向量(或轴角,Axis-Angle)。这种表示法只需一个三维向量即可描述旋转。
旋转向量和旋转矩阵的转换关系:
旋转向量到旋转矩阵,罗德里格斯公式(Rodrigues’s Formula)
R = c o s θ I + ( 1 − c o s θ ) n n T + s i n θ n ∧ R = cos\theta I + (1-cos \theta) nn^T + sin \theta n^{\land} R=cosθI+(1−cosθ)nnT+sinθn∧
符号 ∧ \land ∧ 是向量到反对称的转换符。
旋转矩阵到旋转向量的转化:
t
r
(
R
)
=
c
o
s
θ
t
r
(
I
)
+
(
1
−
c
o
s
θ
)
t
r
(
n
n
T
)
+
s
i
n
θ
t
r
(
n
∧
)
=
3
c
o
s
θ
+
(
1
−
c
o
s
θ
)
=
1
+
2
c
o
s
θ
\begin{aligned} tr(R) &= cos\theta tr(I) + (1-cos\theta)tr(nn^T) + sin \theta tr(n^{\land})\\ &=3 cos \theta + (1-cos\theta) \\ &=1+2cos\theta \end{aligned}
tr(R)=cosθtr(I)+(1−cosθ)tr(nnT)+sinθtr(n∧)=3cosθ+(1−cosθ)=1+2cosθ
所以
θ = a r c c o s ( t r ( R ) − 1 2 ) \theta = arccos(\frac{tr(R) - 1}{2}) θ=arccos(2tr(R)−1)
而欧拉角则提供了一种非常直观的方式来描述旋转——它使用了三个分离的转角,把一个旋转分解成三次绕不同轴的旋转。
- 绕物体的Z轴旋转,偏航角yaw
- 绕物体的Y轴旋转,俯仰角pitch
- 绕物体的X轴旋转,翻滚角roll
此时,我们可以使用 [ r , p , y ] T [r,p,y]^T [r,p,y]T这样一个三维的向量描述任意旋转。欧拉角的一个重大缺点是会碰到著名的万向锁问题(Gimbal Lock):在俯仰角为 ± 9 0 ∘ ±90^{\circ} ±90∘时,第一次旋转与第三次旋转将使用同一个轴,使得系统丢失了一个自由度(由三次 旋转变成了两次旋转)。这被称为奇异性问题,在其他形式的欧拉角中也同样存在。 在SLAM中不直接使用欧拉角表达姿态,但若你想验证自己算法是否有错时,转换成欧拉角能够快速辨认结果的正确与否。
四、四元数
旋转矩阵用九个量描述三自由度的旋转,具有冗余性。欧拉角和旋转向量是紧凑的,但具有奇异性。在表达三维空间旋转时,有一种类似于复数的代数:四元数(Quaternion)。它既是紧凑的,也没有奇异性。 一个四元数
q
q
q拥有一个实部和三个虚部。
q
=
q
0
+
q
1
i
+
q
2
j
+
q
3
k
q = q_0 + q_1i+q_2j+q_3k
q=q0+q1i+q2j+q3k
其中
i
,
j
,
k
i,j,k
i,j,k是四元数的三个虚部。满足下列关系式:
{
i
2
=
j
2
=
k
2
=
−
1
i
j
=
k
,
j
i
=
−
k
j
k
=
i
,
k
j
=
−
i
k
i
=
j
,
i
k
=
−
j
\left\{ \begin{aligned} &i^2=j^2=k^2=-1 \\ &ij=k, ji=-k \\ &jk=i, kj=-i \\ &ki=j, ik= -j \end{aligned} \right.
⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧i2=j2=k2=−1ij=k,ji=−kjk=i,kj=−iki=j,ik=−j
有时人们也用一个标量和一个向量来表达四元数:
q
=
[
s
,
v
]
,
s
=
q
0
∈
R
,
v
=
[
q
1
,
q
2
,
q
3
]
T
∈
R
3
q = [s,v] , \quad s=q_0 \in \R, v=[q_1,q_2,q_3]^T \in \R^3
q=[s,v],s=q0∈R,v=[q1,q2,q3]T∈R3
这里,
s
s
s称为四元数的实部,而
v
v
v称为它的虚部。如果一个四元数虚部为0,称之为实四元数。反之, 若它的实部为0,称之为 虚四元数。
在复数中,乘以
i
i
i应该对应着旋转180度,这样才能保证
i
j
=
k
ij = k
ij=k的性质。而
i
2
=
−
1
i^2 = −1
i2=−1,意味着绕
i
i
i轴旋转360度后,你得到了一个相反的东西。这个东西要旋转两周才会和它原先的样子相等。
旋转向量和四元数的关系:
q
=
[
c
o
s
θ
2
,
n
x
s
i
n
θ
2
,
n
y
s
i
n
θ
2
,
n
z
s
i
n
θ
2
]
T
q = \bigg[ cos\frac{\theta}{2}, n_xsin\frac{\theta}{2}, n_ysin\frac{\theta}{2}, n_zsin\frac{\theta}{2} \bigg]^T
q=[cos2θ,nxsin2θ,nysin2θ,nzsin2θ]T
四元数转换为旋转向量和夹角:
{
θ
=
2
a
r
c
c
o
s
q
0
[
n
x
,
n
y
,
n
z
]
T
=
[
q
1
,
q
2
,
q
3
]
T
/
s
i
n
θ
2
\left\{ \begin{aligned} &\theta=2arccosq_0 \\ &[n_x, n_y, n_z]^T = [q_1,q_2,q_3]^T/sin \frac{\theta}{2} \\ \end{aligned} \right.
⎩⎨⎧θ=2arccosq0[nx,ny,nz]T=[q1,q2,q3]T/sin2θ
四元数转换为旋转矩阵:
反之,四元数转换为旋转向量和夹角:
q
0
=
t
r
(
R
)
+
1
2
,
q
1
=
m
23
−
m
32
4
q
0
,
q
2
=
m
31
−
m
13
4
q
0
,
q
3
=
m
12
−
m
21
4
q
0
q_0 = \frac{\sqrt{tr(R)+1}}{2}, \quad q_1 = \frac{m_{23}-m_{32}}{4q_0}, \quad q_2 = \frac{m_{31}-m_{13}}{4q_0}, \quad q_3 = \frac{m_{12}-m_{21}}{4q_0}
q0=2tr(R)+1,q1=4q0m23−m32,q2=4q0m31−m13,q3=4q0m12−m21
在四元数中,任意的旋转都可以由两个互为相反数的四元数表示。
下面是四元数的计算:
假设有两个四元数
q
a
,
q
b
q_a, q_b
qa,qb 表示为
[
s
a
,
v
a
]
,
[
s
b
,
v
b
]
[s_a,v_a], [s_b,v_b]
[sa,va],[sb,vb]
q
a
=
s
a
+
x
a
i
+
y
a
j
+
z
a
k
,
q
b
=
s
b
+
x
b
i
+
y
b
j
+
z
b
k
q_a=s_a+x_ai+y_aj+z_ak, \quad q_b=s_b+x_bi+y_bj+z_bk
qa=sa+xai+yaj+zak,qb=sb+xbi+ybj+zbk
1. 加法
q a ± q b = [ s a ± s b , v a ± v b ] q_a \plusmn q_b = [s_a \plusmn s_b, v_a \plusmn v_b] qa±qb=[sa±sb,va±vb]
2. 乘法
q a q b = s a s b − x a x b − y a y b − z a z b + ( s a x b + x a s b + y a z b − z a y b ) i + ( s a y b − x a z b + y a s b + z a x b ) j + ( s a z b + x a y b − y b x a + z a s b ) k \begin{aligned} q_a q_b = &s_a s_b - x_a x_b - y_a y_b - z_a z_b \\ &+(s_ax_b+x_as_b+y_az_b-z_ay_b)i \\ &+(s_ay_b-x_az_b+y_as_b+z_ax_b)j \\ &+(s_az_b+x_ay_b-y_bx_a+z_as_b)k \end{aligned} qaqb=sasb−xaxb−yayb−zazb+(saxb+xasb+yazb−zayb)i+(sayb−xazb+yasb+zaxb)j+(sazb+xayb−ybxa+zasb)k
如果写成向量形式并利用内外积运算:
q
a
q
b
=
[
s
a
s
b
−
v
a
T
v
b
,
s
a
v
b
+
s
b
v
a
+
v
a
×
v
b
]
q_aq_b=[s_as_b-v_a^Tv_b,s_av_b+s_bv_a+v_a \times v_b]
qaqb=[sasb−vaTvb,savb+sbva+va×vb]
3.共轭
四元数的共轭是把虚部取成相反数:
q
a
∗
=
s
a
−
x
a
i
−
y
a
j
−
z
a
k
=
[
s
a
,
−
v
a
]
q_a^*=s_a - x_ai-y_aj-z_ak = [s_a, -v_a]
qa∗=sa−xai−yaj−zak=[sa,−va]
四元数共轭与自己本身相乘,会得到一个实四元数,其实部为模长的平方:
q
∗
q
=
q
q
∗
=
[
s
a
2
+
v
T
v
,
0
]
q^*q = qq^* = [s_a^2 + v^Tv, 0]
q∗q=qq∗=[sa2+vTv,0]
4.模长
四元数的模长定义为:
∣
∣
q
a
∣
∣
=
s
a
2
+
x
a
2
+
y
a
2
+
z
a
2
||q_a|| = \sqrt{s_a^2+x_a^2+y_a^2+z_a^2}
∣∣qa∣∣=sa2+xa2+ya2+za2
可以验证,两个四元数乘积的模即为模的乘积。这保证单位四元数相乘后仍是单位四元数。
∣
∣
q
a
q
b
∣
∣
=
∣
∣
q
a
∣
∣
∣
∣
q
b
∣
∣
||q_aq_b|| = ||q_a||||q_b||
∣∣qaqb∣∣=∣∣qa∣∣∣∣qb∣∣
5.逆
一个四元数的逆为:
q
−
1
=
q
∗
/
∣
∣
q
∣
∣
2
q^{-1} = q^*/||q||^2
q−1=q∗/∣∣q∣∣2
四元数和自己的逆的乘积为实四元数的1
q
q
−
1
=
q
−
1
q
=
1
qq^{-1} = q^{-1}q = 1
qq−1=q−1q=1
如果
q
q
q为单位四元数,逆和共轭就是同一个量。
( q a q b ) − 1 = q b − 1 q a − 1 (q_aq_b)^{-1}=q_b^{-1}q_a^{-1} (qaqb)−1=qb−1qa−1
6.数乘和点乘
数乘:
k
q
=
[
k
s
,
k
v
]
kq = [ks, kv]
kq=[ks,kv]
点乘:
q
a
⋅
q
b
=
s
a
s
b
+
x
a
x
b
i
+
y
a
y
b
j
+
z
a
z
b
k
q_a \cdot q_b = s_a s_b + x_a x_b i + y_ay_bj+z_az_bk
qa⋅qb=sasb+xaxbi+yaybj+zazbk
7.用四元数表示旋转
把三维空间点用一个虚四元数来描述:
p
=
[
0
,
x
,
y
,
z
]
=
[
0
,
v
]
p=[0,x,y,z] = [0, v]
p=[0,x,y,z]=[0,v]
用四元数q表示这个旋转:
q
=
[
c
o
s
θ
2
,
n
s
i
n
θ
2
]
q=[cos\frac{\theta}{2}, nsin\frac{\theta}{2}]
q=[cos2θ,nsin2θ]
那么旋转之后的点
p
′
p'
p′可以表示为:
p
′
=
q
p
q
−
1
p'=qpq^{-1}
p′=qpq−1
五、相似、仿射、射影变换
-
相似变换
T s = [ s R t 0 T 1 ] T_s = \bigg[ \begin{aligned} &sR \quad t \\ &0^T \quad 1 \end{aligned} \bigg] Ts=[sRt0T1]
其中 s s s是缩放因子。 -
仿射变换
T A = [ A t 0 T 1 ] T_A = \bigg[ \begin{aligned} &A \quad t \\ &0^T \quad 1 \end{aligned} \bigg] TA=[At0T1]
仿射变换只要求A是一个可逆矩阵,而不必是正交矩阵。仿射变换也叫正交投影。经过仿射变换之后,立方体就不再是方的了,但是各个面仍然是平行四边形。 -
射影变换
T P = [ A t a T v ] T_P = \bigg[ \begin{aligned} &A \quad t \\ &a^T \quad v \end{aligned} \bigg] TP=[AtaTv]
它左上角为可逆矩阵A,右上为平移t,左下缩放 a T a^T aT。
最后各种变换总结如下: