SLAM入门之视觉里程计:单应矩阵

Posted Brook@CV

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SLAM入门之视觉里程计:单应矩阵相关的知识,希望对你有一定的参考价值。

在之前的博文OpenCV,计算两幅图像的单应矩阵,介绍调用OpenCV中的函数,通过4对对应的点的坐标计算两个图像之间单应矩阵\\(H\\),然后调用射影变换函数,将一幅图像变换到另一幅图像的视角中。当时只是知道通过单应矩阵,能够将图像1中的像素坐标\\((u_1,v_1)\\)变换到图像2中对应的位置上\\((u_2,v_2)\\),而没有深究其中的变换关系。

单应(Homography)是射影几何中的概念,又称为射影变换。它把一个射影平面上的点(三维齐次矢量)映射到另一个射影平面上,并且把直线映射为直线,具有保线性质。总的来说,单应是关于三维齐次矢量的一种线性变换,可以用一个\\(3\\times3\\)的非奇异矩阵\\(H\\)表示

\\[x_1 = Hx_2 \\]

这是一个齐次坐标的等式,\\(H\\)乘以一个非零的比例因子上述等式仍然成立,即\\(H\\)是一个\\(3\\times3\\)齐次矩阵,具有8个未知量。

假设已经取得了两图像之间的单应,则可单应矩阵\\(H\\)可以将两幅图像关联起来

\\[\\left(\\begin{array}{c}u_1\\\\v_1\\\\1\\end{array}\\right) = H\\left(\\begin{array}{c}u_2\\\\v_2\\\\1\\end{array}\\right) \\]

其中,\\((u_1,v_1,1)^T\\)表示图像1中的像点,\\((u_2,v_2,1)^T\\)是图像2中的像点,也就是可以通过单应矩阵\\(H\\)将图像2变换到图像1,如下图。这有了很多实际的应用,例如图像的校正、对齐以及在SLAM中估计两个相机间的运动。

同一相机在不同的位姿得到同一平面的图像

假设使用同一相机在不同的位姿拍摄同一平面,如下图:

上图表示场景中的平面\\(\\pi\\)在两相机的成像,设平面\\(\\pi\\)在第一个相机坐标系下的单位法向量为\\(N\\),其到第一个相机中心(坐标原点)的距离为\\(d\\),则平面\\(\\pi\\)可表示为:

\\[N^TX_1 = d \\]

\\[\\frac{1}{d}N^TX_1 = 1,\\forall X_1 \\in \\pi \\]

其中,\\(X_1\\)是三维点\\(P\\)在第一相机坐标系下的坐标,其在第二个相机坐标系下的坐标为\\(X_2\\),则

\\[X_2 = RX_1 + T \\]

将上面式子结合起来,

\\[X_2 = RX_1 + T\\frac{1}{d}N^TX_1=(R+T\\frac{1}{d}N^T)X_1=H\'X_1 \\]

所以就得到了同一平面两个不同相机坐标系的单应矩阵

\\[H\' = R+T\\frac{1}{d}N^T \\]

上面提到单应表示的是两个平面之间的映射,这里为何得到了同一平面两个不同相机坐标系的单应矩阵。虽然平面是通过,但是在不同坐标系中会有不同的表示,单应也是将平面从一个位置映射到另一个位置,并保持其某些性质不变,例如保线性。[image]

上面得到的单应矩阵第一个相机坐标系取得,还需要将其变换到成像平面坐标系中,取得两图像间的单应矩阵。设\\(x_1,x_2\\)\\(P\\)在两图像的像点坐标,

\\[x_1 = KX_1,x_2 = KX_2 \\]

\\(K\\)是相机的内参数,代入上面求得单应变换公式

\\[K^{-1}x_2 = HK^{-1}x_1 \\Longrightarrow x_2 = KH\'K^{-1}x_1=K(R+T\\frac{1}{d}N^T)K^{-1}x_1 \\]

所以,同一平面得到的两个图像间的单应矩阵\\(H\\)

\\[H = K(R+T\\frac{1}{d}N^T)K^{-1} \\]

平面的单应和对极约束的区别

两图像间的单应矩阵后,有什么作用呢?它和两幅图像间的对极约束有何区别

两图像间的对极约束和场景的结构无关,也就是说对极约束对于任意场景结构的两幅图像都是成立的,不能给出两幅图像上的像点的一一对应关系,只能给出点对应的必要条件,另一幅图像上与图像上对应的像点在位于对应的对极线上。基础矩阵\\(F\\)描述的实际是一种点和直线的映射关系,而不是一种点对点的约束关系,并不能给出另一个点的确切位置。

平面间的单应,并不像对极约束完全不需要场景的结构信息,它对场景的结构有了要求:场景的点必须在同一个平面上,因此单应矩阵\\(H\\)也就能够对两图像上对应点的提供更多的约束,知道了某点在一幅图像的像点位置后,可以通过单应矩阵,求得其在另一幅图像中像点的确切位置。

也就说,三维点如果不是在同一个平面上,可以使用基础矩阵\\(F\\)来计算图像上像点在另一幅图像上对应的对极线,而不能使用单应矩阵\\(H\\)得到对应点的确切位置。但如果在这种情况下,仍使用单应矩阵\\(H\\)计算对应点的位置,其结果会如何呢,如下图

通过平面\\(P\\)在两图像上的匹配点,计算得到了其两图像间的单应矩阵\\(H\\)。三维点\\(p\'\\)并不在平面\\(P\\)上,其在图像1中的像点为\\(x_1\\),使用单应矩阵\\(H\\)计算其在图像2中对应的像点。从上图可以看出,\\(p\'\\)在图像2上的像点是\\(x_2\'\\),而使用单应矩阵计算得到的像点却是\\(x_2\\)

在这种情形下,使用单应矩阵\\(H\\)估计图像上对应点位置,误差来自两个方面:

  • 三维点\\(p\'\\)和单应矩阵\\(H\\)对应的平面\\(P\\)之间的距离。
    从上图可知使用\\(H\\)计算\\(p\'\\)像点位置时,实际得到的是却是平面\\(P\\)上的点\\(p\\)在图像2的像点,而\\(p\\)是相机1的中心\\(O_1\\)\\(p\'\\)确定的直线和平面\\(P\\)的交点。
  • 相机2相对于相机1的平移。
    具体分析可看下一小节相机只有旋转无平移下的单应

也就是说,在相机的平移相对于场景的深度足够小时,仍然可以使用单应矩阵\\(H\\)来计算图像中匹配像点的对应位置。

该段分析多数参考Homography 知多少?

相机只有旋转无平移下的单应

当相机在只有旋转而没有平移的情况下取得同一场景的两幅图像,可以使用单应矩阵\\(H\\)来描述这两图像之间的关系。

通过前面的文章知道,相机在不同位姿下取得同一场景的图像,可以使用基础矩阵\\(F\\)描述两图像像点之间的约束关系。这里的不同位姿指的是相机要有旋转和平移,但如果相机之间只有旋转无平移,图像的像点之间又有怎样的约束关系呢,单应矩阵\\(H\\)又和前面提到的基础矩阵\\(F\\),有何不同。

假设得到两幅图像的相机之间只有旋转,而没有平移\\(t = (0,0,0)^T\\),有:

\\[p_1 = KP \\ ,p_2 = KRP \\]

其中,\\(K\\)是相机的内参,\\(p_1,p_2\\)分别是两图像的像点,\\(P\\)在相机坐标系下的三维点坐标,以第一个相机的中心为坐标原点。
从上面公式可得到

\\[P=K^{-1}p_1,p_2 = KRK^{-1}p_1 \\]

又有两个图像间的单应\\(p_2 = Hp_1\\),所以就有:

\\[H = KRK^{-1} \\]

也就是在相机只有旋转的情况下,可像求解两图像间的单应矩阵\\(H\\),然后可从\\(H\\)中分解得到相机的内参数\\(K\\),以及旋转矩阵\\(R\\)
基础矩阵\\(F=K^{-T}t_{\\times}RK^{-1}\\)(具体推导过程可参看:SLAM入门之视觉里程计(3):两视图对极约束 基础矩阵 ),而由于相机的平移向量\\(t = (0,0,0)^T\\),可知基础矩阵\\(F\\)为零矩阵,也就是说

  • 在相机只有旋转而没有平移的情况下,两视图的对极约束就不再适用,这时可以使用单应矩阵\\(H\\)来描述两个图像像点的对应关系。
  • 在这种情况下,两图像点的匹配不依赖于三维点的深度信息,无法使用三角法重构出三维点在世界坐标系中的三维坐标。

通过匹配的点对计算单应矩阵

两图像上的像点\\(p_1(x_1,y_1),p_2(x_2,y_2)\\)是一对匹配的点对,其单应矩阵为\\(H\\),则有

\\[\\left(\\begin{array}{c}x_2\\\\y_2\\\\1\\end{array}\\right)=\\left(\\begin{array}{ccc}H_{11}&H_{12}&H_{13}\\\\H_{21}&H_{22}&H_{23}\\\\H_{31}&H_{32}&H_{33}\\end{array}\\right)\\left(\\begin{array}{c}x_1\\\\y_1\\\\1\\end{array}\\right)\\Leftrightarrow p_2= Hp_1 \\]

将矩阵的乘法展开,即可得到

\\[\\left\\{ \\begin{array}{c} x_2 = H_{11}x_1 + H_{12}y_1 + H_{13} \\\\ y_2 = H_{21}x_1 + H_{22}y_1 + H_{23} \\\\ 1 = H_{31}x_1 + H_{32}y_1 + H_{33} \\end{array} \\right. \\]

方便求解,可以将上面等式变换为\\(Ax = 0\\)的形式,做如下变换
第一和第二个式子的左右两边同时乘以第三个式子的左右两边得到

\\[x_2(H_{31}x_1 + H_{32}y_1 + H_{33})=H_{11}x_1 + H_{12}y_1 + H_{13} \\\\ y_2(H_{31}x_1 + H_{32}y_1 + H_{33})=H_{21}x_1 + H_{22}y_1 + H_{23} \\]

将式子的右边变为0

\\[x_2(H_{31}x_1 + H_{32}y_1 + H_{33})-H_{11}x_1 + H_{12}y_1 + H_{13} = 0 \\\\ y_2(H_{31}x_1 + H_{32}y_1 + H_{33})-H_{21}x_1 + H_{22}y_1 + H_{23} = 0 \\]

将上面的等式改写为向量积的形式,令\\(h=(H_{11}, H_{12},H_{13},H_{21},H_{22},H_{23},H_{31},H_{32},1)^T\\),单应矩阵\\(H\\)是一个齐次矩阵,可以将其最后一个元素归一化为1。
则上面两个式子可以改写为

\\[a_xh = 0\\\\ a_yh = 0 \\]

其中,\\(a_x = (-x_1,-y_1,0,0,0,x_2x_1,x_2y_1,x_2)^T\\)\\(a_y=(0,0,0,-x_1,-y_1,-1,y_2x_1,y_2y_1,y_2)^T\\)

一对匹配的点对,可以得到上述等式,\\(H\\)有8个未知量,也就说最少4对匹配的点对(任意3点不共线),就可以求出两幅图像的单应矩阵\\(H\\)。但是通常来说,图像的匹配点对要超过4对,设得到了\\(n\\)对匹配的点对,可以得到如下的等式

\\[Ah = 0,其中 A = \\left(\\begin{array}{c} a_{x1}^T\\\\a_{y1}^T\\\\a_{x2}^T\\\\a_{y2}^T\\\\ \\vdots \\\\ a_{xn}^T\\\\a_{yn}^T \\end{array}\\right) \\]

具体求解方法,可以参考SLAM入门之视觉里程计(4):基础矩阵的估计,首先将图像坐标归一化,然后使用最小二乘法或者随机采样一致性(RANSAC)的方法估计得到单应矩阵\\(H\\)

在OpenCV 中也封装了各种求解单应矩阵的方法,具体的使用可以参考OpenCV,计算两幅图像的单应矩阵,通过求解两图像的单应矩阵,将图像变换到同一个视角下,然后叠加到一起。

总结

相比于两视图的基础矩阵(本质矩阵)来说,两图像的单应矩阵比较难理解一些。针对本文,总结以下几点

  • 使用场景

    • 基础矩阵表示的是两视图的对极约束,和三维场景的结构无关,只依赖于相机的内参数以及外参数,需要两个相机的位置有旋转和平移
    • 单应矩阵对场景的三维结构有了更多的要求,需要场景中的点在同一个平面上; 或者是,对相机的位姿有了要求,两个相机之间只有旋转而无平移
  • 约束关系

    • 基础矩阵表示的像点和另一幅图像上的对极线的映射关系,使用基础矩阵无法得到像点对应点在另一幅图像上的确切位置。
    • 单应矩阵则是点和点的映射,使用单应矩阵可以找到像点在另一幅图像上对应点的确切位置。
  • 使用单应矩阵而不是基础矩阵

    • 相机只有旋转而无平移的时候,两视图的对极约束不成立,基础矩阵\\(F\\)为零矩阵,这时候需要使用单应矩阵\\(H\\)
    • 场景中的点都在同一个平面上,可以使用单应矩阵计算像点的匹配点。
    • 相机的平移距离相对于场景的深度较小的时候,也可以使用单应矩阵\\(H\\)

以上是关于SLAM入门之视觉里程计:单应矩阵的主要内容,如果未能解决你的问题,请参考以下文章

SLAM入门之视觉里程计:两视图对极约束 基础矩阵

立体视觉入门指南:关键矩阵(本质矩阵,基础矩阵,单应矩阵)

立体视觉入门指南:关键矩阵(本质矩阵,基础矩阵,单应矩阵)

SLAM中的卡方分布

根据相机外参实现单应矩阵计算的理论与实践

SLAM入门之视觉里程计:相机标定 张正友经典标定法详解