项目讲解-AVM 3D 全景泊车-畸变矫正(1)

1. 简介

这里对嵌入式部分的代码就不进行大量说明,主要对软件和算法部分进行讲解。

因为之前做完项目整理成了 doc 文档,这里直接复制过来,格式不太整齐,请谅解

这一篇只讲解一下畸变矫正,后面的历程如果能抽出时间的话,会进行整理。

实现的 AVM 算法主要是通过 4 个超大广角鱼眼摄像头 , 经过特殊算法对所拍摄图像进行畸变矫正以及拼接,形成物体周围的全景影像的系统。

该系统多应用于车辆,实现无盲区行驶,全景泊车等功能,对安全驾驶有所帮助。

而本文的 AVM 算法主要通过以下几个办法实现 ,首先 ,鱼眼畸变矫正部分 ,使用 OCamCalib Matlab 来进行鱼眼摄像头标定 ,获取到摄像机的畸变系数,内部参数等 。再根据系数生成映射矩阵实现畸变矫正 。

对于 3D GPU 加速图像拼接 ,采用的方式是通过 OpenGL ES 画出一个碗状的模型 ,识别标定板的 8 个轮廓 ,对四个摄像头进行系统标定 , 绘制碗状网格 ,将网格上数据根据模型进行拼接 ,计算拼接线函数 ,对拼接接缝进行模糊过渡处理 ,最终完成拼接 。

OpenGL 在本算法中贯穿全文,图像的显示以及模型的建立都由 OpenGL 完成 。以下是效果图

标定板原图下载,最好要按原比例下载:

链接:https://pan.baidu.com/s/1FJ_b2wS_gkuL5DeMCGPYkw 
提取码:hjg0

2. 数学原理

为什么要进行坐标标定? 相机标定的目的是 建立相机成像几何模型并矫正透镜畸变 听起来很拗口,实际上可以将这句话分为两个部分来通俗易懂的解释 。

 

第一个部分 ,建立相机成像的几何模型 ,也就是照片里的物体与真实世界里的物体对应的点与点的关系 ,这么说来可能还是有点难懂 ,再通俗点就是 ,从结果来说就是 ,真实世界里的物体移动了 ,图像上的物体会对应的作出哪些变化 。这个部分主要是得到相机的 内参和外参(这里后面做详解)。

 

第二个部分 ,校正透镜畸变 ,因为工艺原因 ,光线进入相机以后 ,经过透镜时会产生畸变 ,这个畸变一般是规律性变化 ,随着 X 和 Y 轴上数值的变大 ,畸变越来越大 ,而中心点几乎没有畸变 。而这个畸变的变化函数线就是 畸变系数

 

相机成像几何模型

前面提到了建立相机几何模型是为了建立真实世界与图像的关系 ,这样一来我们需要先设定好几个坐标来为后面的映射做好准备

 

世界坐标系(world coordinate system):用户定义的三维世界的坐标系,为了描述目标物在真实世界里的位置而被引入。单位为m

 

相机坐标系(camera coordinate system):在相机上建立的坐标系,为了从相机的角度描述物体位置而定义,作为沟通世界坐标系和图像/像素坐标系的中间一环。单位为m

 

图像坐标系(image coordinate system):为了描述成像过程中物体从相机坐标系到图像坐标系的投影透射关系而引入,方便进一步得到像素坐标系下的坐标。 单位为m

 

像素坐标系(pixel coordinate system):为了描述物体成像后的像点在数字图像上(相片)的坐标而引入,是我们真正从相机内读取到的信息所在的坐标系。单位为个(像素数目)。

 

看到上面四个坐标系可能会有点晕 ,先声明图像坐标系与像素坐标系是在 “同一个位置的同一个坐标系 ”,区别只是在于 像素坐标系是以 “一个像素 ” 为单位作为 X Y 的值 ,再变换一下原点的位置而已

这样就只剩下三个坐标系需要我们着重理解 。

再用一幅图来展示一下三个坐标系的关系(如果对这张图片不太理解 ,往后会有其他图片进行讲解)

再将这幅图拆分详解

世界坐标系:

指的是真实世界的坐标系

 

相机坐标系:

图像坐标系:

像素坐标系:

其中,相机坐标系的 轴与光轴重合,且垂直于图像坐标系平面并通过图像坐标系的原点,相机坐标系与图像坐标系之间的距离为焦距f(也即图像坐标系原点与焦点重合)。像素坐标系平面u-v和图像坐标系平面x-y重合,但像素坐标系原点位于图中左上角(之所以这么定义,目的是从存储信息的首地址开始读写)。

 

在这里我们先引入「棋盘」的概念:

 

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

 

下面将依次对刚体进行一系列变换,使之从世界坐标系进行仿射变换、投影透射,最终得到像素坐标系下的离散图像点,过程中会逐步引入各参数矩阵。

 

我们先再看一下三个坐标系的关系 ,这里引用了小孔成像来说明三个坐标系的关系 。

这里的 物体 就是 世界坐标系 ,针孔面 就是 相机坐标系 ,图像平面 就是 图像坐标系

数学变换一下 ,(用数学的角度来看 ,变换后没有区别 )

 

1、从世界坐标系到相机坐标系

 

我们需要先把棋盘从 世界坐标系 转化到 相机坐标系 中 ,从世界坐标系转换到相机坐标系的过程,可以通过旋转和平移来得到,我们将其变换矩阵由一个旋转矩阵和平移向量组合成的齐次坐标矩阵(为什么要引入齐次坐标可见后续文章)来表示:

第一个矩阵为 相机坐标系矩阵 ,第二个为 世界坐标系 乘以 一个变换矩阵

 

其中,R为旋转矩阵,t为平移向量,因为假定在世界坐标系中物点所在平面过世界坐标系原点且与Zw轴垂直(也即棋盘平面与Xw-Yw平面重合,目的在于方便后续计算),所以zw=0,可直接转换成式1的形式。其中变换矩阵 是一个 4*4 的矩阵,简略表述成如下矩阵

https://pic4.zhimg.com/80/v2-ef4a2aaea29c51b1ecf482fb9283e287_hd.jpg

而为什么通过平移和旋转就能将物体的世界坐标转化成相机坐标呢? 可能有点难以想象这个画面 ,但如果你想象的目标换成世界坐标系的 X Y Z 轴,只需要将 X Y Z 轴的位置与方向旋转到与相机坐标系重叠的位置 ,不就完成了坐标的转换了吗?

 

2. 从相机坐标系到图像坐标系

这一过程进行了从三维坐标到二维坐标的转换,也即投影透视过程(用中心投影法将物体投射到投影面上,从而获得的一种较为接近视觉效果的单面投影图,也就是使我们人眼看到景物近大远小的一种成像方式)。我们还是拿针孔成像来说明(除了成像亮度低外,成像效果和透镜成像是一样的,但是光路更简单)。

这个地方我们重新引用小孔成像的图片

但是为了在数学上更方便描述,我们将相机坐标系和图像坐标系位置对调,变成图三所示的布置方式(没有实际的物理意义,只是方便计算):

此时,假设相机坐标系中有一点M,则在理想图像坐标系下(无畸变)的成像点P的坐标为(可由相似三角形原则得出):

https://pic1.zhimg.com/80/v2-e89827d59c15d20370d4c88e4f5c38f8_hd.jpg

将上式化为齐次坐标表示形式为:

齐次坐标就是在原本的 Xm Ym Zm 的基础上 ,加上一个无意义却方便计算的 1。使他多一个维度,f 在这里代表的是 焦距 的意思。

 

3、从理想图像坐标系到实际图像坐标系(考虑畸变)

 

透镜的畸变主要分为径向畸变和切向畸变,还有薄透镜畸变等等,但都没有径向和切向畸变影响显著,所以我们在这里只考虑径向和切向畸变。

 

径向畸变是由于透镜形状的制造工艺导致。且越向透镜边缘移动径向畸变越严重。下图所示是径向畸变的两种类型:桶形畸变和枕形畸变。

实际情况中我们常用r=0处的泰勒级数展开的前几项来近似描述径向畸变。矫正径向畸变前后的坐标关系为:

Xp 是理想坐标点 ,而X 是实际坐标点,理想坐标点乘以畸变系数 ,变为实际坐标点 ,我们需要进行反向求出 ,即可将实际坐标点反畸变成理想坐标点 。

因为泰勒展开公式得 4 项多项式只能求得角点附近的畸变系数 ,所以多张图片的棋盘要尽可能的扩散 ,覆盖整个相机镜头 。

也就是取了泰勒级数展开的前 4 项作为近似公式 ,来对畸变进行近似拟合 ,因为我们只取了 4 项所以只需要算 3 个参数就能知道大概的径向畸变情况 。

除了径向畸变还有切向畸变。切向畸变需要两个额外的参数来加入 ,矫正前后的坐标关系为:

从上面来看 ,我们需要 5 个参数 ,k1 k2 k3 以及 p1 p2 。

一般情况下鱼眼摄像头我们只考虑径向畸变 ,那就可以化简为求三个参数 。

 

4、从实际图像坐标系到像素坐标系

由于定义的像素坐标系原点与图像坐标系原点不重合,假设图像坐标系原点在像素坐标系下的坐标为(u0,v0),每个像素点在图像坐标系x轴、y轴方向的尺寸为:dx、dy,且像点在实际图像坐标系下的坐标为(xc,yc),于是可得到像点在像素坐标系下的坐标为:

https://pic1.zhimg.com/80/v2-8b8817c2d07b3fa2412dd50faa5f4138_hd.jpg

这句话说起来比较长 ,实际上也就是根据一个像素对应图像坐标系的 x y 轴宽度来映射到 像素坐标系 上 。

也就是将 u v 1 化为矩阵 ,并根据上上公式关系列出一个相乘后为 3*1 的矩阵 ,也就是 3*3矩阵矩阵乘以 3*1 矩阵

3*3 的为参数矩阵

公式https://pic1.zhimg.com/80/v2-e89827d59c15d20370d4c88e4f5c38f8_hd.jpg 中(xp, yp)与公式https://pic1.zhimg.com/80/v2-8b8817c2d07b3fa2412dd50faa5f4138_hd.jpg 中(xc, yc)相同,都是图像坐标系下的坐标。

若暂不考虑透镜畸变,则将式 与式 的转换矩阵相乘即为内参矩阵M:

https://pic1.zhimg.com/80/v2-89fbc2cf556eb531168ba7cb3de24b18_hd.jpg

之所以称之为内参矩阵可以理解为矩阵内各值只与相机内部参数有关,且不随物体位置变化而变化。

 

最后用一幅图来总结从世界坐标系到像素坐标系(不考虑畸变)的转换关系:

而在标定的时候 ,我们是通过一个一个的点来确定映射关系的 ,这个映射关系是通过角点来进行匹配的 。

所以在坐标标定之前 ,我们还需要进行角点检测的算法 ,这里就不过多讲述 。

3. 两种实现方法:OCamCalib

坐标标定的代码除了调用 OpenCV 的库进行标定还可以使用 OCamCalib 工具箱进行标定

这里采用的是 OCamCalib 标定的方法 ,以下将详细介绍 OCamCalib 工具箱的使用方法 。

在使用 OCamCalib 后,生成的 calib_results 通用性较小,不支持 OpenCV 调用参数。

本文还提供另一种实现方法 ,使用 MATLAB 的 cameraCalibrator 也能完成标定 。

3.1 环境配置

这里采用的环境是 Windows 10  ,MATLAB R2015b ,但最好使用 R2017a 会更好的契合工具箱 。但别的也不影响运行 。

MATLAB 的下载与激活方式这里不多阐述 。

 

3.2 OCamCalib 工具箱

我已放入百度网盘 ,地址:

https://pan.baidu.com/s/1dVje9g21plIKlswM0lBA-g

3.3 读取图片

使用 MATLAB 打开 OCamCalib 工具箱中的 ocam_calib.m 文件 ,并 Run

切换路径到你的原始图片的路径下 cd”….”

切换成功后

好了,如果您的图像现在已经准备好了,就可以开始加载它们并校准您的相机了!

加载图像之前,请确保它们与工具箱文件位于同一文件夹中。

然后,单击“ 读取名称 ”按钮。您将在Matlab命令外壳上看到一条消息:

 

基本名称的摄像机校准图像(无编号或后缀):在这里输入你的文件名

 

该消息要求您用磁带录制图像文件的基本名称,而不使用文件格式。

 

 

例如,您将在OcamCalib工具箱中找到的图像类型为:VMRImage0.gifVMRImage1.gif ... VMRImage9.gif。这意味着图像的基本名称是VMRImage。因此,键入:

 

基本名称的摄像机校准图像(无编号或后缀):VMRImage

 

然后,它将要求您键入图像格式。因此,键入与您的格式关联的字母:

 

图像格式:([] ='r'='ras''b'='bmp''t'='tif''g'='gif''p'='pgm''j' ='jpg''m'='ppm'>> g

 

在我们的例子中,图像格式为gif,因此您需要输入g。

此时,工具箱将加载所有具有该基本名称的图像:

 

正在加载图像1 ... 2 ... 3 ... 4 ... 5 ... 6 ... 7 ... 8 ... 9 ... 10 ...

DONE

 

最后,工具箱将显示校准图像的缩略图,如下所示:

 

3.4 角点提取

 

 

提取网格角

 

网格角的提取是校准最重要的阶段,因为校准结果取决于每个图像中棋盘角的位置。

在OCamCalib工具箱的新版本中,您可以选择使用棋盘格的自动提取或进行手动操作。在第一种情况下,工具箱将允许查找所有角。在第二个步骤中,您将必须单击所有角落。

让我们看看它是如何工作的:

单击“ 提取网格角 ”。您将收到以下消息:

 

提取图像上的网格角

 

 

 

键入要处理的图像(例如[1 2 3][] =所有图像)=

 

如果要处理每个图像,请键入ENTER,或键入包含要处理的图像数的向量。在我们的教程中,我们要处理所有图像,因此我们只需要按Enter。

下一条消息是:

 

沿X方向的平方数([] = 10=  

 

键入沿X方向存在的正方形数;表示棋盘格参考框架中的垂直方向。例如,在我们的情况下,我们要沿垂直方向使用6个填充的棋盘格,并沿Y(沿水平方向)使用6个棋盘格。所以输入:

 

沿X方向的方块数([] = 10= 6

沿Y方向的正方形数([] = 10= 6

这里输入的是每个方向上的格子数 – 2 ,在边缘的格子数不算

现在,分别沿X和Y方向键入正方形的大小。在我们的图像中为20毫米。

 

沿X方向的每个正方形的大小dX[] = 30mm= 20

沿Y方向的每个正方形的大小dY[] = 30mm= 20

 

如果仅按ENTER,则工具箱将加载默认参数([] = 30mm)。但是请注意,方格大小仅用于恢复棋盘的绝对位置。但是对于固有参数,则不需要此参数,因此您甚至可以将该字段保留为空。

 

在下一条消息旁边,工具箱将询问全向图像中心的位置(行,列)。由于OcamCalib工具箱能够自动确定中心的位置,因此您只需按ENTER键即可将此字段保留为空。在这种情况下,工具箱将在第一阶段将点(高度/ 2,宽度/ 2)作为中心。不必担心,因为稍后您将使用“ 查找中心 ”按钮找到中心的正确位置!但是,如果需要,可以选择指定中心的位置,以后再使用findcenter对其进行优化

 

全向图像中心的X坐标(沿高度)=[] = 384

全向图像中心的Y坐标(沿宽度)=[] = 512=

 

接下来,您可以选择使用自动图像选择或单独处理每个图像。

使用自动图像选择时,将省略无法自动提取角点的所有图像的任何图像。如果大型校准数据集(例如,从视频数据中提取的图像)或已知角提取对校准数据集有效,则建议使用自动图像选择。

 

格栅角的提取

您要使用自动图像选择吗

还是要单独处理图像([] =自动,其他=独立)?

 

就本教程而言,建议选择单个图像处理。

如果选择了自动图像选择,请下翻到 “校准”。如果决定单独处理图像,请继续阅读此处。

 

对于单个处理,工具箱现在将要求您指定要使用自动角点提取还是手动角点提取。

 

 

我建议您使用自动模式,因为这样可以节省您单击各个角落的时间。如果幸运的话,该工具箱将自动检测所有棋盘格中100%的角。我在不同照度和分辨率下,对来自不同相机的50多个图像数据集尝试了该例程,我始终获得令人满意的95%的检测率。在许多情况下,甚至是100%。此例程基于IROS'08论文。此例程要求您使用带有白色大边框的棋盘格图案。从此处下载图案,将其打印出来并附着在平坦的刚性表面上。

 

是否要使用自动角点提取

还是要手动提取所有点([] =自动,其他=手动)?

这里建议使用自动角点提取

如果选择自动提取,则工具箱将显示以下消息:

 

正在处理图片1 ..

 

在这种情况下,例如检测到100%的角。只需按ENTER。

 

您是否想重新分配任何分配的角([] =是,其他=否)?

 

如果您满意(例如在这种情况下),只需输入任何字符即可说“ no”。

如果您说“是”,则工具箱将要求您重新定位任何已分配的角,方法是使用左键单击将其重新定位,然后单击右键以退出重新定位模式。请按照图中的指示操作!

如果缺少某些角,工具箱将要求您按照图中顶部给出的顺序单击缺失的点。例如,在下图中,缺少一些角:即点n。37、38、39。

 

 

 

 

按照图像顶部给出的指示进行操作:因此,只需按ENTER。图顶部的消息将更改,并指示您必须单击哪个角。在上图中,将要求您连续单击n点。37,然后38,最后40。 

请注意,点的编号可以在每个棋盘上改变。只要在一个方向上顺序增加,这在自动角点提取过程中根本不重要,但是在手动提取过程中则很重要!相反,请注意,当您输入缺失点时,必须遵守标题栏中建议的顺序!

 

在处理下一张图像之前,工具箱将更改点的编号并显示xy轴的方向和轴原点。按ENTER继续。

 

现在,如果您设法检测到所有点,则可以校准相机

3.5 相机校准

如果到达这里,我假设您已加载图像并提取了网格角。

因此,您终于可以校准全向摄像机了。

为此,点击校准按钮。您将收到以下消息:

多项式展开度([] = 4=

 

如果您阅读了坐标标定的数学推导,您就会知道此参数是什么,如果您没有使用此参数,则可以选择多项式的最大阶数,该阶数近似于将每个像素点投影到其中的函数3D空间。在不同相机型号上的几个实验表明,多项式阶数= 4可获得最佳结果。如果您对获得的结果不满意,请尝试减少或增加多项式的阶数。在本教程中,我们将值设置为4。选择多项式阶数后,由于这里使用了最小二乘线性最小化方法,因此可以非常快速地执行校准。

在校准结束时,工具箱将显示以下图形,其中显示了函数F的图以及相应3D矢量相对于地平线的角度THETA的图。

 

 

 

 

 

 

 

 

3.6 查找中心

注意!!!在使用校准细化之前,请始终使用查找中心工具。实际上,图像中心的自动检测是通过迭代应用次优线性估计方法完成的。因此,一旦您估计了图像中心,就可以运行校准细化,它使用非线性方法细化所有校准参数和中心位置。

 

此例程将尝试自动提取图像中心。如果在网格角提取过程中没有为全向图像的中心设置正确的值,则可以使用中心的自动检测。为此,只需单击“ 查找中心 ”按钮,OcamCalib工具箱将启动一种迭代方法来计算图像中心,从而最大程度地减少所有网格点的重投影误差。自动中心检测仅需几秒钟。 

 

迭代1 ... 2 ... 3 ... 4 ... 5 ... 6 ... 7 ... 8 ... 9 ...

 

最后,工具箱将重新计算中心的新位置的所有校准参数,并输出中心的新坐标。见下文。

 

迭代后查找中心工具的输出:

0.44±0.28

 0.37±0.25

 0.38±0.24

 0.42±0.21

 0.29±0.18

 0.32±0.14

 0.33±0.18

 0.46±0.22

 0.40±0.31

 0.36±0.20

 

 平均误差[像素]

 

 0.377502

 

 误差平方和

 

 81.896493

 

xc =

 

    3.832866677912270e + 002

 

 

yc =

 

    5.163646215408636e + 002

 

>>

 

 

平均误差是在所有棋盘上计算的重投影误差的平均值,而“平方误差之和”显然是平方重投影误差的总和。

校准参数是变量ocam_model.ss。该变量包含函数F的多项式系数。

我想回想一下F具有以下形式:

 

例如,在这里,我使用了四阶多项式,而ρ是距全向图像中心的距离,以像素为单位。

ocam_model.ss,系数从最小到最大顺序存储,即ocam_model.ss = [a0,a1,a2…]。

 

请注意,如果您想随时修改中心的坐标,只需修改变量ocam_model.xcocam_model.yc的值即可,它们分别包含中心位置的行和列。

 

 

3.7 校准细化

通过单击“ 校准细化 ”按钮,工具箱将使用Levenberg-Marquadt算法开始对校准参数进行非线性细化。通过尝试最小化平方重投影误差的总和来执行优化。

校准细化是使用Matlab优化工具箱完成的,特别是它需要函数lsqnonlin,默认情况下应具有该函数。

非线性优化分两个步骤完成。首先,它优化外部相机参数,即每个棋盘相对于相机(即RRfin)的旋转和平移矩阵。然后,它优化了相机的固有参数(即ocam_model)。由于外部参数和内部参数不是独立的,因此细化可能需要几次迭代才能收敛到最小化内部参数和外部参数的解决方案。

 

单击“ 校准细化 ”按钮后,工具箱会询问您是否要限制非线性细化的迭代次数,并告知您该过程可能需要几秒钟。

此功能交替完善  EXTRINSICINTRINSIC  校准参数

通过使用非线性最小化方法 

由于涉及到计算,因此精炼可能需要几秒钟的时间。
循环中断:按Enter键停止精炼。(必须选择OCamCalib GUI!)

 

最大迭代次数([] = 1000 =中止,-1 =无限制)=

 

按ENTER开始优化。

 

迭代1

开始优化EXTRINSIC参数...

优化棋盘姿势123456788910

棋盘姿势1已优化

开始细化INTRINSIC参数...

误差平方和:137.670161

 

 

 

 

正如您将看到的,最后一步涉及到相机的INTRINSIC参数的优化,该阶段需要大部分时间,但是通常不超过几秒钟。您可以随时按ENTER键中断优化。必须选择OCamCalib工具箱GUI(该窗口必须在焦点上)才能使中断起作用。

非线性优化终止后,您可以再次使用分析误差显示校准结果按钮来显示重新投影误差或校准结果。

3.8 重新投影图像

通过单击“ 在图像上重新投影”按钮,工具箱将根据刚刚估算出的新校准参数重新投影所有网格角。

 

会发现 X Y 轴更加契合棋盘了

在上面的左图中,您可以看到图像中心,以红色圆圈表示,该中心是使用自动中心检测计算得出的。

同时,在右图上,您可以看到棋盘格的详细信息,其中突出显示了所有角网格以及参考框架的XY轴。

红叉是您单击的网格角,而圆是校准后重新投影到图像上的网格角。

 

 

3.9 显示外部

通过单击显示外部按钮,工具箱将显示每个棋盘相对于全向摄像机参考系的位置。

这里照片比较多显示的不太清晰 ,大体为每次图片相对于照相机的位置 。

以下是官方图片:

 

3.10 分析错误

如果单击分析误差按钮,则可以看到所有棋盘的每个点的重投影误差的分布。颜色指的是棋盘的不同图像。

 

3.11 重新计算角点

通过使用此工具,工具箱将自动检测重新投影点周围的每个网格角。如果在提取网格角时您犯了一些错误,或者自动角检测器犯了一些错误,则此功能非常有用。通过使用按钮Recomp。角落,该工具箱将尝试重新计算每一个角落点的位置,你点击,通过使用再投影网作为角落最初位置。

3.12 显示校准结果

单击显示校准结果按钮 ,将显示经过一系列处理优化后的参数

将显示以下图像:

3.13 保存、加载与导出结果

要加载并保存校准结果,只需单击相应的按钮。

校准结果将保存为名称Omni_Calib_Results.mat。

 

单击导出数据按钮以将校准结果导出到文件“ calib_results.txt”。

该文件对于读取此处提供的C / C ++例程(unistort,cam2world和world2cam)非常有用。

 

到这里我们就完成了坐标标定的过程 ,成功提取到了我们需要的参数 ,接下来就可以根据参数进行畸变校正了 。

4. 两种实现方法:CameraCalibrator

使用 cameraCalibrator 的优势很明显,操作简单了许多,但同时,可修改的参数也少了许多 ,意味着根据 cameraCalibrator 标定出来的参数可能需要更多的时间去优化 ,读者酌情使用 。

文中采用的是 OCamCalib 方法,读者可以采用相同的方法,以便后续文章的阅读

4.1 环境配置

这里采用的环境是 Windows 10  ,MATLAB R2015b ,

MATLAB 的下载与激活方式这里不多阐述 。

4.2 打开 Matlab 标定工具

 

在 Command Window 窗口输入命令 cameraCalibrator 后回车

即可打开 cameraCalibrator 窗口 ,如下图所示

点击 添加图片,这里出现:

在这里注意,你添加的图片可能会被拒绝,因为你拍摄的图片不符合标准,需要重新拍摄图片来进行标定

这里我设定为 20 mm,也就是方格实际上的大小 。

 

输入无误后就涉及到最关键的一步了,选择参数。

为什么说他关键呢,因为如果你仔细阅读了OpenCV的说明之后你会大概明白畸变参数,总共有五个,径向畸变3个(k1,k2,k3)和切向畸变2个(p1,p2)。

径向畸变:

切向畸变:

因为这直接影响到了校正的结果 。

 

以及在OpenCV中的畸变系数的排列(这点一定要注意k1k2p1p2k3),千万不要以为k是连着的。

这一点可能会花费你一天的时间来发现这个错误。

并且通过实验表明,三个参数的时候由于k3所对应的非线性较为剧烈。估计的不好,容易产生极大的扭曲,所以我们在MATLAB中选择使用两参数,并且选择错切和桶形畸变。

点击开始后等待一段时间即可完成标定。并且MATLAB给出的可视化还是很不错的,可以对比校正前后的样子。

(点击图片左下角的 show Undistorted 即可临时观看畸变校正以后的样子)

到这为止,你已经完成了标定过程。选择导出参数,即可把参数进行保存。

点击 即可导出参数文件 ,导出成功后即可在在左边的工作空间看到导出文件 。双击打开

里面的RadialDistortion对应k1,k2,k3设置为0了。

TangentialDistortion对应p1,p2。

 

 

IntrinsicMatrix对应内参,注意这个和OpenCV中是转置的关系,注意不要搞错。

双击即可显示详细的内参矩阵 ,注意,这里的矩阵与 OpenCV 是转置关系

对应

 

  • 20
    点赞
  • 130
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值