单应矩阵的两种形式(两帧运动模型与棋盘格模型)
一、引言
最近做视觉的充电桩自动对接项目,先搭建基于棋盘格的demo出来。由于棋盘格的角点都是平面的,理所当然的应当用单应矩阵去计算位姿。由于单应矩阵这块不是很熟,所以拿出了高翔的视觉十四讲准备对着这个编写。高翔大佬的书上对这块介绍不多,计算完单应矩阵后就没有详细讲如何分解并选择为R和t,所以打算上网搜搜(偷懒.jpg)。百度相关的介绍不多,并且都是与分解R和t不相关的。只好去谷歌搜一下。
但是,在opencv
的例程中,我看到了一些不一样的解释和方法,这种方法针对棋盘格标定,泛用性不是那么强,但是很有意思,在关于棋盘格定位的特定任务下简单快捷,因此想和大家分享一下。
二、两帧运动模型的单应矩阵
这个模型推导详见高翔的书上,这里就不在献丑了。从原理上来说,这种方法和求解基础矩阵毫无二致,这里基础矩阵被定义为:
p
t
1
=
H
t
1
t
2
p
t
2
w
h
e
r
e
:
H
t
1
t
2
=
K
(
c
R
t
1
t
2
−
t
n
T
d
)
K
−
1
p_{t1} = H^{t2}_{t1}\ p_{t2}\\ where :\ \ H^{t2}_{t1} = K(^cR^{t2}_{t1}-\frac{tn^T}{d})K^{-1}
pt1=Ht1t2 pt2where: Ht1t2=K(cRt1t2−dtnT)K−1
这里的
p
t
p_t
pt表示t时刻目标角点在像素平面的投影;
c
R
1
2
^cR^2_1
cR12表示相机坐标
c
c
c下从
t
1
t1
t1时刻到
t
2
t2
t2时刻的旋转矩阵;
n
T
n^T
nT表示平面法向量,理论上相机与平面平行时
n
T
=
1
n^T=1
nT=1;
d
d
d为平面截距。分解方法可以参考ORB程序(虽然很长),也可以参考十四讲中提到的引用文献。
三、棋盘格模型
这个模型的主要想法是把单应矩阵作为一种仿射变换,直接从像素平面变换到世界坐标系下。假设世界坐标系为棋盘格坐标系,其Z全部为零,因此
P
=
[
X
Y
Z
=
0
1
]
P=\begin{bmatrix} X \\Y \\Z=0 \\1\end{bmatrix}
P=⎣⎢⎢⎡XYZ=01⎦⎥⎥⎤退化为
P
~
=
[
X
Y
1
]
\widetilde{P}=\begin{bmatrix} X \\Y \\ 1\end{bmatrix}
P
=⎣⎡XY1⎦⎤,并且在矩阵乘法中将R的第三列消去。具体表达如下:
p
t
=
w
c
H
t
P
~
w
h
e
r
e
:
w
c
H
t
=
K
[
r
11
r
12
t
x
r
12
r
22
t
y
r
31
r
32
t
z
]
p_t =\ ^c_wH_t \ \widetilde{P}\\ where:\ \ ^c_wH_t = K \begin{bmatrix} r_{11} & r_{12} & t_x\\ r_{12} & r_{22} & t_y \\ r_{31} & r_{32} & t_z \end{bmatrix}
pt= wcHt P
where: wcHt=K⎣⎡r11r12r31r12r22r32txtytz⎦⎤
之后,分解H矩阵,求解到R和t:
H
=
K
[
r
1
r
2
t
]
R
=
[
r
1
r
2
r
1
×
r
2
]
H = K\begin{bmatrix} r_1 & r_2 & t\end{bmatrix}\\ R = [r_1 \quad r_2 \quad r_1 \times r_2]
H=K[r1r2t]R=[r1r2r1×r2]
值得一提的是,opencv
的H矩阵也是类似方法计算的。这样做的好处是能够仅利用单帧信息求解R和t。然而,这样得到的R矩阵不满足旋转矩阵必须是单位正交阵的要求,因此需要对其进行修正。有三种思路:
- 建立带有惩罚项的优化方程,在优化环节处理
- 施密特正交化
- 先进行归一化,再进行SVD分解正交处理
个人理解2、3应该是差不多的,但是本人数学菜逼,不确定对不对。opencv
例程给的是SVD分解方法。代码如下:https://docs.opencv.org/3.4/d9/dab/tutorial_homography.html
注意这里例程中使用了undistortPoints 这个函数,并且没有添加参数P,因此效果是将
p
→
K
−
1
p
′
p \to K^{-1}p^{'}
p→K−1p′ 而非矫正后的
p
′
p^{'}
p′。因此最后求解H时候没有左乘K.inv()
。
四、总结
两种方法对比,在已知世界坐标系下平面位置的时候,明显是第二种更加方便。并且,opencv
为第二种方法提供了接口和简单的教程。但是在slam中,由于缺少标定板这种已知的先验条件,第一种方法更加普遍。东北大学吴博曾经在泡泡机器人公开课上对第一种方法求解单应矩阵做过详细的分析,如果有需要可以参考他的讲解学习。