如果我们已知多对匹配好的2D/3D特征点,我们可以用PnP方法去求得相机的运动。对于单目相机来说,我们可以通过利用对极约束或者单应性求得相机的运动,然后三角化获得3D点;对于双目可以通过视差恢复深度信息从而获得3D点;对于RGB-D相机来说深度信息可以直接测量,因此3D点可以根据内参直接算出。
直接变换法(DLT)
如果我们知道空间中的某个点在世界坐标系下(或者上一帧相机坐标系下)的齐次坐标为
P
=
[
x
,
y
,
z
,
1
]
T
\bm P=[x,y,z,1]^T
P=[x,y,z,1]T,其在当前帧相机坐标系下的归一化坐标为
x
x
x(其与像素坐标差了一个内参),当前帧相机坐标系相对世界坐标系(或者上一帧相机坐标系)的相对位姿为旋转矩阵
R
\bm R
R和平移向量
t
\bm t
t(这正是我们需要计算的量),那么根据相机模型有:
s
x
=
[
R
∣
t
]
P
⟹
s
[
u
v
1
]
=
[
r
1
T
r
2
T
r
3
T
]
P
s\bm x=[\bm R|\bm t] \bm P \implies s \begin{bmatrix} u\\v\\1 \end{bmatrix}=\begin{bmatrix} \bm {r_1^T}\\\bm{r_2^T}\\\bm{r_3^T} \end{bmatrix} \bm P
sx=[R∣t]P⟹s⎣⎡uv1⎦⎤=⎣⎡r1Tr2Tr3T⎦⎤P
其中
s
s
s是空间点在当前帧相机坐标系下的深度,
r
T
\bm r^T
rT表示矩阵
[
R
∣
t
]
[\bm R|\bm t]
[R∣t]的行向量。通过消去
s
s
s可得两个约束方程(这里用到了向量的点乘满足交换律的性质):
r
1
T
P
−
s
u
=
r
1
T
P
−
r
3
T
P
u
=
P
T
r
1
−
u
P
T
r
3
=
0
\bm{r_1^T}\bm P-su=\bm{r_1^T}\bm P-\bm{r_3^T} \bm Pu=\bm P^T\bm{r_1}- u\bm P^T\bm{r_3}=0
r1TP−su=r1TP−r3TPu=PTr1−uPTr3=0
r
2
T
P
−
s
v
=
r
2
T
P
−
r
3
T
P
v
=
P
T
r
2
−
v
P
T
r
3
=
0
\bm{r_2^T}\bm P-sv=\bm{r_2^T}\bm P-\bm{r_3^T} \bm Pv=\bm P^T\bm{r_2}- v\bm P^T\bm{r_3}=0
r2TP−sv=r2TP−r3TPv=PTr2−vPTr3=0
那么对于
n
n
n对匹配的点可得如下线性方程组:
(
P
1
T
0
−
u
1
P
1
T
0
P
1
T
−
v
1
P
1
T
⋮
⋮
⋮
P
n
T
0
−
u
n
P
n
T
0
P
n
T
−
v
n
P
n
T
)
(
r
1
r
2
r
3
)
=
0
\left(\begin{array}{ccc} \boldsymbol{P}_{1}^{\mathrm{T}} & 0 & -u_{1} \boldsymbol{P}_{1}^{\mathrm{T}} \\ 0 & \boldsymbol{P}_{1}^{\mathrm{T}} & -v_{1} \boldsymbol{P}_{1}^{\mathrm{T}} \\ \vdots & \vdots & \vdots \\ \boldsymbol{P}_{n}^{\mathrm{T}} & 0 & -u_{n} \boldsymbol{P}_{n}^{\mathrm{T}} \\ 0 & \boldsymbol{P}_{n}^{\mathrm{T}} & -v_{n} \boldsymbol{P}_{n}^{\mathrm{T}} \end{array}\right)\left(\begin{array}{l} \boldsymbol{r}_{1} \\ \boldsymbol{r}_{2} \\ \boldsymbol{r}_{3} \end{array}\right)=0
⎝⎜⎜⎜⎜⎜⎛P1T0⋮PnT00P1T⋮0PnT−u1P1T−v1P1T⋮−unPnT−vnPnT⎠⎟⎟⎟⎟⎟⎞⎝⎛r1r2r3⎠⎞=0
至少需要6对匹配的点通过SVD分解即可求得上述方程组的最小二乘解,但是由于没有考虑旋转矩阵的约束条件,求得的
R
\bm R
R不一定是正交群,可以通过QR分解或者取
(
R
R
T
)
−
1
2
R
(\bm R \bm {R^T})^{-\frac 1 2}\bm R
(RRT)−21R。
P3P
根据3对匹配点,利用三个三角形相似性,根据余弦定理可以构造两个二元二次方程,通过吴消元可以得到四个解析解,然后通过验证点来获取最适合的解。根据方程的解,可以获取3个点在相机坐标系下的3D坐标,此时可以把问题转换为3D/3D问题,利用ICP求出相机运动。由于P3P只能利用三对点的信息,如果存在误匹配,对结果影响很大。
EPnP
EPnP跟P3P相似,也是先求得特征点在相机坐标系下的3D坐标,然后利用ICP求解,不同是的EPnP是利用4个具有代表性的控制点来间接求得3D坐标的。由于空间中的任意一点可以由4个不共面的点进行加权平均,对于世界坐标系下的某个点
p
i
w
p_i^w
piw可表达为:
P
i
w
=
∑
j
=
1
4
α
i
c
j
w
,
∑
j
=
1
4
α
i
=
1
P_i^w=\sum_{j=1}^4 \alpha_i \bm c_j^w ,\sum_{j=1}^4 \alpha_i=1
Piw=j=1∑4αicjw,j=1∑4αi=1
对应的相机坐标系下的点可表示为:
P
i
c
=
∑
j
=
1
4
α
i
c
j
c
P_i^c=\sum_{j=1}^4 \alpha_i \bm c_j^c
Pic=j=1∑4αicjc
也就是说,对于某个空间点,其在世界坐标系下的坐标可由4个世界坐标系下的控制点进行加权平均,其在相机坐标系下的坐标也可由这4个控制点在相机坐标系下进行加权平均,并且两者权重是相同的。如果我们知道了权重和控制点在相机坐标系下的坐标,就可以求得特征点在相机坐标系下的3D坐标,然后使用ICP求解相机运动。
通常选择所有特征点的重心作为第一个控制点,即:
c
1
w
=
1
n
∑
i
=
1
n
P
i
w
c_1^w=\frac 1 n\sum_{i=1}^nP_i^w
c1w=n1∑i=1nPiw,然后通过每个世界坐标点与控制点作差得到到矩阵
A
A
A,其中
a
i
=
p
i
w
−
c
1
w
\bm a_i=p_i^w-c_1^w
ai=piw−c1w。设
A
T
A
A^TA
ATA的特征值和特征向量分别为
λ
c
,
j
\lambda_{c,j}
λc,j
和
和
和
v
c
,
j
\bm v_{c,j}
vc,j,那么剩下3个控制点可通过下式获得:
c
j
w
=
c
1
w
+
λ
c
,
j
−
1
1
2
v
c
,
j
−
1
,
j
=
2
,
3
,
4
c_j^w=c_1^w+\lambda_{c,j-1}^{\frac 1 2}\bm v_{c,j-1}, j=2,3,4
cjw=c1w+λc,j−121vc,j−1,j=2,3,4
有了控制点之后,对于每一个特征点我们都可以计算出对应的权重。其权重在相机坐标系下依然适用,我们可以利用多个点的权重和其在相机坐标系下的像素坐标(归一化坐标),计算出在相机坐标系下的控制点坐标:
s
x
i
c
=
P
i
c
=
∑
j
=
1
4
α
i
c
j
c
⟹
s
[
u
i
v
i
1
]
=
∑
j
=
1
4
α
i
[
x
j
c
y
j
c
z
j
c
]
sx_i^c=P_i^c=\sum_{j=1}^4 \alpha_i \bm c_j^c\implies s\begin{bmatrix}u_i\\v_i\\1\end{bmatrix}=\sum_{j=1}^4 \alpha_i\begin{bmatrix}x_j^c\\y_j^c\\z_j^c\end{bmatrix}
sxic=Pic=j=1∑4αicjc⟹s⎣⎡uivi1⎦⎤=j=1∑4αi⎣⎡xjcyjczjc⎦⎤
每个特征点可以提供两个方程,共有12个未知数,通过提供至少6个点可解得相机坐标系下的控制点。
非线性优化方法(最小化重投影误差)
假如我们知道了相机运动
R
R
R、
t
t
t,就可以把世界坐标系中的某个点
P
i
w
P_i^w
Piw投影到相机的成像平面上,但由于相机的运动估计的不是那么准确,可能与实际像素位置存在偏差,这个偏差称为重投影误差。
e
i
=
s
i
p
i
−
K
P
i
c
=
s
i
p
i
−
K
(
R
P
i
w
+
t
)
=
s
i
[
u
i
v
i
1
]
−
K
(
R
[
x
i
w
y
i
w
z
i
w
]
+
t
)
\bm e_i=s_i\bm p_i-KP_i^c=s_i\bm p_i-K(RP_i^w+t)=s_i\begin{bmatrix}u_i\\v_i\\1\end{bmatrix}-K(R\begin{bmatrix}x_i^w\\y_i^w\\z_i^w\end{bmatrix}+t)
ei=sipi−KPic=sipi−K(RPiw+t)=si⎣⎡uivi1⎦⎤−K(R⎣⎡xiwyiwziw⎦⎤+t)
我们可以通过优化方法不断迭代来使所有特征点的重投影误差达到最小,从而估计出最优的相机运动结果。优化目标如下:
T
∗
=
arg min
R
,
t
1
2
∑
i
=
1
n
∥
e
i
∥
2
2
T^*=\argmin_{R,t}\frac 1 2\sum_{i=1}^n\|\bm e_i\|_2^2
T∗=R,targmin21i=1∑n∥ei∥22
为了更新优化变量,我们需要求得误差项关于优化变量的一阶导数,即雅克比矩阵。根据链式法则有:
∂
e
i
∂
R
=
∂
e
i
∂
P
i
c
∂
P
i
c
∂
R
,
∂
e
i
∂
t
=
∂
e
i
∂
P
i
c
∂
P
i
c
∂
t
\frac {\partial e_i} {\partial R}=\frac {\partial e_i} {\partial P_i^c}\frac {\partial P_i^c} {\partial R} ,\frac {\partial e_i} {\partial t}=\frac {\partial e_i} {\partial P_i^c}\frac {\partial P_i^c} {\partial t}
∂R∂ei=∂Pic∂ei∂R∂Pic,∂t∂ei=∂Pic∂ei∂t∂Pic
∂
e
i
∂
P
i
c
=
−
[
∂
u
∂
x
i
c
∂
u
∂
y
i
c
∂
u
∂
z
i
c
∂
v
∂
x
i
c
∂
v
∂
y
i
c
∂
v
∂
z
i
c
]
=
−
[
f
x
z
i
c
0
−
f
x
x
i
c
z
i
c
2
0
f
y
z
i
c
−
f
y
y
i
c
z
i
c
2
]
\frac {\partial e_i} {\partial P_i^c}=-\begin{bmatrix} \frac {\partial u} {\partial x_i^c} & \frac {\partial u} {\partial y_i^c} & \frac {\partial u} {\partial z_i^c} \\ \frac {\partial v} {\partial x_i^c} & \frac {\partial v} {\partial y_i^c} & \frac {\partial v} {\partial z_i^c} \end{bmatrix}= -\begin{bmatrix} \frac {f_x} {z_i^c} & 0 & {-\frac {f_x x_i^c} {z_i^{c2}}} \\ 0 & \frac {f_y} {z_i^c} & -\frac {f_y y_i^c} {{z_i^{c2}}} \end{bmatrix}
∂Pic∂ei=−[∂xic∂u∂xic∂v∂yic∂u∂yic∂v∂zic∂u∂zic∂v]=−[zicfx00zicfy−zic2fxxic−zic2fyyic]
∂
P
i
c
∂
R
=
∂
(
R
P
i
w
+
t
)
∂
R
=
−
(
R
P
i
w
)
∧
=
−
(
P
i
c
)
∧
=
[
0
−
z
i
c
y
i
c
z
i
c
0
−
x
i
c
−
y
i
c
x
i
c
0
]
,
∂
P
i
c
∂
t
=
I
\frac {\partial P_i^c} {\partial R}=\frac {\partial(RP_i^w+t)} {\partial R}=-(RP_i^w)^\land=-(P_i^c)^\land=\begin{bmatrix}0 & -z_i^c & y_i^c\\z_i^c&0&-x_i^c\\-y_i^c&x_i^c&0 \end{bmatrix} , \frac {\partial P_i^c} {\partial t} = I
∂R∂Pic=∂R∂(RPiw+t)=−(RPiw)∧=−(Pic)∧=⎣⎡0zic−yic−zic0xicyic−xic0⎦⎤,∂t∂Pic=I
非线性优化的方法对于初始值比较敏感,我们可以先试用EPnP求解出相机的位姿,然后再使用优化的方式对位姿进行微调。