鱼眼相机中基于平面假设的光心偏移校正

这篇文章主要是对 Hugin 开源软件中 <libpano/math.c> 的 plane_transfer_to_camera() 和 plane_transfer_from_camera() 等函数的原理分析与总结。

       在《鱼眼图像的全景矫正》这篇文章中,我们已经详细介绍了如何将一幅鱼眼图像映射到对应的 360 度全景图像上,其基本模型如图 1 所示。三维坐标 O X Y Z {OXYZ} OXYZ 表示的是我们所处的物理空间,其中 Y Y Y 轴指向我们所面朝的方向, Z Z Z 轴指向天空, X X X 轴指向我们的右手侧。而以坐标原点 O O O 为球心的球面则可视为拍摄所使用的鱼眼镜头, O O O 点即镜头的光心,将球面展开为平面即为我们所需要的全景图像。下面的二维平面 O ′ X f Y f O'X_fY_f OXfYf 为相机的成像平面。拍摄时,从 P P P 点出发的光线沿着直线 O P OP OP 到达光心 O O O 点,并发生折射,其中折射特性由镜头的设计模型和制造工艺决定,通常采用的是线性模型,即折射角线性正比于入射角。最终,折射后的光线沿着直线 O P 1 OP_1 OP1 到达成像平面,因为此时成像平面上的图像是180度颠倒的,为了方便我们通常使用的是点 P 1 P_1 P1 关于原点对称的点 P 2 P_2 P2。所有这些点 P 2 P_2 P2 就组成了我们所获得的鱼眼图像。鱼眼图像的矫正的主要工作就是从球面上的 P P P 点坐标计算出其对应的鱼眼图像上的坐标 P 2 P_2 P2,从而通过插值获得点 P P P 的像素值。

图1 鱼眼投影示意图

       从图 1 可以看到,从球面到成像平面的映射具有一定的局限性,即现实中我们无法制造一个具有完整球面的镜头,这样就无法在一次拍摄中获得完整的360度的视角。然而,要制造出一个视角大于180度的鱼眼镜头并不难,如果我们使用这样的镜头,让它朝着 Y Y Y 轴正方向拍摄一幅图像,然后绕着 Z Z Z 轴旋转180度,即朝着 Y Y Y 轴的负方向再拍摄一幅图像,理论上我们就能获得覆盖整个球面的具有360度视角的图像了。这就是多目鱼眼图像拼接所要做的事情。但这种方法也存在致命的缺陷,即我们无法拍摄运动场景的全景画面,因为这种方法中不同视角的图像来自不同的时刻。这时,我们很容易想到使用两个具有相同参数的鱼眼相机,分别朝着 Y Y Y 轴的正负方向安装,经过同步后似乎就可以同时获取360度视角的内容了。但问题又来了,因为两个鱼眼镜头的光学中心并不在同一个物理空间点上,我们称之为光心偏移,即图 1 中实际存在着两个不同位置的球面,空间中某个点分别沿着经过球心的直线到达这两个球面时,其相对于两个球心的经纬度坐标并不一样。因此,我们无法直接把一个球面上的内容复制到另一个球面上,否则会在画面交界处出现断层,也就是所谓的视差,这个问题在近景拍摄中尤为明显。要完美解决视差的问题通常十分困难,大多数情况下甚至是不可能的,因为从三维物理空间到二维图像平面的映射本身就是信息丢失的过程。因此,我们只能对一些特定的问题进行求解。例如,假设我们所拍摄的内容都在一个平面上?

图2 光心偏移校正示意图

       图 2 展示了基于平面假设的鱼眼镜头光心偏移校正的过程,主要参考了开源软件 Hugin 中所使用的方法,并通过阅读代码对其原理进行大致的归纳。为了便于理解,这里简化为二维的情况,其原理对于三维空间同样适用。其中点 O O O 是主相机的光心位置,也就是图 1 的物理坐标系原点。点 P 1 P_1 P1 是副相机的镜头光心所在位置, O P 1 OP_1 OP1 即两个镜头的光心偏移量。注意在点 O O O 和点 P 1 P_1 P1 上建立的坐标系方向是一致的,镜头的偏航、俯仰和旋转可通过其他的步骤进行处理,因此这里只涉及光心的平移。图 2 中的点的坐标都是以点 O O O 为原点的。

       假设在副相机的鱼眼图像上有一个控制点(即用于参数优化的点),其经过鱼眼投影模型的逆映射后得到的球面坐标为 P 2 P_2 P2,那么该控制点实际对应的透视投影点应该为 P 3 P_3 P3。我们只能知道该控制点对应的真正的空间坐标点在点 P 1 P_1 P1 P 3 P_3 P3 的延长线上,但无法知道相应的距离。这时我们需要一些假设条件,如假设在点 P 0 P_0 P0 处有一张平面,例如一堵墙,其与直线 O P 0 OP_0 OP0 垂直,其中 P 0 P_0 P0 在以点 O O O 为球心的球面上的经纬度坐标已知。注意,我们并不需要知道平面的真实距离。当该平面前方没有物体遮挡,即为前景时,我们就可以知道 P 3 P_3 P3 实际来自于直线 P 1 P 3 P_1P_3 P1P3 和该平面的交点 P 5 P_5 P5,其中直线 P 1 P 3 P_1P_3 P1P3 O P 0 OP_0 OP0 的夹角不能大于等于90度。如此,即可求得点 P 5 P_5 P5 沿着直线 O P 5 OP_5 OP5 到达以 O O O 点为球心的球面上的交点 P P P 的经纬度坐标。

       根据三角形的相似性,有

P 1 A = P 1 P 3 → T ⋅ P 1 P 4 → P 1 P 4 = O P 2 → T ⋅ O P 0 → O P 0 , (1) {P_1}A = \frac{ { { {\overrightarrow { {P_1}{P_3}} }^T} \cdot \overrightarrow { {P_1}{P_4}} }}{ { {P_1}{P_4}}} = \frac{ { { {\overrightarrow {O{P_2}} }^T} \cdot \overrightarrow {O{P_0}} }}{ {O{P_0}}}, \tag{1} P1A=P1P4P1P3 TP1P4 =OP0OP2 TOP0 ,(1)

P 1 B = P 1 P 0 → T ⋅ P 1 P 4 → P 1 P 4 = ( O P 0 → − O P 1 → ) T ⋅ O P 0 → O P 0 , (2) {P_1}B = \frac{ { { {\overrightarrow { {P_1}{P_0}} }^T} \cdot \overrightarrow { {P_1}{P_4}} }}{ { {P_1}{P_4}}} = \frac{ { { {\left( {\overrightarrow {O{P_0}} - \overrightarrow {O{P_1}} } \right)}^T} \cdot \overrightarrow {O{P_0}} }}{ {O{P_0}}}, \tag{2} P1B=P1P4P1P0 TP1P4 =OP0(OP0 OP1 )TOP0 ,(2)

P 1 P 3 P 1 P 5 = P 1 A P 1 B ⇒ P 1 P 5 → = P 1 B P 1 A ⋅ P 1 P 3 → . (3) \frac{ { {P_1}{P_3}}}{ { {P_1}{P_5}}} = \frac{ { {P_1}A}}{ { {P_1}B}} \Rightarrow \overrightarrow { {P_1}{P_5}} = \frac{ { {P_1}B}}{ { {P_1}A}} \cdot \overrightarrow { {P_1}{P_3}} . \tag{3} P1P5P1P3=P1BP1AP1P5 =P1AP1BP1P3 .(3)

那么,

O P 5 → = O P 1 → + P 1 P 5 → = O P 1 → + P 1 B P 1 A ⋅ O P 2 → = O P 1 → + ( O P 0 → − O P 1 → ) T ⋅ O P 0 → O P 2 → T ⋅ O P 0 → ⋅ O P 2 → . (4) \overrightarrow {O{P_5}} = \overrightarrow {O{P_1}} + \overrightarrow { {P_1}{P_5}} = \overrightarrow {O{P_1}} + \frac{ { {P_1}B}}{ { {P_1}A}} \cdot \overrightarrow {O{P_2}} = \overrightarrow {O{P_1}} + \frac{ { { {\left( {\overrightarrow {O{P_0}} - \overrightarrow {O{P_1}} } \right)}^T} \cdot \overrightarrow {O{P_0}} }}{ { { {\overrightarrow {O{P_2}} }^T} \cdot \overrightarrow {O{P_0}} }} \cdot \overrightarrow {O{P_2}} .\tag{4} OP5 =OP1 +P1P5 =OP1 +P1AP1BOP2 =OP1 +OP2 TOP0 (OP0 OP1 )TOP0 OP2 .(4)

同理,如果我们知道 P P P 点在以 O O O 点为球心的球面上的经纬度坐标,那么点 P 5 P_5 P5 在以 P 1 P_1 P1 点为球心的球面上的透视投影点 P 3 P_3 P3 相对于点 P 1 P_1 P1 的坐标为

O P 5 O P = O P 0 O P → T O P 0 → / O P 0 ⇒ O P → 5 = O P 0 2 O P → T O P 0 → O P → , (5) \frac{ {O{P_5}}}{ {OP}} = \frac{ {O{P_0}}}{ { { {\overrightarrow {OP} }^T}\overrightarrow {O{P_0}} /O{P_0}}} \Rightarrow {\overrightarrow {OP} _5} = \frac{ {OP_0^2}}{ { { {\overrightarrow {OP} }^T}\overrightarrow {O{P_0}} }}\overrightarrow {OP} ,\tag{5} OPOP5=OP TOP0 /OP0OP0OP 5=OP TOP0 OP02OP ,(5)

P 1 P 5 → = O P 5 → − O P 1 → ⇒ O P 2 → = P 1 P 3 → = P 1 P 5 → / ∥ P 1 P 5 → ∥ . (6) \overrightarrow { {P_1}{P_5}} = \overrightarrow {O{P_5}} - \overrightarrow {O{P_1}} \Rightarrow \overrightarrow {O{P_2}} = \overrightarrow { {P_1}{P_3}} = \overrightarrow { {P_1}{P_5}} /\left\| {\overrightarrow { {P_1}{P_5}} } \right\|.\tag{6} P1P5 =OP5 OP1 OP2 =P1P3 =P1P5 /P1P5 .(6)

       平面假设的前提是,所有点都是来自于同一个平面的,这也是为什么说我们不需要知道该平面的真实距离的原因(但需要知道具体的方位),然而这并不总是成立的,相反,在很多场景应用中都不可能存在可以覆盖大部分视场的平面。因此,这种方法更加适合于大面积平面图像如墙壁涂鸦的多相机拼接。当然,这也十分适合于多目鱼眼相机光心距离的估计,因为控制点都出现在各镜头的重叠视场内,而这部分视场是相对比较小的,我们可以利用一个棋盘格来提供这么一个足够大的平面。然而,即使我们已经得到了光心距离比较准确的估计,在实际鱼眼图像矫正中,如果我们不能提供所需的平面,由于空间点的来源比较复杂,依然还是难以避免出现视差。

猜你喜欢

转载自blog.csdn.net/qq_33552519/article/details/121039023