前言
我们在[1]中曾经谈到了如何在对极线上去寻找对应点,这样会使得算法更鲁棒,而且速度更快。在本文中,我们将会继续介绍一种称之为图像矫正的方法,通过这种方法,我们可以在对极线的基础上,使得寻找对应点变得更为容易。如有谬误,请联系指正。转载请联系作者并注明出处和链接。
∇ \nabla ∇ 联系方式:
e-mail: FesianXu@gmail.com
QQ: 973926198
github: https://github.com/FesianXu
知乎专栏: 计算机视觉/计算机图形理论与应用
微信公众号:
为什么我们需要图像矫正
我们在[1]曾经聊到了在对极线上寻找对应点的方法,如Fig 1.1所示。这种方法将对应点可能的范围约束到了一条直线上,而不是一个二维平面,这样大大减小了搜索空间。同时,我们也在[1]中聊过,每个对极面都是会经过基线的,每个对极线也是会经过对应的对极点的,正是因为如此,其实对于单张图的对极线组来说,如果延伸每条对极线,我们会发现每条对极线都会汇聚于对极点上,如Fig 1.2所示。也正是因为如此,我们得到的对极线们都不是平行的,如Fig 1.3所示。
我们在后续的处理中,将会发现不平行的对极线会使得寻找对极点的运算变得复杂,我们期望的是, 如果每对对极线都是平行的,那将会大大减少后续算法的复杂度,特别是在求视差时,平行的对极线将会提供极大的便利。 理想的对极线对的效果如Fig 1.4所示。我们后续就讨论如何才能从不平行的对极线转换成平行的,也就是 图像矫正(image rectification) 的具体操作。
图像矫正
需要明确的是,进行图像矫正之前需要知道相机的内参数和外参数[4]。
我们首先要知道,为什么我们的对极线对会不平行呢?如图Fig 2.1所示,其不平行的原因是因为我们的成像平面没有共面(coplanar),那么自然地,我们的直接做法就是矫正我们的成像平面,使得其共面,效果如图Fig 2.2的黄色面所示。其总体效果,如Fig 2.3所示,我们可以发现,通过这种手段,我们的对应点的搜索空间进一步缩小到了水平线上,只用一个水平线上的参数 x x x表示其距离就可以描述对应点了,这样其实是大大减少了运算量的。
我们后续具体分析这个矫正过程,我们要想怎么样才能将成像平面矫正到共面呢?我们观察图Fig 2.4,我们延伸射线 P O PO PO和 P O ′ PO^{\prime} PO′分别得到 P P ˉ , P P ˉ ′ P\bar{P}, P\bar{P}^{\prime} PPˉ,PPˉ′,使得 O O ′ / / P ˉ P ˉ ′ OO^{\prime} // \bar{P}\bar{P}^{\prime} OO′//PˉPˉ′,同时,我们确保 O , O ′ O, O^{\prime} O,O′到平面 ∏ ˉ , ∏ ˉ ′ \bar{\prod}, \bar{\prod}^{\prime} ∏ˉ,∏ˉ′的距离相同,那么我们的平面 ∏ ˉ , ∏ ˉ ′ \bar{\prod}, \bar{\prod}^{\prime} ∏ˉ,∏ˉ′就是期望得到的矫正成像平面了。其实这个也不难理解,因为每个对极面都是经过基线的,而基线平行于 ∏ ˉ , ∏ ˉ ′ \bar{\prod}, \bar{\prod}^{\prime} ∏ˉ,∏ˉ′,那么 e p , e ′ p ′ ep,e^{\prime}p^{\prime} ep,e′p′在基线上的投影必然是平行于 P ˉ P ˉ ′ \bar{P}\bar{P}^{\prime} PˉPˉ′的,同时,我们保证了两个焦点到两个平面的距离相同,确保了其是 ∏ ˉ , ∏ ˉ ′ \bar{\prod}, \bar{\prod}^{\prime} ∏ˉ,∏ˉ′的投影。
我们为什么要加上这个焦点到两个矫正后的成像平面的距离相同这个约束呢?让我们看一个例子。
在如图Fig 2.5的系统中,我们假设两个成像平面是共面的,其焦点之间的距离 O O ′ = d OO^{\prime} = d OO′=d,两个摄像头之间不存在有旋转关系,那么我们可以知道其相机参数为:
R = I T = [ − d , 0 , 0 ] T E = [ T × ] R = [ 0 0 0 0 0 d 0 − d 0 ] (2.1) \begin{aligned} \mathbf{R} &= \mathbf{I} \\ \mathbf{T} &= [-d, 0, 0]^{\mathrm{T}} \\ \mathbf{E} &= [\mathbf{T}_{\times}]\mathbf{R} = \left[ \begin{matrix} 0 & 0 & 0 \\ 0 & 0 & d \\ 0 & -d & 0 \end{matrix} \right] \end{aligned} \tag{2.1} RTE=I=[−d,0,0]T=[T×]R=⎣⎡00000−d0d0⎦⎤(2.1)
从[1]中提到的对极约束的代数表达形式,我们有:
p ′ E p = 0 ⇒ [ x ′ , y ′ , f ] [ 0 0 0 0 0 d 0 − d 0 ] [ x y f ] = 0 ⇒ y = y ′ (2.2) \begin{aligned} \mathbf{p}^{\prime}\mathbf{E}\mathbf{p} &= 0 \\ &\Rightarrow [x^{\prime}, y^{\prime}, f] \left[ \begin{matrix} 0 & 0 & 0 \\ 0 & 0 & d \\ 0 & -d & 0 \end{matrix} \right] \left[ \begin{matrix} x \\ y \\ f \end{matrix} \right] = 0 \\ & \Rightarrow y = y^{\prime} \end{aligned} \tag{2.2} p′Ep=0⇒[x′,y′,f]⎣⎡00000−d0d0⎦⎤⎣⎡xyf⎦⎤=0⇒y=y′(2.2)
从中我们发现,我们必须引入这个约束去约束成像平面的位置。
我们知道极点
e
e
e是本征矩阵的零空间向量,也就是说我们有
E
e
=
0
\mathbf{E}e = 0
Ee=0,我们可以解出:
[
0
0
0
0
0
d
0
−
d
0
]
[
1
0
0
]
=
0
\left[ \begin{matrix} 0 & 0 & 0 \\ 0 & 0 & d \\ 0 & -d & 0 \end{matrix} \right] \left[ \begin{matrix} 1 \\ 0 \\ 0 \end{matrix} \right] = 0
⎣⎡00000−d0d0⎦⎤⎣⎡100⎦⎤=0
我们如果从齐次坐标的角度去看待
e
=
[
1
0
0
]
e = \left[ \begin{matrix} 1 \\ 0 \\ 0 \end{matrix} \right]
e=⎣⎡100⎦⎤ 那么我们知道其实这个时候极点是在无限远处了。(关于齐次坐标系,见[2,3])
于是,其实矫正成像平面的后果就是,我们的极点被挪到了无限远处,这个和我们图Fig 1.2的推论相同。
我们到现在算是对图像矫正有了直观上的印象,接下来我们尝试用算法去描述这个过程。图像矫正算法主要分四步。
-
用旋转矩阵 R r e c \mathbf{R}_{\mathrm{rec}} Rrec旋转左相机,使得左成像平面的极点到无限远处。
-
用和第一步相同的旋转矩阵旋转右相机。
-
用外参数中的 R \mathbf{R} R旋转继续旋转右相机。
-
对坐标系调整尺度。
我们首先需要确定旋转矩阵
R
r
e
c
\mathbf{R}_{\mathrm{rec}}
Rrec。为了确定这个矩阵,我们需要构造一组彼此正交的单位向量
e
1
,
e
2
,
e
3
\mathbf{e}_1, \mathbf{e}_2, \mathbf{e}_3
e1,e2,e3。我们一般选择以其中一个焦点为原点构建,选择
O
O
′
=
T
=
(
T
x
,
T
y
,
T
z
)
T
OO^{\prime} = \mathbf{T} = (T_x, T_y, T_z)^{\mathrm{T}}
OO′=T=(Tx,Ty,Tz)T作为一个基底,然后进行单位化,我们有:
e
1
=
T
∣
∣
T
∣
∣
\mathbf{e}_1 = \dfrac{\mathbf{T}}{||\mathbf{T}||}
e1=∣∣T∣∣T
构造
e
2
\mathbf{e}_2
e2则只有和
e
1
\mathbf{e}_1
e1正交并且是单位向量这约束,因此比较任意,如:
e
2
=
1
T
x
2
+
T
y
2
(
−
T
y
,
T
x
,
0
)
T
\mathbf{e}_2 = \dfrac{1}{\sqrt{T_x^2+T_y^2}} (-T_y, T_x, 0)^{\mathrm{T}}
e2=Tx2+Ty21(−Ty,Tx,0)T
容易定义:
e
3
=
e
1
×
e
2
\mathbf{e}_3 = \mathbf{e}_1 \times \mathbf{e}_2
e3=e1×e2
因此旋转矩阵为:
R
r
e
c
=
(
e
1
T
e
2
T
e
3
T
)
\mathbf{R}_{\mathrm{rec}} = \left(\begin{matrix}\mathbf{e}_1^{\mathrm{T}} \\ \mathbf{e}_2^{\mathrm{T}} \\\mathbf{e}_3^{\mathrm{T}}\end{matrix}\right)
Rrec=⎝⎛e1Te2Te3T⎠⎞
然后设置左右摄像机的旋转矩阵
R
l
=
R
r
e
c
R
r
=
R
R
r
e
c
\begin{aligned}\mathbf{R}_{l} &= \mathbf{R}_{\mathrm{rec}} \\\mathbf{R}_{r} &= \mathbf{R} \mathbf{R}_{\mathrm{rec}}\end{aligned}
RlRr=Rrec=RRrec
其中的
R
\mathbf{R}
R是外参数的旋转矩阵。
随后进行旋转和调整坐标系尺度,如:对于左相机的点
p
l
=
[
x
,
y
,
f
]
T
\mathbf{p}_l = [x,y,f]^{\mathrm{T}}
pl=[x,y,f]T,计算出
R
l
p
l
=
[
x
′
,
y
′
,
z
′
]
\mathbf{R}_l \mathbf{p}_l = [x^{\prime},y^{\prime},z^{\prime}]
Rlpl=[x′,y′,z′],随后计算器调整后的坐标系,最终有:
p
l
′
=
f
z
′
[
x
′
,
y
′
,
z
′
]
\mathbf{p}_l^{\prime} = \dfrac{f}{z^{\prime}} [x^{\prime},y^{\prime},z^{\prime}]
pl′=z′f[x′,y′,z′]
对于右相机,其操作相同。
最后的矫正结果展示如:
Reference
[1]. https://blog.csdn.net/LoseInVain/article/details/102665911
[2]. Hartley R, Zisserman A. Multiple View Geometry in Computer Vision[J]. Kybernetes, 2008, 30(9/10):1865 - 1872.
[3]. https://blog.csdn.net/LoseInVain/article/details/102756630
[4]. https://blog.csdn.net/LoseInVain/article/details/102632940