(四)单应矩阵

单应矩阵原理

 

  单应(透射变换)是射影几何中的概念,又称为射影变换。他把一个射影平面上的点映射到另一个平面对应的位置,并且把直线映射为直线,具有保线性质。与对极几何不同的是,对极几何将点映射到线上,而单应矩阵是点对点的关系。要注意的是单应矩阵的适用场景为:当场景中的特征点都落在同一平面上,比如墙、地面等,此时可用单应性估计运动。

 

  单应(透射变换)可以看成是仿射变换的拓展。仿射变换在图形中的变换包括:平移、缩放、旋转、斜切及它们的组合形式。这些变换的特点是:平行关系和线段的长度比例保持不变,即保持物体的平直性。而单应中也存在上述多种变换的组合形式,但是差别在于单应并不一定能保持平行关系和线段的长度比例不变。单应的特点是共面点成像,即单应变换是将某一块共面的地方变换到另外一个地方,但是多数情况下都会彻底改变物体位置和形状。

 

平面表示方法

 

  首先需要确定一个平面法向量为 $\mathbf{\vec{n}} = [n_{1}, n_{2}, n_{3}]^{T}$,但是确定法向量并不能唯一确定一个平面。我们会得到无数多的相互平行的平面。为了唯一确定一个平面,我们还需要一个点,若平面上有一个定点 $\mathbf{x} = [x_{1}, x_{2}, x_{3}]^{T}$, 那么我们即可确定一个平面。
    假设平面上任意一点为 $\mathbf{m} = \{x, y, z\}$,平面方程为
$$Ax + By + Cz + D = 0$$

 

由于法向量已知,则上述方程可以表示成:
$$\mathbf{\vec{n}^{T}} \mathbf{m} + D = 0$$

 

显然上述的方程表示的是无数组平行的平面,确定 $D$ 即可确定唯一平面。则利用上述所说的平面上的任意动点 $x$,则有:
$$D = -\mathbf{\vec{n}^{T}}\mathbf{x} = -(n_{1}x_{1} + n_{2}x_{2} + n_{3}x_{3})$$

 

则平面的唯一表示方法为:
$$Ax + Bx + Cz = (n_{1}x_{1} + n_{2}x_{2} + n_{3}x_{3})$$

 

综上,为了表示一个平面,我们需要一个法向量,以及一个平面上的点(目的是为了求偏置)。



单应矩阵

 

由上述可知平面的表示方法可以写成:
$$\mathbf{\vec{n}}^{T}\mathbf{x} = d$$

 

参考对极几何及单应矩阵这篇文章,我们可以得到单应约束图像:

 

 

 

假设左边为第一个相机坐标系 $C_{1}$,右边为第二个相机坐标系 $C_{2}$。并且平面 $\pi$ 在第一个相机坐标系的法向量为 $\mathbf{\vec{n}}$,$C_{2}$ 到平面 $\pi$ 的距离为 $d$。假设平面中任意一个点 $\mathbf{X}$ 在第一个相机坐标系中的表示为 $\mathbf{X_{1}}$,则平面 $\pi$ 的表示方法为:
$$\mathbf{\vec{n}}^{T} \mathbf{X_{1}} = d$$
 
显然,上面的表示方法满足我们前面介绍的平面表示方法的约束条件,即一个法向量以及平面内有一个已知点。接着我们将平面 $\pi$ 的表示方法改变一下:
$$\frac{1}{d}\mathbf{\vec{n}}^{T} \mathbf{X_{1}} = 1$$

 

假设平面 $\pi$ 中有一空间点 $X$,对应两个相机的投影像素分别为 $\mathbf{p_{1}}, \mathbf{p_{2}}$,相机内参矩阵为 $\mathbf{K},$归一化平面中的坐标系为 $\mathbf{x_{1}},\mathbf{{x_{2}}}$,并且满足条件 $s_{1}\mathbf{x_{1}} = \mathbf{X_{1}}$,其中 $s_{1}$ 为 $X_{1}$ 的深度值。若已知两个坐标系之间的相对变换为 $\mathbf{R}, \mathbf{t}$,表示从相机坐标系 $1$ 变换到相机坐标系 $2$,则有:
$$\mathbf{x_{1}} = \mathbf{K}^{-1}\mathbf{p_{1}}$$
$$\mathbf{x_{2}} = \mathbf{K}^{-1}\mathbf{p_{2}}$$
$$s_{2}\mathbf{x_{2}} = s_{1}\mathbf{R}\mathbf{x_{1}} + \mathbf{t}$$
$$s_{2}\mathbf{K}^{-1}\mathbf{p_{2}} = s_{1}\mathbf{R}\mathbf{K}^{-1}\mathbf{p_{1}} + \mathbf{t}$$
 
将平面 $\pi$ 的信息代入上述方程中得到:
$$s_{2}\mathbf{K}^{-1}\mathbf{p_{2}} = s_{1}\mathbf{R}\mathbf{K}^{-1}\mathbf{p_{1}} + \frac{s_{1}}{d}\mathbf{t}\mathbf{\vec{n}}^{T} \mathbf{K}^{-1} \mathbf{p_{1}} = s_{1}(\mathbf{R} + \frac{1}{d}\mathbf{t}\mathbf{\vec{n}}^{T})\mathbf{K}^{-1} \mathbf{p_{1}} $$

 

两边左乘相机内参矩阵:
$$s_{2}\mathbf{p_{2}} = s_{1} \mathbf{K}(\mathbf{R} + \frac{1}{d}\mathbf{t}\mathbf{\vec{n}}^{T})\mathbf{K}^{-1} \mathbf{p_{1}}$$
 
其中 $\mathbf{H} = \mathbf{K}(\mathbf{R} + \frac{1}{d}\mathbf{t}\mathbf{\vec{n}}^{T})\mathbf{K}^{-1}$ 称为单应矩阵。再进一步简化为:
$$\mathbf{p_{2}} = \frac{s_{1}}{s_{2}}\mathbf{H}\mathbf{p_{1}}$$
 
在上述的式子当中,我们发现除了单应约束以外,还有一个常系数 $\frac{s_{1}}{s_{2}}$。实际上该系数影响并不大,因为在实际求解当中,我们需要将得到的三个方程同时除以第三个方程,才能得到两个有用的约束关系。(笔者以为:之所以需要这么做,是因为我们输入的数据,均是归一化的点,因此,在最终的结果上也应保持左右两边最后一维的数值应该为 $1$)。显然,上述方程对于尺度的变化是不敏感的,因为没有任何作用。
 
通过将约束条件 $\mathbf{p_{2}} = \mathbf{H}\mathbf{p_{1}}$ 展开,我们可以得到两个方程。并且我们由上面的分析可以知道,单应矩阵 $\mathbf{H}$ 并非是有 $9$ 维自由度的矩阵,因为其对尺度不敏感。所以我们将单应矩阵最后一维置为 $1$。(或者可以强制单应矩阵所有参数的平方和为 $1$)最后我们需要求解的单应矩阵一共有 $8$ 个维度。而每一对匹配点可以提供两个约束方程,那么我们至少需要四对匹配点才可以求解八个参数。在上一讲的对极约束中,我们求解的问题是一个齐次方程,而若是我们采用令单应矩阵最后一维为1的约束,我们需要求解的则是一个 $Ax = b$ 非齐次方程,不过求解方法仍是采用SVD分解来得到。若是我们想要的问题结构是一个齐次方程,则我们需要限制单应矩阵所有元素的平方和为1。

 

拾遗

 

  其实回顾上一讲中的本质矩阵,再关联一下基础矩阵。我们可以知道这两个矩阵之间相差的只是相机内参矩阵。而上述的单应矩阵其实也可以有两种解法。一种是如上的解法,也就是将相机内参矩阵融入问题结构中,与相机位姿一起求解,最后再分解出来,这种方法类对极约束中的基础矩阵的求法。另外一种就是去除相机内参,但是输入参数需要是归一化平面上的点,也就是说我们在第一步就将相机内参用了,无需再用它,那么求解单应矩阵的时候相应的就不需要求解相机内参了,这种方法类对极约束中的本质矩阵的求法。
 
   由于OpenCV提供的求解函数是基于像素点的,因此单应矩阵中包含相机内参和相对位姿。为了能够和代码对得上,笔者就将内容修改为如上的内容。代码可以参考我的github

 

参考材料
 
 
 
 
 
 
 
 
posted @ 2020-04-01 14:15  小C酱油兵  阅读(4073)  评论(0编辑  收藏  举报