智慧交通day03-车道线检测实现02-2:张氏标定法+双目标定

6.张氏标定法

张氏标定法是张正友博士在1999年发表在国际顶级会议ICCV上的论文《Flexible Camera Calibration By Viewing a Plane From Unknown Orientations》中,提出的一种利用平面棋盘格进行相机标定的实用方法。

该方法介于传统标定法和自标定法之间,既克服了传统标定法需要的高精度三维标定物的缺点,又解决了自标定法鲁棒性差的难题。标定过程不需要特殊的标定物,只需使用一张打印出来的棋盘格,并从不同方向拍摄几组图片即可,不仅实用灵活方便,而且精度很高,鲁棒性好。因此很快被全世界广泛采用,极大的进了三维计算机视觉从实验室走向真实世界的进程。

6.1. 棋盘格数据

棋盘是一块由黑白方块间隔组成的标定板,我们用它来作为相机标定的标定物(从真实世界映射到数字图像内的对象)。之所以我们用棋盘作为标定物是因为平面棋盘模式更容易处理(相对于复杂的三维物体),但与此同时,二维物体相对于三维物体会缺少一部分信息,于是我们会多次改变棋盘的方位来捕捉图像,以求获得更丰富的坐标信息。如下图所示,是相机在不同方向下拍摄的同一个棋盘图像。如下图所示:

6.2. 单应性矩阵

张氏校正法是基于平面棋盘格的标定,首先我们介绍下两个平面中的单应性映射,在计算机视觉中,单应性(Homography)指从一个平面到另一个平面的投影映射,所以在标定物平面与图像平面之间存在单应性。

上文中我们已经得到了像素坐标系和世界坐标系下的坐标映射关系,因为标定物是平面,我们假设标定棋盘位于世界坐标中z=0平面,然后进行单应性计算。化简前文中的公式有:

那单应性矩阵定义为:

代入上式中有:

那怎么求H的值呢?

假设单应性矩阵H为:

假设图像中对应点的齐次坐标为图像点(u,v,1)和真实世界点(x,y,1)则有:

将上述矩阵展开后有三个等式:

将最后一个公式代入前两个公式中:

所以一组点对应着两个等式。

下面我们将上面的公式展开:

将其整理下:

假如我们得到了标定物与图像中对应的N个点对,那么有线性方程组为:

因为单应性矩阵中包含齐次坐标,我们可以直接将和h33设为1,剩余的8个参数未知的H至少需要4个点对即可计算出来。

6.3. 利用约束条件求解内参矩阵

通过上述介绍,应用4个点我们可以获得单应性矩阵H。但是,H是内参和外参的合体。如果我们想要最终分别获得内参和外参,需要想个办法,先把内参求出来。然后外参也就随之解出了。现在我们把单应性矩阵写成三个列向量的形式:

根据单应性矩阵的定义,有:

其中,λ是标量。

我们知道r1和r2是世界坐标系沿x和y轴的旋转向量,所以两者之间是正交的,且模长为1,可得出两个约束条件:

约束条件1:r1和r2的点积为0,即:

约束条件2:r1和r2的模长为1,即:

将r1和r2用h1,h2和内参矩阵A表示,即:

接下来将约束条件替换为h1,h2和内参矩阵A的表示,则有:

其中,h1和h2已通过单应性矩阵求解出来,未知量就是内参矩阵A了。

首先令:

内参矩阵和它的逆分别是:

 

则B矩阵为:  

从上式中可以发现B是一个对称阵,所以B的有效元素只剩下六个(因为有三对对称的元素是相等的,所以只要解得下面的6个元素就可以得到完整的B了),让这六个元素构成向量b。

接下来我们在做一下化简,令:

即单应性矩阵H的某一列向量,假设:

推导可得:

利用约束条件,有:

这个方程组的本质与用h和A组成的约束条件方程组是一样的。

得到矩阵B之后我们就可以计算内参矩阵A,很简单,内参矩阵中有5个未知参数,结果如下:

6.4. 基于内参矩阵估计外参矩阵

通过上面的计算,我们已经得到了相机的内参矩阵A,根据下式:

进行化简,即可得到相机的外参矩阵。

上述的推导过程是基于理想情况下的解,从几何推导上证明了张氏标定的可行性,并没有物理意义。在实际应用中,一般使用极大似然估计进行结果进行改善。

6.5. 极大似然参数估计

首先我们回顾下极大似然估计:极大似然估计是一种估计总体未知参数的方法。它主要用于点估计问题。所谓点估计是指用一个估计量的观测来估计未知参数的真值,即在参数空间中选取使得样本取得观测值的概率最大的参数。

例如:有两个外形完全相同的箱子,甲箱中有99只白球,1只黑球;乙箱中有99只黑球,1只白球。一次实验取出一只球,该球是黑球。问题是:黑球从哪个箱子中取出的?

第一印象是:黑球最像是从乙箱中取出来的,这个推断是符合人们的经验事实。“最像”即为“极大似然”之意,这种想法被称为“极大似然原理”。

那怎么使这个函数最小呢?张氏标定法运用了解决多参数非线性优化问题的LM算法,我们接下来给大家进行介绍。

6.6.优化方法

上一节中我们介绍到极大似然求解时,我们提到了LM算法。如果要优化的问题为线性的可以直接对目标函数求导,并且令其等于零,以此求得其极值,并通过比较求取全局最小值(Global Minimizer),并将其最为目标函数的解。但是如果问题为非线性,此时我们通常无法直接写出其导数形式(函数过于复杂),因此不去试图直接找到全局最小值,而是退而求其次通过不停的迭代计算寻找到函数的局部最小值(Local Minimizer),并认为该局部最小值能够使得我们的目标函数取得最优解(最小值),这就是非线性最小二乘的通常求解思路。很显然,在张氏较正中优化问题并不是线性的,我们需要通过迭代来求最优解。

那如何进行迭代计算呢?

6.6.1. 迭代方法

梯度下降法大家已经在机器学习中接触过,我们现在根据LM算法的发展,依次介绍:牛顿法,高斯牛顿法和LM算法。

6.6.2. 牛顿法

牛顿法主要用来解决非线性优化问题,其收敛速度比梯度下降速度快。主要思想是:在现有的极小值估计值的附近对目标函数做二阶泰勒展开,进而找到极小点的下一个估计值,反复迭代直到函数的一阶导数小于某个接近0的阀值。

 

所以:

什么是雅各比矩阵和hessian矩阵?

牛顿法就是用一个二次曲面去拟合你当前所处位置的局部曲面,而梯度下降法是用一个平面去拟合当前的局部曲面,通常情况下,二次曲面的拟合会比平面更好,所以牛顿法选择的下降路径会更符合真实的最优下降路径。下图中红线表示牛顿法,绿线表示梯度下降法。

牛顿法的缺点是包含Hessian矩阵的计算,在高维度计算Hessian矩阵需要消耗很大的计算量,甚至无法计算。

6.6.3. 高斯牛顿法

高斯牛顿(Gauss-Newton)法是对牛顿法的一种改进,它用雅克比矩阵的乘积近似代替牛顿法中的二阶Hessian 矩阵,从而省略了求二阶Hessian 矩阵的计算。下面来看看高斯牛顿法是怎么做的。

 

 

6.6.4. LM法

Levenberg-Marquardt(LM)法在一定程度上修正了高斯牛顿法的缺点,因此它比高斯牛顿法更加鲁棒,不过这是以牺牲一定的收敛速度为代价的--它的收敛速度比高斯牛顿法慢。

下面来看看LM算法到底怎么修正高斯牛顿法的缺点的?

LM采用的搜索方法是信赖域(Trust Region)方法,因为高斯牛顿法中采用近似泰勒函数只在展开点附近有较好的近似效果,如果步长太大近似就不准确,因此我们应该给步长加个信赖区域,在信赖区域里,我们认为近似是有效的,出了这个区域,近似会出问题。

下面我们通过一个示例来看下LM算法的流程:

LM算法可以一定程度避免系数矩阵的非奇异和病态问题,可以提供更鲁棒、更准确的步长。因此LM算法在相机标定、视觉SLAM等领域中应用非常广泛。

6.7. 标定流程

张氏标定就是利用一张打印的棋盘格,然后对每个角点进行标记其在像素坐标系的像素点坐标,以及在世界坐标系的坐标,张氏标定证明通过4组以上的点就可以求解出H矩阵的值,但是为了减少误差,具有更强的鲁棒性,我们一般会拍摄许多张照片,选取大量的角点进行标定。具体过程如下:

  • 打印一张棋盘格标定图纸,将其贴在平面物体的表面.
  • 拍摄一组不同方向棋盘格的图片,可以通过移动相机来实现,也可以移动标定图片来实现。
  • 对于每张拍摄的棋盘图片,检测图片中所有棋盘格的特征点(角点,也就是下图中黑白棋盘交叉点,中间品红色的圆圈内就是一个角点)。我们定义打印的棋盘图纸位于世界坐标系zw=0的平面上,世界坐标系的原点位于棋盘图纸的固定一角(比如下图中黄色点)。像素坐标系原点位于图片左上角。

  • 因为棋盘标定图纸中所有角点的空间坐标是已知的,这些角点对应在拍摄的标定图片中的角点的像素坐标也是已知的,如果我们得到这样的N>=4个匹配点对(越多计算结果越鲁棒),就可以根据LM等优化方法得到单应性矩阵H,进而得到相机的内参,外参等信息。

7. 双目标定

对于双目立体视觉,有两个摄像头。它们就像人的一双眼睛一样,从不同的方向看世界。两只眼睛中的图像的视差,让我们对世界有了三维的认识。

双目标定不仅要计算出每个摄像头的内部参数,还需要通过标定来测量两个摄像头之间的相对位置(即右摄像头相对于左摄像头的三维平移 t 和旋转 R 参数)。

两摄像头之间的旋转矩阵和平移矩阵可以由下式求出:

其中,R为两摄像头间的旋转矩阵,T为两摄像头间的平移矩阵。Rr为右摄像头经过张氏标定得到的相对标定物的旋转矩阵,Tr为右摄像头通过张氏标定得到的相对标定物的平移向量。Rl为左摄像头经过张氏标定得到的相对相同标定物的旋转矩阵,Tl为左摄像头经过张氏标定得到的相对相同标定物的平移向量。

我们在直观上感受下旋转矩阵和平移矩阵的意义:

对于R,首先用T把左摄像机坐标系平移到右摄像机坐标系上(即两坐标系远点重合)。然后在同一参考系下的两个旋转矩阵相乘,表示世界坐标先向右旋转到Rr ,再向左旋转Rl。那么两次旋转后得到的旋转,就是右摄像机旋转到左摄像机所需的旋转矩阵R。

对于T,先用R对左坐标系旋转一下,把左右两摄像机调成平行,然后直接平移向量相减,即得到。两摄像机之间的平移向量T。

得到双目标定的结果,我们就可以进行立体校正,立体匹配,三维重建的内容。


总结:

  1. 相机标定的意义

    建立世界坐标系和像素坐标之间的关系,可用于三维重建,图像校正等

  2. 成像原理

    小孔成像

  3. 相机成像模型

    世界坐标系:目标物体位置的参考系,是为了更好的描述相机的位置创建的

    相机坐标系:站在相机角度的坐标系

    图像坐标系:以图像中心为原点的坐标系

    像素坐标系:以图像左上角为原点的坐标系

    坐标系之间的转换:刚体变换-- 透射变换—离散化

    内参:描述相机内部属性的参数

    外参:决定相机坐标与世界坐标系之间相对位置关系

  4. 图像畸变

    径向畸变:沿着透镜半径方向产生的畸变

    切向畸变:透镜本身与相机传感器平面或图像平面不平行而产生

  5. 相机标定方法分类

    传统的标定方法,自标定法,基于主动视觉的标定方法

  6. 张氏标定法

    利用棋盘格图像对相机进行标定:单应性矩阵,利用约束条件求解内参矩阵,根据内参矩阵估计外参矩阵,利用极大似然方法估计参数,优化方法:牛顿法,高斯牛顿法和LM算法

    标定流程:

    • 打印一张棋盘格标定图纸,将其贴在平面物体的表面.
    • 拍摄一组不同方向棋盘格的图片,可以通过移动相机来实现,也可以移动标定图片来实现。
    • 对于每张拍摄的棋盘图片,检测图片中所有棋盘格的特征点。

    • 因为棋盘标定图纸中所有角点的空间坐标是已知的,这些角点对应在拍摄的标定图片中的角点的像素坐标也是已知的,如果我们得到这样的N>=4个匹配点对(越多计算结果越鲁棒),就可以根据LM等优化方法得到单应性矩阵H,得到相机的内参,外参等信息。

  7. 双目校正

    双目较正,就是利用单目校正得到每个相机的参数后,在计算两个相机之间的相对位置。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/469658.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

指针的基本操作(10.1 Basic Pointer Operations)

[This section corresponds to K&R Sec. 5.1] The first things to do with pointers are to declare a pointer variable, set it to point somewhere, and finally manipulate the value that it points to. A simple pointer declaration looks like this: 对指针的第…

C/C++中的声明与定义

含义 声明(Declaration), 用于告诉编译器被声明的函数/变量的存在, 及它们的类型/调用格式信息, 以检查是否被正确调用. 声明不分配内存空间. 定义(Definition), 用于告诉编译器被声明的函数/变量的存在位置, 会分配内存空间. 变量/函数在被使用之前一定要被声明. 声明和定义可…

HTML animate()动画更改多个元素背景颜色但不同时生效问题

问题: 我想点击按钮时把页面中的body颜色和button中颜色【同时】改变 这个时候出现了body颜色先变化,而button颜色后变化,似乎是因为我的代码是这样有先后顺序的: $("html,body").animate({backgroundColor:BGC[rando…

plt.axis()用法详解

plt.axis(‘square’) 作图为正方形,并且x,y轴范围相同,即y m a x − y m i n x m a x − x m i n y_{max}-y_{min} x_{max}-x_{min}y plt.axis(‘equal’) x,y轴刻度等长 plt.axis(‘off’) 关闭坐标轴 官网上也贴出了其他的一些选项 plt.axis([a,…

工作队列

关于工作队列的详细API解释:http://blog.csdn.net/angle_birds/article/details/8448070 工作队列的使用:http://blog.csdn.net/zhenwenxian/article/details/17980231 下面是TP驱动中用到的工作队列:但是唤醒任务用的是queue_work函数 /** drivers/input/touchscreen/gt80…

python3列表生成式中的for循环与普通放在外面的for循环细微差异

python3列表生成式中的for循环与普通放在外面的for循环细微差异 实例: 给定列表alist [1,2,3,4,5,6,7],k3 想要使用for循环达成输出[5,6,7,1,2,3,4] 1.用外面的for循环做: alist [1,2,3,4,5,6,7] k 3 for _ in range(k):alist[0:0] [ali…

struts2学习笔记之十一:struts2的类型转换器

Struts2的类型转换器如何实现Struts2的类型转换器?* 继承StrutsTypeConverter* 覆盖convertFromString和convertToString注册类型转换器* 局部类型转换器,局部类型转换器只对当前Action起作用,需要提供如下配置文件:MyActionName-…

【Pytorch神经网络基础理论篇】 01 从零开始介绍深度学习算法和代码实现

同学你好!本文章于2021年末编写,已与实际存在较大的偏差! 故在2022年末对本系列进行填充与更新,欢迎大家订阅最新的专栏,获取基于Pytorch1.10版本的理论代码(2023版)实现, Pytorch深度学习理论篇(2023版)…

不让系统进休眠(调试时有时会用到)

关于android的锁机制,可以查看:http://blog.csdn.net/sfrysh/article/details/6608118 不让android进入休眠可以在kernel里加上三行代码。一直保管着这个锁。系统就不会进入休眠。如下: static struct wake_lock wqf_charge_display_lock; /…

【Pytorch神经网络基础理论篇】 02 pytorch环境的安装

同学你好!本文章于2021年末编写,已与实际存在较大的偏差! 故在2022年末对本系列进行填充与更新,欢迎大家订阅最新的专栏,获取基于Pytorch1.10版本的理论代码(2023版)实现, Pytorch深度学习理论篇(2023版)…

JavaScript (If...Else和Switch和循环遍历) 语句以及常用消息框

If...Else 语句 JavaScript中if...else语句和Java中的语法和使用方法是一样的。 只是在JavaScript中要使用小写字母。使用大写的 IF 会出错! 至于if...else...else if...和Java中的都是一样的。 例: var d new Date() var time d.getHours()if (time&l…

numpy中两个array数值比较,在IDE中显示完全相同,但是bool判断两个array是否相等却返回False

numpy踩坑:两个array中数值分别比较,在IDE显示相同,但是bool判断两个array是否相等值却是False 在numpy数据比较时,在IDE显示完全相同但是比较是否相等却有时候返回False? 原因出在了精度显示上面,在代码开…

C两个小例子(数组与指针)

大端模式 所谓的大端模式,是指数据的高位,保存在内存的低地址中,而数据的低位,保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位…

智慧交通day03-车道线检测实现03:相机校正和图像校正的实现

1.相机标定 根据张正友校正算法,利用棋盘格数据校正对车载相机进行校正,计算其内参矩阵,外参矩阵和畸变系数。 标定的流程是: 准备棋盘格数据,即用于标定的图片对每一张图片提取角点信息在棋盘上绘制提取到的角点&a…

win10编辑js文件报错,错误','

在filezilla中编辑js文件报错,在本地可以使用文本编辑,但需重新上传覆盖,很不方便 在win10默认应用中修改为文本编辑即可,在FTP编辑: 直接可以打开编辑

智慧交通day03-车道线检测实现04:车道线提取原理+代码实现+效果图

我们基于图像的梯度和颜色特征,定位车道线的位置。 在这里选用Sobel边缘提取算法,Sobel相比于Canny的优秀之处在于,它可以选择横向或纵向的边缘进行提取。从车道的拍摄图像可以看出,我们关心的正是车道线在横向上的边缘突变。Ope…

linux下的shell编程

下面是一个最简单的shell: 例5:输入参数 $#是指参数个数、$是所有输入的参数 #! /bin/sh echo "$# parameters"; echo "$";wqfwqf-System-Product-Name:/worksen/linuxshell$ ./echo.sh ad 1 parameters ad新建一个shell. gedit echo.sh 输入以…

C#通过修改注册表改变IE默认选项

修改注册表,这个代码好实现,关键是怎么找到对应的注册表值,也就是说画一条线很容易,难的是找到要在哪里画,然后我百度了一圈,出来的都是画线的,没有指出或者指出的不全的注册表对应值&#xff0…

宝塔+wordpress搭建/迁移网站

使用宝塔linux和阿里云ECS搭建网站/从百度云服务器迁移网站到阿里云ECS 为服务器安装宝塔软件 示例: ECS:Ubuntu 18.04 打开阿里云控制台,进入已绑定的实例页面,使用workbench或者VNC(推荐使用workbench,workbench可…

智慧交通day03-车道线检测实现05:透视变换+代码实现

为了方便后续的直方图滑窗对车道线进行准确的定位,我们在这里利用透视变换将图像转换成俯视图,也可将俯视图恢复成原有的图像,代码如下: 计算透视变换所需的参数矩阵: def cal_perspective_params(img, points):offs…