• (四)单应矩阵


    单应矩阵原理
      单应(透射变换)是射影几何中的概念,又称为射影变换。他把一个射影平面上的点映射到另一个平面对应的位置,并且把直线映射为直线,具有保线性质。与对极几何不同的是,对极几何将点映射到线上,而单应矩阵是点对点的关系。要注意的是单应矩阵的适用场景为:当场景中的特征点都落在同一平面上,比如墙、地面等,此时可用单应性估计运动。
      单应(透射变换)可以看成是仿射变换的拓展。仿射变换在图形中的变换包括:平移、缩放、旋转、斜切及它们的组合形式。这些变换的特点是:平行关系和线段的长度比例保持不变,即保持物体的平直性。而单应中也存在上述多种变换的组合形式,但是差别在于单应并不一定能保持平行关系和线段的长度比例不变。单应的特点是共面点成像,即单应变换是将某一块共面的地方变换到另外一个地方,但是多数情况下都会彻底改变物体位置和形状。
    平面表示方法
      首先需要确定一个平面法向量为 $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
    参考材料
     
     
     
     
     
     
     
     
  • 相关阅读:
    JavaScript 相等(==)与全等(===)操作符
    JavaScript 判断空对象、空数组的方法
    JavaScript中的深拷贝与浅拷贝
    JS trim去除字符串收尾指定字符
    Django+Markdown+Pygments 支持Markdown 实现代码高亮
    crontab 定时服务
    程序员如何修复婚姻的bug
    向Mysql 中插入汉字(Emoji)出现 Incorrect string value
    根据html页面id寻找对应的Js文件
    Django Pagination
  • 原文地址:https://www.cnblogs.com/yepeichu/p/12612273.html
Copyright © 2020-2023  润新知