【一文弄懂】张正友标定法-完整学习笔记-从原理到实战

2023-05-16

张正友标定法-完整学习笔记-从原理到实战

文章目录

  • 张正友标定法-完整学习笔记-从原理到实战
  • (零)前言:
    • 1 为什么需要标定?
    • 2 相机标定的已知条件和待求解是什么?
      • 标定前的已知条件:
      • 待求信息:
  • (一)概念介绍和成像几何模型
    • 1.张正友标定处于什么水平,为啥提到相机标定,就不得不提他张博士的方法?
    • 2 简单介绍张博士----张氏标定法发明人
    • 3【WHY:为什么要进行相机标定?】
    • 4【HOW:相机标定的原理】
      • 在这里我们先引入「棋盘」的概念:
      • 1.从世界坐标系到相机坐标系
        • 旋转矩阵简介:
        • 旋转矩阵性质:
          • 先探究旋转矩阵怎么来的?
          • 再探究旋转矩阵和正交矩阵的关系:
        • 继续介绍外参-旋转加平移
      • 2 从相机坐标系到理想图像坐标系(不考虑畸变)
      • 3 从理想图像坐标系到实际图像坐标系(考虑畸变,第一次推导可以先不管)
      • 4 从实际图像坐标系到像素坐标系
      • 5 从相机坐标系到像素坐标系--内参矩阵
  • (二)单应矩阵
    • 1 单应性概念的引出
    • 2 单应性在计算机视觉中的应用
      • a 图像校正
      • b 视角变换
      • c 增强现实(AR)
    • 3 如何估计单应矩阵?
    • 3 如何根据标定图得到单应矩阵?
  • (三)推导求解
      • 关于标定图片数量n和内参获取的关系
  • (四)实战 | 相机标定
  • (五)标定结果的评判标准
    • 重投影误差Re-projection error

(零)前言:

算是全网最全了(毕竟直接copy了好几位大佬的教程),几乎可以一文整明白“张正友标定”。
本人的知乎链接:
张正友标定法-完整学习笔记-从原理到实战 - 未入门的炼丹学徒的文章 - 知乎

感觉CSDN的编辑更方便,但是破乎看起来更舒服一些,建议点一波知乎关注/斜眼笑

大量文字和图片直接复制的其他博主的文章,有些没有具体的标明
整理之前,需要提出几个问题:

1 为什么需要标定?

我们拿到一个新的相机,用来拍照,将三维世界的信息,投影到二维平面,得到一张RGB图像。
信息流图

一般来说,小孔成像模型就可以解释成像原理,但是真在使用过程中,由于镜片的畸变和装配等原因,单纯的小孔成像模型无法满足要求。

在需要重建三维信息的项目中,我们需要利用图像平面的特征点 + 特征点对应的深度值 + 内参和外参 ,利用“小孔成像”模型的三角关系,计算出该特征点的三维坐标

或者径向畸变比较大的情况下,rgb图片都有比较大的畸变,必须校正。

但是相机内参,一般是不好测量的,出厂的参数也很难直接拿来使用,因为制作和装配会有偏差。比如我之前用的Kinect v2相机,成像效果就畸变的厉害(效果就是,深度图和rgb图不匹配),但我同学的相机就比较好。

因此如果需要高精度的测量,必须要进行“相机标定”。

2 相机标定的已知条件和待求解是什么?

标定前的已知条件:

  • 一个可以拍照的相机,焦距固定(不要在校准和使用的时候变焦)
  • 分辨率一般已知,但是标定好像用不上。

待求信息:

相机内参(M)在这里插入图片描述
相机外参(R, t),标定过程中的外参一般用不上,需要单独标定外参
其实标定过程中的外参,用不上。毕竟标定板换了一个位姿,世界坐标系就变了,求出来的外参也会变化。
一般应用时的外参,也许是单独标定?
这个我自己没试过,感觉坑应该也不少。
在这里插入图片描述
弄清楚了上面两个问题,就需要深入的探究下面一系列的问题:

  1. 张正友标定处于什么水平,为啥提到相机标定,就不得不提他张博士的方法?
  2. 简单介绍一下张博士
  3. 他的方法优缺点,有没有替代方案?
  4. 他的方法输入输出是啥?利用工具包实现流程如何?
  5. 他的方法如何推导优化?
  6. 哪些因素对标定精度有影响?
    1. 有哪些常见的标定板?
    2. 对于角点检测,目前有哪些检测算子?
    3. 对于不同的靶标,目前能达到多高的精度等?
    4. 相机的标定精度影响因素有哪些?
    5. 对于针孔模型与鱼眼模型的标定原理是否相同?

之前准备直接复制别人的教程,但是发现别人的教程逻辑和我的有点不一样,而且有些细节和自己的推导和经验,不好加进去,更重要的是,我需要自己捋一遍标定相关知识的流程。

下面是摘抄的一些关于标定的其他小问题:

参考资料:
1.从零开始学习-张氏相机标定法:算法的基本概念和详细推导
2.【3D视觉工坊】第二期公开课:相机标定的基本原理与经验分享:基本原理和实际标定的一些细节分享
3.平面旋转基本知识:旋转矩阵的原理和性质,推导公式的时候需要用到。

(一)概念介绍和成像几何模型

1.张正友标定处于什么水平,为啥提到相机标定,就不得不提他张博士的方法?

在这里插入图片描述

本节教程链接

  1. Tsai两步法是先线性求得相机参数,之后考虑畸变因素,得到初始的参数值,通过非线性优化得到最终的相机参数。Tsai两步法速度较快,但仅考虑径向畸变,当相机畸变严重时,该方法不适用。
  2. 张氏标定法使用二维方格组成的标定板进行标定,采集标定板不同位姿图片,提取图片中角点像素坐标,通过单应矩阵计算出相机的内外参数初始值,利用非线性最小二乘法估计畸变系数,最后使用极大似然估计法优化参数。该方法操作简单,而且精度较高,可以满足大部分场合。详细原理见《从零开始学习「张氏相机标定法」(一)成像几何模型》。
  3. 基于主动视觉的相机标定法是通过主动系统控制相机做特定运动,利用控制平台控制相机发生特定的移动拍摄多组图像,依据图像信息和已知位移变化来求解相机内外参数。这种标定方法需要配备精准的控制平台,因此成本较高。
  4. 分层逐步标定法是先对图像的序列做射影重建,在重建的基础上进行放射标定和欧式标定,通过非线性优化算法求得相机内外参数。由于初始参数是模糊值,优化算法收敛性不确定。
  5. 基于Kruppa的自标定法是通过二次曲线建立关于相机内参矩阵的约束方程,至少使用3对图像来标定相机。图像序列长度会影响标定算法的稳定性,无法保证射影空间中的无穷远平面。

总结:

张正友标定,精度比较高,硬件条件可以争取.

但是张正友标定只考虑了径向畸变,没有考虑切向畸变.

2 简单介绍张博士----张氏标定法发明人

先来简单介绍一下我们的主角:张正友博士。他是世界著名的计算机视觉和多媒体技术的专家,ACM Fellow,IEEE Fellow。现任微软研究院视觉技术组高级研究员,已经Tencent Robotics X了,他在立体视觉、三维重建、运动分析、图像配准、摄像机标定等方面都有开创性的贡献。
在这里插入图片描述

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

其后2000的这篇《A flexible new technique for camera calibration》引用数更是达到了恐怖的13885次,江湖地位可见一斑。

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

在介绍「张氏标定法」之前,我们先来搞清楚一些基本问题。

3【WHY:为什么要进行相机标定?】

下面是复制别人的描述,前言是我自己的描述,感觉差距还是蛮大的— —

相机标定的目的是:建立相机成像几何模型并矫正透镜畸变。这句话有点拗口,下面分别对其中两个关键部分进行解释。

建立相机成像几何模型: 计算机视觉的首要任务就是要通过拍摄到的图像信息获取到物体在真实三维世界里相对应的信息,于是,建立物体从三维世界映射到相机成像平面这一过程中的几何模型就显得尤为重要,而这一过程最关键的部分就是要得到相机的内参和外参(后续文有具体解释)。

矫正透镜畸变: 我们最开始接触到的成像方面的知识应该是有关小孔成像的,但是由于这种成像方式只有小孔部分能透过光线就会导致物体的成像亮度很低,于是聪明的人类发明了透镜。虽然亮度问题解决了,但是新的问题又来了:由于透镜的制造工艺,会使成像产生多种形式的畸变,于是为了去除畸变(使成像后的图像与真实世界的景象保持一致),人们计算并利用畸变系数来矫正这种像差。虽然理论上可以设计出不产生畸变的透镜,但其制造工艺相对于球面透镜会复杂很多,所以相对于复杂且高成本的制造工艺,人们更喜欢用数学来解决问题。

4【HOW:相机标定的原理】

前面已经说过,相机标定的目的之一是为了建立物体从三维世界到成像平面上各坐标点的对应关系,所以首先我们需要定义这样几个坐标系来为整个过程做好铺垫:

世界坐标系(world coordinate system): 用户定义的三维世界的坐标系,为了描述目标物在真实世界里的位置而被引入。一般坐标描述为 P w = ( X w , Y w , Z w ) P_w = (X_w, Y_w, Z_w) Pw=(Xw,Yw,Zw) . 单位为m。

相机坐标系(camera coordinate system): 在相机上建立的坐标系,为了从相机的角度描述物体位置而定义,作为沟通世界坐标系和图像/像素坐标系的中间一环。 P c = ( X c , Y c , Z c ) P_c = (X_c, Y_c, Z_c) Pc=(Xc,Yc,Zc) .单位为m。

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

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

一下子定义出来四个坐标系可能有点晕,下图可以更清晰地表达这四个坐标系之间的关系:

在这里插入图片描述

世界坐标系:Xw、Yw、Zw。相机坐标系: Xc、Yc、Zc。图像坐标系:x、y。像素坐标系:u、v。

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

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

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

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

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

刚体从世界坐标系转换到相机坐标系的过程,可以通过旋转和平移来得到,我们将其变换矩阵由一个旋转矩阵和平移向量组合成的齐次坐标矩阵(为什么要引入齐次坐标可见后续文章)来表示:
在这里插入图片描述
其中,R为旋转矩阵,t为平移向量。
至于为什么r3会被省略:

假定在世界坐标系中,坐标原点选择在棋盘的左上角特征点,棋盘的平面刚好是与Xw-Yw平面重合,Zw轴穿越平面垂直向上,这时棋盘所有特征点的Zw=0,特别方便后面的计算。可直接转换成式1的形式,即省略了对Zw轴的旋转量r3

旋转矩阵简介:

参考链接:[图像]摄像机标定(1) 标定中的四个坐标系
这个旋转可以拆解为,相机绕着三个轴旋转。
先是一个基元旋转 (看一下上面的原文),有了基元旋转的基础,如果一个点在两个坐标系之中,而且两个坐标系共用一个原点,这样空间点在两个坐标系之间转换存在一个旋转矩阵R 。
在这里插入图片描述

假如两个坐标轴之间的变换关系为,坐标系1 先绕 Oz 轴旋转, 再绕 Oy 轴旋转, 最后绕 Ox 轴旋转,最终得到了坐标系2,则 旋转矩阵R 为这三个 基元旋转矩阵 依次 左乘 。
即三维空间中,完整的旋转矩阵如下表述:

旋转矩阵性质:

先探究旋转矩阵怎么来的?

二维旋转矩阵和三维旋转矩阵的推导
轴OA旋转角度(即三维空间绕Z轴旋转) θ \theta θ ,那么在二维空间如图所示:
在这里插入图片描述
有下面几条公式:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
即旋转矩阵R = 在这里插入图片描述
那么三维空间中绕Z轴的矩阵即为在这里插入图片描述
其他两个轴同理。

再探究旋转矩阵和正交矩阵的关系:

参考链接:正交矩阵是旋转矩阵吗?

  • 在矩阵论中,正交矩阵满足以下条件:
  • 1. 它的转置矩阵是它的逆矩阵,即 A T = A − 1 A^T = A^{-1} AT=A1
  • 2. 它的转置矩阵和它本身乘为E,即 A T A = E = A A T A^TA = E = AA^T ATA=E=AAT
  • 正交矩阵的行列式是正负1.
  • 正交矩阵的每一列都是单位向量
    ,互相正交,即模为1
    但是如果正交矩阵的行列式为 1,则我们称之为特殊正交矩阵–旋转矩阵,而正交矩阵行列式为-1时,为镜面反射。因此正交矩阵的性质,旋转矩阵统统继承。
  • 详细性质和推导,还是直接看维基百科。很多人写的博客和文章都不太完善的样子。

后面需要用到两个性质,旋转矩阵是一个完美的矩阵——正交矩阵:

知道了初始的旋转矩阵Rx, Ry, Rz是旋转矩阵还不行,我必须得清楚,旋转矩阵相乘,是否仍然是旋转矩阵,摘了wiki百科的一段话

所有特殊正交矩阵形成一个子群,称为特殊正交群。亦即,旋转矩阵与旋转矩阵的乘积也是一个旋转矩阵

这保证了三个旋转矩阵相乘之后,仍然是旋转矩阵,旋转矩阵的那些性质仍然能用上,即正交矩阵的性质也能用上。我们需要下面两个性质:

  1. R所有列向量单位向量,且互相正交。
  2. R的逆等于它的转置。

继续介绍外参-旋转加平移

因为假定在世界坐标系中,坐标原点选择在棋盘的左上角特征点,棋盘的平面刚好是与Xw-Yw平面重合,Zw轴穿越平面垂直向上,这时棋盘所有特征点的Zw=0,特别方便后面的计算。可直接转换成式1的形式,即省略了对Zw轴的旋转量r3。其中变换矩阵在这里插入图片描述
即为前文提到的外参矩阵,之所称之为外参矩阵可以理解为只与相机外部参数有关,且外参矩阵随刚体位置的变化而变化。

下图表示了用R,t将上述世界坐标系转换到相机坐标系的过程。
在这里插入图片描述

2 从相机坐标系到理想图像坐标系(不考虑畸变)

这一过程进行了从三维坐标到二维坐标的转换,也即投影透视过程(用中心投影法将物体投射到投影面上,从而获得的一种较为接近视觉效果的单面投影图,也就是使我们人眼看到景物近大远小的一种成像方式)。我们还是拿针孔成像来说明(除了成像亮度低外,成像效果和透镜成像是一样的,但是光路更简单)。
在这里插入图片描述
成像过程如图二所示:针孔面(相机坐标系)在图像平面(图像坐标系)和物点平面(棋盘平面)之间,所成图像为倒立实像。

但是为了在数学上更方便描述,我们将相机坐标系和图像坐标系位置对调,变成图三所示的布置方式(没有实际的物理意义,只是方便计算):
在这里插入图片描述
此时,假设相机坐标系中有一点M,则在理想图像坐标系下(无畸变)的成像点P的坐标为(可由相似三角形原则得出):
在这里插入图片描述
将上式化为齐次坐标表示形式为:
在这里插入图片描述

3 从理想图像坐标系到实际图像坐标系(考虑畸变,第一次推导可以先不管)

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

径向畸变是由于透镜形状的制造工艺导致。且越向透镜边缘移动径向畸变越严重。下图所示是径向畸变的两种类型:桶形畸变和枕形畸变。
在这里插入图片描述
实际情况中我们常用r=0处的泰勒级数展开的前几项来近似描述径向畸变。矫正径向畸变前后的坐标关系为:
在这里插入图片描述
由此可知对于径向畸变,我们有3个畸变参数需要求解。

切向畸变是由于透镜和CMOS或者CCD的安装位置误差导致。因此,如果存在切向畸变,一个矩形被投影到成像平面上时,很可能会变成一个梯形。切向畸变需要两个额外的畸变参数来描述,矫正前后的坐标关系为:

在这里插入图片描述

由此可知对于切向畸变,我们有2个畸变参数需要求解(但是张正友标定法,不求切向畸变)。
综上,我们一共需要5个 3个畸变参数(k1、k2、k3、p1和p2 )来描述透镜畸变。

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

由于定义的像素坐标系(u, v)原点与图像坐标系(x,y)原点不重合,假设图像坐标系原点在像素坐标系下的坐标为(u0,v0),每个像素点在图像坐标系x轴、y轴方向的尺寸为:dx(每米多少个像素)、dy,且像点在实际图像坐标系下的坐标为(xc,yc),于是可得到像点在像素坐标系下的坐标为:
在这里插入图片描述
化为齐次坐标表示形式可得:

在这里插入图片描述

公式2中(xp, yp)与公式5中(xc, yc)是一个概念,都是图像坐标系下的坐标。

若暂不考虑透镜畸变,则将式2与式5的转换矩阵相乘即为内参矩阵M:
在这里插入图片描述
之所以称之为内参矩阵可以理解为矩阵内各值只与相机内部参数有关,且不随物体位置变化而变化。

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

在这里插入图片描述

5 从相机坐标系到像素坐标系–内参矩阵

直接将相机坐标系-像素坐标系联合起来,就是内参矩阵在这里插入图片描述

(二)单应矩阵

在之前的描述中,已经得到了棋盘格的世界坐标系和像素坐标系下坐标映射关系:
在这里插入图片描述
其中,u、v表示像素坐标系中的坐标,s表示尺度因子,fx、fy、u0、v0、γ(由于制造误差产生的两个坐标轴偏斜参数,通常很小)表示5个相机内参,R,t表示相机外参,Xw、Yw、Zw(假设标定棋盘位于世界坐标系中Zw=0的平面)表示世界坐标系中的坐标。

1 单应性概念的引出

我们在这里引入一个新的概念:单应性(Homography)变换。可以简单的理解为它用来描述物体在世界坐标系和像素坐标系之间的位置映射关系。对应的变换矩阵称为单应性矩阵。在上述式子中,单应性矩阵定义为:

在这里插入图片描述
其中,M是内参矩阵
在这里插入图片描述
从单应矩阵定义式子来看,它同时包含了相机内参和外参。在进一步介绍相机标定知识之前,我们重点来了解一下单应性,这有助于深入理解相机标定。因为在计算机视觉领域,单应性是一个非常重要的概念。

为了不让读者一上来就淹没在公式的汪洋大海中失去兴趣,我们颠倒一下顺序,先来看看单应性到底有什么用,然后再介绍单应矩阵的估计方法。

2 单应性在计算机视觉中的应用

单应性在计算机视觉领域是一个非常重要的概念,它在图像校正、图像拼接、相机位姿估计、视觉SLAM等领域有非常重要的作用。

a 图像校正

单应矩阵进行图像矫正的例子如下图所示,最少需要四个对应点对(后面会给出原因)就可以实现。

在这里插入图片描述

b 视角变换

单应矩阵用于视角变换的例子如下图所示,可以方便地将左边普通视图转换为右图的鸟瞰图。
在这里插入图片描述

c 增强现实(AR)

平面二维标记图案(marker)经常用来做AR展示。根据marker不同视角下的图像可以方便的得到虚拟物体的位置姿态并进行显示,如下图所示。
在这里插入图片描述

3 如何估计单应矩阵?

了解了上述单应性的部分应用后,我们就有很大的动力来学习单应矩阵的推导和计算了。首先,我们假设两张图像中的对应点对齐次坐标为(x’,y’,1)和(x,y,1),单应矩阵H定义为:
在这里插入图片描述
则有:
在这里插入图片描述
矩阵展开后有3个等式,将第3个等式代入前两个等式中可得:
在这里插入图片描述
也就是说,一个点对对应两个等式。在此插入一个讨论:单应矩阵H有几个自由度?

或许有人会说,9个啊,H矩阵不是9个参数吗?从h11到h33总共9个。真的是这样吗?实际上并不是,因为这里使用的是齐次坐标系,也就是说可以进行任意尺度的缩放。比如我们把hij乘以任意一个非零常数k并不改变等式结果:
在这里插入图片描述
所以实际上单应矩阵H只有8个自由度。8自由度下H计算过程有两种方法。

第一种方法:直接设置 h33=1,那么上述等式变为:
在这里插入图片描述
第二种方法:将H添加约束条件,将H矩阵模变为1,如下:
在这里插入图片描述
以第2种方法(用第1种也类似)为例继续推导,我们将如下等式(包含||H||=1约束):在这里插入图片描述
乘以分母展开,得到:
在这里插入图片描述
整理,得到:
在这里插入图片描述
假如我们得到了两幅图片中对应的N个点对(特征点匹配对),那么可以得到如下线性方程组:
在这里插入图片描述
写成矩阵形式:
在这里插入图片描述
由于单应矩阵H包含了||H||=1约束,因此根据上图的线性方程组,8自由度的H我们至少需要4对对应的点才能计算出单应矩阵。 这也回答了前面图像校正中提到的为何至少需要4个点对的根本原因。

也就是说单张标定图片,必须要4个特征点被提取出来,我们的棋盘格远多于这个值,因此会有优化效果。

但是,以上只是理论推导,在真实的应用场景中,我们计算的点对中都会包含噪声。比如点的位置偏差几个像素,甚至出现特征点对误匹配的现象,如果只使用4个点对来计算单应矩阵,那会出现很大的误差。因此,为了使得计算更精确,一般都会使用远大于4个点对来计算单应矩阵。另外上述方程组采用直接线性解法通常很难得到最优解,所以实际使用中一般会用其他优化方法,如奇异值分解、Levenberg-Marquarat(LM)算法(后续文章会介绍)等进行求解。

3 如何根据标定图得到单应矩阵?

经过前面一系列的介绍,我们应该大致明白如何根据打印的棋盘标定图和拍摄的照片来计算单应矩阵H。我们来总结一下大致过程。

1、打印一张棋盘格标定图纸,将其贴在平面物体的表面。

2、拍摄一组不同方向棋盘格的图片,可以通过移动相机来实现,也可以移动标定图片来实现。

3、对于每张拍摄的棋盘图片,检测图片中所有棋盘格的特征点(角点,也就是下图中黑白棋盘交叉点,中间品红色的圆圈内就是一个角点)。我们定义打印的棋盘图纸位于世界坐标系Zw=0的平面上,世界坐标系的原点位于棋盘图纸的固定一角(比如下图中黄色点)。像素坐标系原点位于图片左上角。
在这里插入图片描述
4、因为棋盘标定图纸中所有角点的空间坐标是已知的,这些角点对应在拍摄的标定图片中的角点的像素坐标也是已知的,如果我们得到这样的N>=4个匹配点对(越多计算结果越鲁棒),就可以根据LM等优化方法得到其单应矩阵H。当然计算单应矩阵一般不需要自己写函数实现,MATLAB和OpenCV中就有现成的函数可以调用。

Mat findHomography(InputArray srcPoints, 
InputArray dstPoints, 
int method=0, 
double ransacReprojThreshold=3, 
OutputArray mask=noArray() )

从函数定义来看,只要输入匹配点对,指定具体计算方法即可输出结果。

至此,我们已经搞清楚单应矩阵的概念、推导和应用了,下一篇文章我们继续学习张氏相机标定法。

(三)推导求解

(一)成像几何模型 中我们学习了相机成像几何模型,知道了如何将世界坐标系中的三维坐标和像素坐标系中的二维坐标联系起来 ,在 (二)单应矩阵中,我们根据标定棋盘图纸及其对应的照片已经可以得到单应矩阵H了。如下所示:
在这里插入图片描述
其中s为非零常数 ,在上一节中可以知道,因为H这里使用的是齐次坐标系,也就是说可以进行任意尺度的缩放。

下一步如何求相机内外参数呢?

我们知道H是内参矩阵和外参矩阵的混合体,而我们想要最终分别获得内参和外参。所以需要想个办法,先把内参求出来(先求内参是因为更容易,因为每张图片的内参都是固定的,而外参是变化的),得到内参后,那张标定图片的外参也就随之解出了。

我们先不考虑镜头畸变,来看看如何求解内参和外参。求解思路是利用旋转向量的约束关系,以下是具体推导,建议自己演算一遍,加深理解。

为了利用旋转向量之间的约束关系,我们先将单应性矩阵H化为3个列向量,即H=[h1 h2 h3],则有
在这里插入图片描述
按元素对应关系可得:
在这里插入图片描述
因为旋转向量在构造中是相互正交的,即r1和r2相互正交,由此我们就可以利用“正交”的两个含义,得出每个单应矩阵提供的两个约束条件:

约束条件1: 旋转向量点积为0(两垂直平面上的旋转向量互相垂直),这个可以参考上面对旋转矩阵的性质介绍 – 旋转矩阵的每一列都是彼此正交,且模为1,即:
在这里插入图片描述
约束条件2:旋转向量长度相等(旋转不改变尺度),(我认为还是上面的那个性质–旋转矩阵的每一列都是彼此正交,且模为1)即:
在这里插入图片描述
所以一个单应性矩阵H可以提供上述两个约束条件 。那么如何利用上述两个约束条件求解内参或者外参呢?我们一步一步来看,由前面可知内参矩阵M:

在这里插入图片描述
记为公式B展开
在这里插入图片描述
我们看到B为对称矩阵,真正有用的元素只有6个(主对角线任意一侧的6个元素)。把B带入前面两个约束条件后可转化为:
在这里插入图片描述
上面两约束中的式子均可写为通式: h i T B h j h_i^TBh_j hiTBhj 的形式,定义3X3的单应矩阵H=[h1 h2 h3]的第i列列向量:
h i = [ h i 1 , h i 2 , h i 3 , ] h_i = [h_{i1}, h_{i2}, h_{i3},] hi=[hi1,hi2,hi3,]
将如下表达式代入上述的约束单项式:
(这一步得详细的解释一下,我从上面的图,到下面的图,是一眼没看出来如何变化的。
其实这个变化就是将 h i T B h j h_i^TBh_j hiTBhj乘完,得到的就是行向量(hij相关)*列向量(Bij)=0的式子。
即已经将已知参数hi和未知参数Bij分开了。

在这里插入图片描述
为了简化表达形式,令:

在这里插入图片描述
则有:
在这里插入图片描述
由此,两约束条件最终可以转化为如下形式:
在这里插入图片描述
如果我们拍摄了n张不同角度的标定图片,因为每张图片我们都可以得到一组(2个)上述的等式。其中,v12,v11,v22可以通过前面已经计算好的单应矩阵得到,因此是已知的,而b中6个元素是待求的未知数。因此,至少需要保证图片数 n>=3,我们才能解出b。

根据n张不同角度的标定图片,最终我们得到了一个矩阵集合 Vb=0 ,其中V是一个 (2n x 6) 的矩阵。

关于标定图片数量n和内参获取的关系

如果 n>=3,就可以得到唯一解b(带有一个比例因子λ)。

如果 n=2,也就是只有两张标定图片,那么我们可以设置内参中的γ=0(γ表示由于制造误差产生的两个坐标轴偏斜参数,通常很小,可忽略),将前面式子(搬运到下图)中γ=0可以看到对应 B12=0,换句话说,就是增加了一个约束条件:[0, 1, 0, 0, 0, 0]b = 0。

如果n=1,只能假设u0, v0已知(位于图像中心)且 γ=0,这样只能解出fx, fy两个参数。

即如果我们假设畸变可以忽略,图像分辨率已知(基本都知道),那么我们仍然能求出内参!

前面说到,B中包含一个尺度因子λ,即:
在这里插入图片描述
假设我们已经根据前面计算得到了矩阵B元素的值,那么根据已知的矩阵B很容易解出内参(代入公式B展开),如下:
在这里插入图片描述
这里最后一行,应该是直接解出了尺度因子λ ?

得到内参数后,内参矩阵M也已知。单应矩阵H也已知,因此可继续求得外参数(其中r3,由于世界坐标系是彼此正交,因此r3=r1*r2,不加负号,应该是右手坐标系?):
在这里插入图片描述
其中又由旋转矩阵性质有
在这里插入图片描述
则可得(疑惑的是,为啥这里有一次求解了尺度因子λ?
在这里插入图片描述
实际情况下,数据中是存在噪音的,所以计算得到的旋转矩阵R并不一定能满足旋转矩阵的性质。所以通常根据奇异值分解来得到旋转矩阵R。

上述的推导结果是基于理想情况下的解,从理论上证明了张氏标定算法的可行性。但在实际标定过程中,一般使用最大似然估计进行优化。假设我们拍摄了n张标定图片,每张图片里有m个棋盘格角点。三维空间点X在图片上对应的二维像素为x,三维空间点经过相机内参M,外参R,t变换后得到的二维像素为x’(类似于一个函数,输入参数和世界坐标,输出一个二维投影图像坐标(x’,y’)),假设噪声是独立同分布的,我们通过最小化x, x’的位置来求解上述最大似然估计问题:
在这里插入图片描述
现在我们来考虑透镜畸变的影响,由于径向畸变的影响相对较明显,所以主要考虑径向畸变参数,根据经验,通常只考虑径向畸变的前两个参数k1,k2就可以(增加更多的参数会使得模型变的复杂且不稳定)。实际求解中,通常把k1,k2也作为参数加入上述函数一起进行优化,待优化函数如下所示
在这里插入图片描述
上述非线性优化问题通常用Levenberg-Marquardt(LM)算法进行迭代求解。一般将k1,k2初值设为0。

至此,张氏相机标定理论部分已经介绍完毕。

(四)实战 | 相机标定

MATLAB相机标定应用程序
MATLAB自带相机标定应用程序,有camera calibrator和stereo camera calibrator两类相机标定应用程序。其操作简单、直观,能够获得相机的内、外参数以及畸变参数等。
在这里插入图片描述
其中,camera calibrator用于单目相机标定;stereo camera calibrator用于双目相机标定。两者操作方式相同,唯一区别在于stereo camera calibrator添加图片时会弹出添加两个相机图片的操作框。
在这里插入图片描述
标定板准备(实验室经费有限,只能自己制作)
平面标定板具有以下几个优点:

  1. 易于操作;
  2. 尺寸可以制作的非常精确;
  3. 非常方便应用在背光照明应用中,只需要使用透明材料制作放置标志点的底盘即可。

使用MATLAB编程进行棋盘标定板的制作,将图片打印后固定在一块平板上。程序如下:

J = (checkerboard(300,3,4)>0.5);   %生成黑白棋盘图像
figure, imshow(J) %显示黑白棋盘图像
imwrite(J,'plate.jpg');%保存黑白棋盘图像

效果如图:(感觉有点寒酸呀,“但这不重要”,没条件自己创造)
(我的经验–这样的棋盘效果很差!)
在这里插入图片描述
Camera Calibrator应用程序
camera calibrator操作界面如下:
在这里插入图片描述
对于标定图像数量,位姿越多,标定结果也会越精确,建议在10到20幅之间。按照上图中的1、2、3进行相机标定操作。我们可以选择径向畸变系数以及是否计算切向畸变和倾斜,通过优化选项可以设置内参矩阵以及径向畸变参数的输出形式。

1.添加标定图像后显示界面如下图:
在这里插入图片描述
2.相机标定后显示界面会显示相机与标定板之间的位置关系。
在这里插入图片描述
3.相机参数输出camera calibrator应用程序相机标定参数输出如图所示:
在这里插入图片描述
高亮:MATLAB相机标定结果中的内参矩阵默认格式为在这里插入图片描述
,其中fx,fy、分别为x轴和y轴的有效焦距;s为u轴和v轴的不垂直因子,一般令s=0; u0,v0是光学中心。注意事项:

  1. 制作棋盘格标定板时,黑色方格与白色方格尺寸需要相同,所有方格尺寸一致;
  2. 采集标定板图像时,应采集多幅不同位姿的标定板图像,采集图像数量不应太少,建议10~20幅为宜;
  3. 采集图像时,相机的焦距不能调节,否则会改变相机的内参数,导致标定失败;
  4. MATLAB相机标定程序能够自动计算重投影误差,重投影误差越小表示相机标定的精度越高。

相机标定参数的准确度
相机标定过程中如果标定板放置不适当的话将会导致相机参数中某个参数或某些参数不能得到唯一值。为了得到高准确度的相机参数必须避免这种情况的发生。除了这个影响外,影响相机参数准确度的主要因素就是用于进行相机标定的图像数量。下面显示了用于相机标定的图像数量对参数的影响。
在这里插入图片描述
从图中可以看出相机参数的准确度随使用图像数量的增加而明显增加。为什么使用相当多的标定图像可以提高相机标定精度?这主要是因为相机参数之间存在不容忽视的相关性,这些参数只能通过多次无关测量进行求解。为了得到更准确的相机参数,我们需要这样做:

标定板在图像中最好能够覆盖整个视野(覆盖图像的每个角落可以使得径向畸变系数更准确);

标定板覆盖较大的深度范围(将标定板绕它的轴和轴旋转或者放置在不同距离的位置上)。

(五)标定结果的评判标准

重投影误差Re-projection error

用目标函数,将三维物点投影至二维图像中与二维图像中提取出的对应角点坐标做某种差值计算(目标函数)求和。

提出问题:重投影误差是否可以完全正确的反应出标定(内外参)结果是否正确?

不一定,这个重投影误差还受以下因素影响:

①图像角点检测精度,如果角点检测精度差,会直接影响到重投影误差;

②相机本身存在噪声,相机抖动;

③与相机分辨率有关,由于单位是像素。在其它条件一致的情况下,分辨率越大的相机,它的像素越密集,得到的重投影误差也会大;

④优化算法

其它评判标准:

选择两个三维的点,将其投影在二维图像上,计算这两个点的距离。用角点检测算法在这个图像上检测出对应点,也计算这两个像点之间的距离。判断两个距离的偏差。

(4)应用

①单目:PnP问题

根据三维标定靶与二维平面之间的对应点坐标,求解三维标定靶与二维平面之间的转换关系(旋转和平移矩阵)。

在OpenCV中可通过函数solvePnP实现。

②双目测量

用两个相机拍摄的图片中可以恢复三维信息,这是由于二维图片中的一点对应于三维空间中的一条射线,由两条射线的交点可以确定这个点在三维空间中的位置。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【一文弄懂】张正友标定法-完整学习笔记-从原理到实战 的相关文章

  • java中几种读取配置文件的方法

    java读取 properties配置文件的几种方法 xff08 1 xff09 Properties类读取 Properties类继承自Hashtable类并且实现了Map接口 xff0c 也是使用一种键值对的形式来保存属性集 不过Pro
  • Java项目分层

    MVC模式 在实际的开发中有一种项目的程序组织架构方案叫做MVC模式 xff0c 按照程序 的功能将他们分成三个层 xff0c 如下图 xff1a Modle层 xff08 模型层 xff09 View层 xff08 显示层 xff09 C
  • 简单介绍控制理论(经典、现代)

    1 经典和现代的区别和联系 xff08 1 xff09 区别 研究对象 经典控制系统一般局限于单输入单输出 线性定常系统 主要分为开环控制系统和闭环控制系统 严格的说 xff0c 理想的线性系统在实际中并不存在 实际的物理系统 xff0c
  • 框架中<include>**/*.xml</include>配置解释

    在mybatis Spring SpringMVC SpringBoot等框架的配置文件中经常会使用到如下代码 xff1a lt resource gt lt directory gt src main java lt directory
  • 反转单链表的几种方式对比(包括双指针法和递归)

    需求 xff1a 给你单链表的头节点 head xff0c 请你反转链表 xff0c 并返回反转后的链表 方式一 xff1a 双指针法 建立一个虚拟节点 class Solution public ListNode reverseList
  • 正则表达式 ^$ 同时出现代表什么

    与 同时出现在正则前后表示什么 xff1f 脱字符 xff1a 匹配开头 xff0c 若存在多行匹配多行的行头 美元符 xff1a 匹配尾部 xff0c 若存在多行匹配多行的尾部 同时写时只是限制字符的起点与终点 xff0c 比如 xff1
  • 设置虚拟机为固定IP,避免每次启动虚拟机都会分配新的IP地址

    采用一种最简单的方式 xff0c 通过修改配置文件来指定IP xff0c 并可以连接到外网 要求 xff1a 将IP地址配置为静态的 xff0c 比如设固定IP地址为192 168 117 131 打开文件 etc sysconfig ne
  • 我的2014--众人皆醉我独醒

    转眼间大学两年过去了 xff0c 舍友们还在撸游戏 xff0c 有的也找到了另一半的归属 我是我宿舍唯一一个不玩电脑游戏的人 xff0c 当然 xff0c 不是不玩游戏就代表着成绩很好 xff0c 也不代表玩游戏就不好 xff0c 但意味着
  • Java多线程通信-利用传统的线程通信wait(),notify()方法实现“生产者消费者模式”

    想利用传统的线程通信wait notify xff0c notifyAll 方法 xff0c 必须依赖于同步监听器的存在 xff0c 也就是说 xff0c 对于synchronized修饰的同步方法 xff0c 因为该类的默认实例 xff0
  • java TCP/IP实现简单的多人聊天功能

    TCP IP是可靠的网络协议 xff0c 数据的传输需要服务端和客户端之间三次 握手 xff0c 比较适合文本等一些可靠性要求高的数据传输 xff0c 但是它的效率较UDP低 下面通过一张图来简要说明使用 ServerSocket 创建 T
  • 死锁面试题(什么是死锁,产生死锁的原因及必要条件)

    什么是死锁 xff1f 所谓死锁 xff0c 是指多个进程在运行过程中因争夺资源而造成的一种僵局 xff0c 当进程处于这种僵持状态时 xff0c 若无外力作用 xff0c 它们都将无法再向前推进 因此我们举个例子来描述 xff0c 如果此
  • 标准模板库-容器

    标准模板库STL Standard Template Libarary 是一个标准类与函数模板的库 STL包含容器 容器适配器 迭代器 算法 函数对象和函数适配器 容器 用来存储和组织其他对象的对象 T是存储在容器中的元素类型的模板类型形参
  • Ubuntu18.04安装PX4踩坑、报错及解决方案整理

    笔者最近需要跑无人机巡检大坝的仿真 xff0c 于是在自己的Ubuntu2018 04中开始安装PX4 xff0c 问过不少之前已经装过PX4的师兄和同学 xff0c 都曾在PX4安装过程中踩过许多坑 xff0c 耗费了不少时间 xff0c
  • 初识ROS文件结构:以阿木实验室Prometheus项目为例

    ROS的工作空间是一个存放工程开发相关文件的文件夹 xff0c Fuerte版本之后的ROS默认使用的是Catkin编译系统 功能包是ROS软件中的基本单元 xff0c 包含ROS节点 库 配置文件等 一个文件夹是功能包的标志是该文件夹中有
  • 六轴无人机装配问题小结(Pixhawk飞控、APM固件、电机装配、电调校准)

    笔者近期需要组装一架六轴无人机供超声波避障模块 单点激光雷达等传感器的测试使用 由于是第一次碰真机 xff0c 面对散落一箱的部件还是非常的头大的 xff0c 不过好在实验室有经验的大佬能提供一些指导 xff0c 并且还能够参考 创客智造
  • 测试API接口,返回404。

    报错 xff1a 34 timestamp 34 34 2020 06 02T12 40 53 125 43 00 00 34 34 status 34 404 34 error 34 34 Not Found 34 34 message
  • 再谈STM32的CAN过滤器-bxCAN的过滤器的4种工作模式以及使用方法总结

    转自 xff1a http blog csdn net flydream0 article details 52317532 1 前言 bxCAN是STM32系列最稳定的IP核之一 xff0c 无论有哪个新型号出来 xff0c 这个IP核基
  • NVIDIA TX2自制底板的USB口无法使用的一种解决方法

    这是由于官方的底板上采用INA3221芯片做了电源监控电路 xff0c 只有确保5V电源达到要求的情况下才会使能USB口 而自制的底板上将上述电路省略了 xff0c 所以导致了USB口无法使用 解决办法就是要给TX2更新设备树 在网上找到一
  • Benchmark(基准测试)初相识

    一 benchmark概念 在计算中 xff0c 基准是运行一个计算机程序 一组程序或其他操作的行为 xff0c 以评估一个对象的相对性能 xff0c 通常是通过对它运行一些标准测试和试验 基准测试一词也通常用于精心设计的基准测试程序本身
  • 嵌入式中的通讯协议——UART、I2C、SPI、DMA

    目录 一 通讯的基本概念 二 USART 串口通讯 三 I2C通讯协议 四 SPI通讯协议 五 DMA 直接存储器存取 六 USART I2C SPI比较 一 通讯的基本概念 1 串行通讯与并行通讯 xff08 按数据的传送方式 xff09

随机推荐

  • RISC与CISC比较

    RISC的设计重点在于降低由硬件执行指令的复杂度 xff0c 因为软件比硬件容易提供更大的灵活性和更高的智能 xff0c 因此RISC设计对编译器有更高的要求 xff1b CISC的设计则更侧重于硬件执行指令的功能 xff0c 使CISC的
  • 操作系统选择调度方式和算法的若干准则

    1 调度的类型 按调度的层次 xff1a 长期 xff08 长程 作业 高级 xff09 调度 xff1b 中期 xff08 中级 中程 xff09 调度 xff1b 短期 xff08 短程 进程 低级 xff09 调度 按OS 的类型 x
  • 提灯过桥问题

    题目 xff1a 小明一家过一座桥 xff0c 过桥时是黑夜 xff0c 所以必须有灯 现在小明过桥要1秒 xff0c 小明的弟弟要3秒 xff0c 小明的爸爸要6秒 xff0c 小明的妈妈要8秒 xff0c 小明的爷爷要12秒 每次此桥最
  • 如何判断一个整数数组中是否有重复元素

    题目 xff1a 写一个函数判断一个int类型的数组是否是有效的 所谓有效是指 xff1a 假设数组大小为n xff0c 那么这个int数组里的值为0 n 1之间的数 xff0c 并且每个数只能出现一次 xff0c 否则就是无效数组 例如
  • C++发送HTTP请求---亲测可行

    转自 xff1a http hi baidu com benbearlove item 1671c23017575825b3c0c53f 环境 xp sp3 vs2008 vs2010在静态库中使用 MFC include lt afxwi
  • 百度2014开发测试工程师笔试题(沈阳站)

    时间 xff1a 2013 9 21 地点 xff1a 沈阳 职位 xff1a 开发测试工程师
  • 2014百度校招开发测试工程师笔试题

    时间 xff1a 2013 9 28 地点 xff1a 深圳 职位 xff1a 开发测试工程师
  • 整体了解HADOOP框架及一些开源项目

    Hadoop框架中 xff0c 有很多优秀的工具 xff0c 帮助我们解决工作中的问题 Hadoop的位置 从上图可以看出 xff0c 越往右 xff0c 实时性越高 xff0c 越往上 xff0c 涉及到算法等越多 越往上 xff0c 越
  • Kafka简介

    Kafka简介 在当前的大数据时代 xff0c 第一个挑战是海量数据的收集 xff0c 另一个就是这些数据的分析 数据分析的类型通常有用户行为数据 应用性能跟踪数据 活动数据日志 事件消息等 消息发布机制用于连接各种应用并在它们之间路由消息
  • Flume入门笔记------架构以及应用介绍

    在具体介绍本文内容之前 xff0c 先给大家看一下Hadoop业务的整体开发流程 xff1a 从Hadoop的业务开发流程图中可以看出 xff0c 在大数据的业务处理过程中 xff0c 对于数据的采集是十分重要的一步 xff0c 也是不可避
  • 分布式服务框架dubbo原理解析

    alibaba有好几个分布式框架 xff0c 主要有 xff1a 进行远程调用 类似于RMI的这种远程调用 的 dubbo hsf xff0c jms消息服务 napoli notify xff0c KV数据库 tair 等 这个框架 工具
  • Linux下安装ElasticSearch

    Linux下安装ElasticSearch 一 下载 amp 安装二 安装中遇到的问题及解决方案三 使用中遇到的问题及解决方案四 安装head五 安装kibana 一 下载 amp 安装 先安装JDK 下载elasticsearch 7 0
  • cmake学习1:基本的CMakeLists的编写

    前言 自己在使用cmake进行编译工程的时候不太了解cmake的基本使用方法 有时候出现找不到第三方库的问题也不知如何排查 因此相对cmake有个稍微系统的认识 希望能用这个强大的工具来更好的为自己的工程服务 因此总结为了几篇博客 主要参考
  • ZooKeeper 报错 ERROR [main:ZooKeeperServerMain@64] 的解决办法

    myid span class hljs type ERROR span main span class hljs type ZooKeeperServerMain span 64 span class hljs number 64 spa
  • Ubuntu14.04下安装cmake 3.9.6

    简述 xff1a CMake是一个跨平台 的编译自动配置 工具 xff0c 它使用一个名为CMakeLists txt 的文件来描述构建过程 xff0c 可以产生标准的构建文件 它可以用简单的语句来描述所有平台的安装 编译过程 它能够输出各
  • 二维数组功能测试,超详细

    include lt stdio h gt int main char buf 2 5 61 39 a 39 39 b 39 39 c 39 39 d 39 39 e 39 39 f 39 39 g 39 39 h 39 39 i 39 3
  • Cmake知识----编写CMakeLists.txt文件编译C/C++程序

    简述 xff1a CMake是一个跨平台的安装 编译 工具 可以用简单的语句来描述所有平台的安装 编译过程 他能够输出各种各样的makefile或者project文件 能测试编译器所支持的C 43 43 特性 类似UNIX下的automak
  • 知识点总结:Java核心技术(卷1)

    Java核心技术 xff08 卷1 xff09 一 基础概念 1 1 基本程序设计结构 1 1 数据类型 1 1 1 数值类型 1 从java7开始 xff0c 加上前缀0b或0B就可以写二进制 xff1b 2 指数的表示 十进制中以10为
  • 单片机-控制-直流电机-基于L9110S-、L298N、TB6612FNG驱动

    直流电机 xff08 direct current machine xff09 能将直流电能转换成机械能 xff08 直流电动机 xff09 或将机械能转换成直流电能 xff08 直流发电机 xff09 的旋转电机 它是能实现直流电能和机械
  • 【一文弄懂】张正友标定法-完整学习笔记-从原理到实战

    张正友标定法 完整学习笔记 从原理到实战 文章目录 张正友标定法 完整学习笔记 从原理到实战 xff08 零 xff09 前言 xff1a 1 为什么需要标定 xff1f 2 相机标定的已知条件和待求解是什么 xff1f 标定前的已知条件