前面预积分对IMU的数据进行预处理,现在需要对视觉的信息进行处理,在VINS中视觉初始化的处理就是使用SFM,但是这里的三角化他没有用opencv给的函数,而是用自己的方法进行三角化。
这里SFM的方式就是现在滑窗里面找到枢纽帧,然后枢纽帧和最后一帧进行三角化获得3D点,然后通过PNP计算滑窗中其他关键帧的位姿,同时也三角化出更多新的点,顺序是先从枢纽帧向右再向左,然后再遍历只被中间帧看到的点进行三角化
三角化公式推导
公式如下
[
x
,
y
,
z
]
T
=
[
R
,
t
]
⋅
p
[x,y,z]^{T}=[R,t]·p
[x,y,z]T=[R,t]⋅p
其中
p
p
p 是世界点
p
=
[
x
,
y
,
z
,
1
]
p=[x,y,z,1]
p=[x,y,z,1] ,为了和变换矩阵齐次所以要有第4维为1,
[
x
,
y
,
z
]
[x,y,z]
[x,y,z] 是在各自相机系下的观测,[R,t] 是两帧间的位姿变换关系,这里面总会有一帧定义为单位阵的,这样才能作为这个3D点的世界系。由于各自相机系下的观测一般都是归一化相机坐标系,所以
z
=
1
z=1
z=1,所以公式变成
[
x
,
y
,
1
]
T
=
a
⋅
[
R
,
t
]
⋅
p
[x,y,1]^{T}=a·[R,t]·p
[x,y,1]T=a⋅[R,t]⋅p
这个a系数可以理解为尺度的倒数
1
s
\frac{1}{s}
s1 ,就是为了让公式成立的,就是右边变换完后还进行了归一化操作
[
R
t
]
属于
3
×
4
\begin{bmatrix} R &t\end{bmatrix}属于3×4
[Rt]属于3×4 矩阵
可以写成
[
R
t
]
=
[
p
0
p
1
p
2
]
3
×
4
M
a
t
r
i
x
\begin{bmatrix} R &t\end{bmatrix}=\begin{bmatrix} p_{0} \\ p_{1} \\p_{2}\end{bmatrix}_{3×4 Matrix}
[Rt]=
p0p1p2
3×4Matrix
p
0
,
p
1
,
p
2
属于
1
×
4
p_{0},p_{1},p_{2}属于1×4
p0,p1,p2属于1×4
与点
p
=
[
x
,
y
,
z
,
1
]
p=[x,y,z,1]
p=[x,y,z,1]相乘则有
[
x
y
1
]
T
=
a
[
p
0
⋅
p
p
1
⋅
p
p
2
⋅
p
]
3
×
1
M
a
t
r
i
x
\begin{bmatrix} x&y&1 \end{bmatrix}^{T}=a\begin{bmatrix} p_{0}·p\\p_{1}·p\\p_{2}·p\end{bmatrix}_{3×1Matrix}
[xy1]T=a
p0⋅pp1⋅pp2⋅p
3×1Matrix
两个向量满足
c
⃗
=
a
⋅
b
⃗
\vec{c}=a·\vec{b}
c=a⋅b 那么则证明这两个向量平行
两个平行向量的叉乘为0,因为
c
⃗
×
b
⃗
=
∣
c
⃗
∣
∣
b
⃗
∣
s
i
n
(
θ
)
\vec{c}×\vec{b}=|\vec{c}||\vec{b}|sin(θ)
c×b=∣c∣∣b∣sin(θ),都平行了这个θ肯定为0,所以整体为0,对上面两个向量进行叉乘则有
y
p
2
p
−
p
1
p
=
0
yp_{2}p-p_{1}p=0
yp2p−p1p=0
p
0
p
−
x
p
2
p
=
0
p_{0}p-xp_{2}p=0
p0p−xp2p=0
x
p
1
p
−
y
p
0
p
=
0
xp_{1}p-yp_{0}p=0
xp1p−yp0p=0
把
p
p
p 提出来得到
(
y
p
2
−
p
1
)
p
=
0
(yp_{2}-p_{1})p=0
(yp2−p1)p=0
(
p
0
−
x
p
2
)
p
=
0
(p_{0}-xp_{2})p=0
(p0−xp2)p=0
(
x
p
1
−
y
p
0
)
p
=
0
(xp_{1}-yp_{0})p=0
(xp1−yp0)p=0 ③
根据
[
x
y
1
]
T
=
a
[
p
0
⋅
p
p
1
⋅
p
p
2
⋅
p
]
3
×
1
M
a
t
r
i
x
\begin{bmatrix} x&y&1 \end{bmatrix}^{T}=a\begin{bmatrix} p_{0}·p\\p_{1}·p\\p_{2}·p\end{bmatrix}_{3×1Matrix}
[xy1]T=a
p0⋅pp1⋅pp2⋅p
3×1Matrix有
x
=
a
p
0
p
x=ap_{0}p
x=ap0p ,
y
=
a
p
1
p
y=ap_{1}p
y=ap1p,把这两个
x
,
y
x,y
x,y 代入到③中
则有
a
p
0
p
1
−
a
p
1
p
0
=
0
ap_{0}p_{1}-ap_{1}p_{0}=0
ap0p1−ap1p0=0,这里是向量点乘,这个式子必然成立,所以这个式子就没有意义了,公式就变成
(
y
p
2
−
p
1
)
p
=
0
(yp_{2}-p_{1})p=0
(yp2−p1)p=0
(
p
0
−
x
p
2
)
p
=
0
(p_{0}-xp_{2})p=0
(p0−xp2)p=0
一个位姿就会得到两个这个公式,三角化需要两帧,有两个位姿,所以代码中有4行这个公式
(
y
p
2
−
p
1
)
∈
1
×
4
(yp_{2}-p_{1})∈1×4
(yp2−p1)∈1×4
如果一个特征点可以被多帧看到的话,左边这个矩阵还能继续扩大,整个问题就是求解
A
x
=
0
Ax=0
Ax=0 的问题,用SVD求解去右奇异矩阵最后一个向量即可,具体原因见上一节。