【相机标定与三维重建原理及实现】学习笔记2——标定的算法与方法

前言

由于我目前正在研究使用数字图像相关技术来测量材料的变形方向,由于涉及到使用图像处理来参与测量或检测研究,所以不可避免的是空间中的任何一点建筑和摄像头捕捉到的图像是无法避免的。图像上点之间的数学关系和数学模型。之前有校准经验的我,只是简单的使用了别人打包的功能,现在仔细推导发现了其中的奥秘。我认为,如果你想在一项技术上进行创新,最重要的是能够把它学得透彻。希望记录下作为初学者学习和推导这个原理的过程,也方便大家涉足这个领域。人们可以更清晰、更快速地应用这些知识。

本文所写的内容主要参考《学习OpenCV 3 》1以及 大奥特曼打小怪兽大佬的博客第六节、双目视觉之相机标定2。但是本文的讲解思路会稍有不同,同时也会更偏向数学推导。如果本文对你的帮助不大,建议可以看一下提到的书籍与博客,可以提供一些不同角度的讲解。

本文的推导基于上一篇笔记【相机标定与三维重建原理及实现】学习笔记1——相机模型数学推导详解,建议先行阅读,上一篇笔记探讨了为什么要标定以及标定是在标定什么,本章节我希望探讨的有以下几个问题:

  1. 如何校准?
  2. 校准需要多少张校准图像?每个校准图像需要多少个特征点?

本栏目目录:

  1. 【相机标定与三维重建原理及实现】学习笔记1——相机模型数学推导详解
  2. 【相机标定与三维重建原理及实现】学习笔记2——标定的算法与方法

在最后一个注解中,我们知道标定的主要目的是建立相机图像的像素位置与物体空间位置的关系,即世界坐标系与像素坐标系的关系。在这些关系中需要求解的主要有两个模型:针孔成像模型和畸变模型,其中前者是线性的,后者是非线性的。首先我们看一下针孔成像模型的表达式的映射关系:
z_%7Bc%7D%5Cleft%5B%5Cbegin%7Barray%7D%7Bl%7D%20u%20%5C%5C%20v%20%5C%5C%201%20%5Cend%7Barray%7D%5Cright%5D%20%3D%5Cleft%5B%5Cbegin%7Barray%7D%7Bccc%7D%20f_%7Bx%7D%20%26%200%20%26%20c_%7Bx%7D%5C%5C%200%20%26f_%7By%7D%26%20c_%7By%7D%5C%5C%200%20%26%200%20%26%201%20%5Cend%7Barray%7D%5Cright%5D%5Cleft%5B%5Cbegin%7Barray%7D%7Bcccc%7D%20R%20%26%20t%20%5C%5C%200_%7B3%7D%5E%7BT%7D%20%26%201%20%5Cend%7Barray%7D%5Cright%5D%5Cleft%5B%5Cbegin%7Barray%7D%7Bc%7D%20x_%7Bw%7D%20%5C%5C%20x_%7Bw%7D%20%5C%5C%20z_%7Bw%7D%20%5C%5C%201%20%5Cend%7Barray%7D%5Cright%5D 其中

  • u%2Cv表示像素坐标系中的坐标
  • f_%7Bx%7D%3Df%20%5Ccdot%20s_%7Bx%7D%EF%BC%8Cf_%7By%7D%3Df%20%5Ccdot%20s_%7By%7D是两个合起来的量,表示相机系统的焦距乘以对应方向单位尺寸的像素数的结果
  • R表示从世界坐标系到相机坐标系的旋转矩阵,实际上只包含三个未知数,即坐标系绕三个轴的旋转角度
  • t表示从世界坐标系到相机坐标系的平移向量,包括三个未知数
  • x_%7Bw%7D%2Cx_%7Bw%7D%2Cz_%7Bw%7D表示对应物点在世界坐标系中的坐标位置
  • z_%7Bc%7D表示物点在相机坐标系下的Z方向坐标值,其具体数值可以从%5Cleft%5B%5Cbegin%7Barray%7D%7Bcccc%7D%20R%20%26%20t%20%5C%5C%200_%7B3%7D%5E%7BT%7D%20%26%201%20%5Cend%7Barray%7D%5Cright%5D%5Cleft%5B%5Cbegin%7Barray%7D%7Bc%7D%20x_%7Bw%7D%20%5C%5C%20x_%7Bw%7D%20%5C%5C%20z_%7Bw%7D%20%5C%5C%201%20%5Cend%7Barray%7D%5Cright%5D中提取出来,是一个中间变量

在计算机视觉中,这种从一个平面到另一个平面的投影映射称为单应性。我们稍微改写一下上面的公式,把z_%7Bc%7D移到方程的右边,设置它的倒数为s%3D1/z_%7Bc%7D,设置相机系统的内参矩阵为M%3D%5Cleft%5B%5Cbegin%7Barray%7D%7Bccc%7D%20f_%7Bx%7D%20%26%200%20%26%20c_%7Bx%7D%5C%5C%200%20%26f_%7By%7D%26%20c_%7By%7D%5C%5C%200%20%26%200%20%26%201%20%5Cend%7Barray%7D%5Cright%5D,外参矩阵为W%3D%5Cleft%5B%5Cbegin%7Barray%7D%7Bcccc%7D%20R%20%26%20t%20%5C%5C%200_%7B3%7D%5E%7BT%7D%20%26%201%20%5Cend%7Barray%7D%5Cright%5D,那么我们可以得到修改后的公式:
%5Cleft%5B%5Cbegin%7Barray%7D%7Bl%7D%20u%20%5C%5C%20v%20%5C%5C%201%20%5Cend%7Barray%7D%5Cright%5D%3Ds%5Ccdot%20M%5Ccdot%20W%5Cleft%5B%5Cbegin%7Barray%7D%7Bc%7D%20x_%7Bw%7D%20%5C%5C%20x_%7Bw%7D%20%5C%5C%20z_%7Bw%7D%20%5C%5C%201%20%5Cend%7Barray%7D%5Cright%5D设矩阵H%3DM%5Ccdot%20W,则有:
%5Cleft%5B%5Cbegin%7Barray%7D%7Bl%7D%20u%20%5C%5C%20v%20%5C%5C%201%20%5Cend%7Barray%7D%5Cright%5D%3Ds%5Ccdot%20H%5Cleft%5B%5Cbegin%7Barray%7D%7Bc%7D%20x_%7Bw%7D%20%5C%5C%20x_%7Bw%7D%20%5C%5C%20z_%7Bw%7D%20%5C%5C%201%20%5Cend%7Barray%7D%5Cright%5D其中H又被称为单应性矩阵,表达了两个坐标系之间的映射关系,而s是H里面可以分解得到的一个变量(上面提到了z_%7Bc%7D是一个中间变量,因此是可以从H中提取的)。写成这样的形式,我想很容易就可以看出,这不就是个形如线性方程组的形式嘛!!那按照求解线性方程组的方式,只要知道足够多的相互对应的物点和像点,就可以构建大于等于未知量数目的方程组,这不就可以求解未知量了嘛!

其实标定就是通过这种方式得到图像与世界的映射关系,但是这个公式其实是一个非线性方程组(因为s的存在),如果要求解映射关系中的未知数需要使用非线性最小二乘法来找到一组最优解,以最小化目标函数(误差平方和)。在这个问题中,目标函数可以写成:
%5Csum_%7Bi%3D1%7D%5E%7Bn%7D%5Csum_%7Bj%3D1%7D%5E%7Bm%7D%5Cleft%20%5C%7C%20%5Cmathbf%7Bm%7D_%7Bij%7D-%20s%5Ccdot%20H%5Ccdot%5Cmathbf%7Bw%7D_%7Bij%7D%5Cright%20%5C%7C%5E%7B2%7D其中%5Cmathbf%7Bm%7D_%7Bij%7D表征了上述式子中的像点%5Cleft%5B%5Cbegin%7Barray%7D%7Bl%7Du%20%5C%5Cv%20%5C%5C1%5Cend%7Barray%7D%5Cright%5D%5Cmathbf%7Bw%7D_%7Bij%7D表征了上述式子中的物点%5Cleft%5B%5Cbegin%7Barray%7D%7Bc%7D%20x_%7Bw%7D%20%5C%5C%20x_%7Bw%7D%20%5C%5C%20z_%7Bw%7D%20%5C%5C%201%20%5Cend%7Barray%7D%5Cright%5D,整个式子的物理意义即计算三维空间中的点%5Cmathbf%7Bw%7D_%7Bij%7D经过坐标映射投影回图像后的坐标与实际图像上提取的点%5Cmathbf%7Bm%7D_%7Bij%7D的坐标之间的2-范数(即两点间的距离),数值越小则表明误差越小、效果越好。以这个目标函数为准则,利用非线性最小二乘即可求解出最优的单应性矩阵H。而这正是标定的算法核心,但照这样直接去做标定存在两个问题:

  1. 如何测量被摄物点在世界坐标系中的坐标?
  2. 目标函数包含很多未知数,当初始值不好时(例如像点的特征提取效果较差或目标点的测量误差较大),很容易陷入局部最优。

张正友提出的使用校准板进行校准的方法(拜拜!)在很大程度上解决了这两个问题。

一.张氏标定法

“张氏标定”是指张正友教授于1998年提出的单平面棋盘格的摄像机标定方法。张氏标定法已经作为工具箱或封装好的函数被广泛应用。张氏标定的原文为“A Flexible New Technique forCamera Calibration”3。张正友大佬的这个方法其实听起来会觉得非常简单,他的方法有两个核心,第一,使用如下图所示的棋盘格标定板方便提取像点和衡量物点;第二,默认标定板平面为世界坐标系中z%3D0的平面。然后通过拍拍摄若干张这样的图片,计算出不同标定板姿态下的单应性矩阵,再利用多组单应性矩阵构成的超定方程组求解内参和外参。
【相机标定与三维重建原理及实现】学习笔记2——标定的算法与方法
这样,标记便于从图像中获取特征点;其次,将标定板视为z%3D0的平面,只需知道特征点的打印距离(算法中特征点之一从四个角中提取出来的通常作为世界坐标系的原点);最后,由于所有物点都位于z%3D0平面上,目标函数的优化量大大减少。映射公式可以改写为:
%5Cbegin%7Baligned%7D%5Cleft%5B%5Cbegin%7Barray%7D%7Bl%7D%20u%20%5C%5C%20v%20%5C%5C%201%20%5Cend%7Barray%7D%5Cright%5D%26%3Ds%5Ccdot%20M%5Ccdot%20W%5Cleft%5B%5Cbegin%7Barray%7D%7Bc%7D%20x_%7Bw%7D%20%5C%5C%20x_%7Bw%7D%20%5C%5C%20z_%7Bw%7D%20%5C%5C%201%20%5Cend%7Barray%7D%5Cright%5D%5C%5C%26%3Ds%5Ccdot%20M%5Ccdot%5Cbegin%7Bbmatrix%7D%20%5Cmathbf%7Br%7D_%7B1%7D%20%26%20%5Cmathbf%7Br%7D_%7B2%7D%20%26%20%5Cmathbf%7Br%7D_%7B3%7D%20%26%20%5Cmathbf%7Bt%7D%20%5Cend%7Bbmatrix%7D%20%5Cleft%5B%5Cbegin%7Barray%7D%7Bc%7D%20x_%7Bw%7D%20%5C%5C%20x_%7Bw%7D%20%5C%5C%200%20%5C%5C%201%20%5Cend%7Barray%7D%5Cright%5D%20%5C%5C%20%26%3Ds%5Ccdot%20M%5Ccdot%5Cbegin%7Bbmatrix%7D%20%5Cmathbf%7Br%7D_%7B1%7D%20%26%20%5Cmathbf%7Br%7D_%7B2%7D%20%26%20%5Cmathbf%7Bt%7D%20%5Cend%7Bbmatrix%7D%20%5Cleft%5B%5Cbegin%7Barray%7D%7Bc%7D%20x_%7Bw%7D%20%5C%5C%20x_%7Bw%7D%20%5C%5C%201%20%5Cend%7Barray%7D%5Cright%5D%20%5Cend%7Baligned%7D此时的H%3DM%5Ccdot%5Cbegin%7Bbmatrix%7D%20%5Cmathbf%7Br%7D_%7B1%7D%20%26%20%5Cmathbf%7Br%7D_%7B2%7D%20%26%20%5Cmathbf%7Bt%7D%20%5Cend%7Bbmatrix%7D为一个3X3的矩阵,计算量相比于之前减少了很多。而正是这样的设计大大减少了算法的耗时并且提升了标定的鲁棒性!接下来我们需要探讨使用张氏标定法究竟需要拍多少张这样的图片以及标定板上究竟需要多少个特征点。

二.张氏标定需要的特征点数以及拍摄图片数

总结张氏标定法的算法思想,可以得到如图所示的流程示意图。当使用单个标定图像时,我们可以在有足够的特征点时计算当前标定板的姿态(外参)。的情况下的单应矩阵H,所以我们需要在不同的标定板位姿下拍摄图像。也就是说,对于标定板的特征点数和张氏标定法拍摄的图片数量,可以得出以下结论:

  • 单个标定板图像:讨论计算单应矩阵所需的特征点数H
  • 多个标定板图像:讨论有多少个不同的单应矩阵H(即需要拍摄的图像数量),并可以建立一个方程组来求解内部参数

【相机标定与三维重建原理及实现】学习笔记2——标定的算法与方法

1.所需特征点数

首先,我们看一下求解H所需的特征点数
H%3D%5Cbegin%7Bbmatrix%7D%20%5Cmathbf%7Bh%7D_%7B1%7D%20%26%20%5Cmathbf%7Bh%7D_%7B2%7D%20%26%20%5Cmathbf%7Bh%7D_%7B1%7D%20%5Cend%7Bbmatrix%7D%3DM%5Ccdot%5Cbegin%7Bbmatrix%7D%20%5Cmathbf%7Br%7D_%7B1%7D%20%26%20%5Cmathbf%7Br%7D_%7B2%7D%20%26%20%5Cmathbf%7Bt%7D%20%5Cend%7Bbmatrix%7D%20%3D%5Cleft%5B%5Cbegin%7Barray%7D%7Bccc%7D%20f_%7Bx%7D%20%26%200%20%26%20c_%7Bx%7D%5C%5C%200%20%26f_%7By%7D%26%20c_%7By%7D%5C%5C%200%20%26%200%20%26%201%20%5Cend%7Barray%7D%5Cright%5D%5Cbegin%7Bbmatrix%7D%20%5Cmathbf%7Br%7D_%7B1%7D%20%26%20%5Cmathbf%7Br%7D_%7B2%7D%20%26%20%5Cmathbf%7Bt%7D%20%5Cend%7Bbmatrix%7DH是一个3×3的矩阵,但由于其中内参矩阵是以齐次坐标的形式进行的表达,因此H当中实际只有8个未知量待求解,图像是一个二维的点,一个点包含了%28u%2Cv%29两个方向的坐标值,即可以输出2个方程。因此如果需要求解一副图像的所对应的当前标定板到图像像素的坐标映射关系H,至少需要有四个特征点(8个方程)被提取到。当然,实际标定当中还是希望有更多的特征点,可以有更多的方程从而构建超定方程组,冗余帮助标定的的鲁棒性更强,但是注意它们最多也只能提取到8个参数,而一个单应性矩阵H实际是有6个外参+4个内参组合而成(10个未知量),因此一副图像即使得到特征点数再多也无法解算得到相机的内参。

在OpenCV当中有封装好的函数来通过非线性最小二乘法计算得到单张标定板图像所对应的单应性矩阵。

Mat cv::findHomography	(	InputArray 	srcPoints,
							InputArray 	dstPoints,
							int 	method = 0,
							double 	ransacReprojThreshold = 3,
							OutputArray 	mask = noArray(),
							const int 	maxIters = 2000,
							const double 	confidence = 0.995 
						)	

2.所需拍摄的标定板图像数

如果只想知道结果,那可以明确的说,使用张氏标定至少需要的标定板图像为3张,我这边实际测试的结果8张以上的标定板图像结果和误差才会趋于稳定,因此建议实际标定时使用10张及以上的标定板图像进行标定。

但在这里我还是想从数学推导的角度说明一下,为什么至少需要3张标定图像?这部分内容在《学习OpenCV 3》1中也可以找到。首先我们在上一节中提到了,计算一个单应性矩阵H至少需要提供4个特征点(8个方程)来计算得到H中的8个参数,而一个H是由6个外部参数+4个内部参数组合而成。每多一副标定板图像会引入6个新的外部参数,因此很容易得到对于每次参与计算H的8个方程,实际只提供了两个约束用于求解那4个固有的内部参数。那我们来看如何从单应性矩阵H求解得到4个内参

对于H%5Cbegin%7Bbmatrix%7D%20%5Cmathbf%7Bh%7D_%7B1%7D%20%26%20%5Cmathbf%7Bh%7D_%7B2%7D%20%26%20%5Cmathbf%7Bh%7D_%7B1%7D%20%5Cend%7Bbmatrix%7D%3DM%5Ccdot%5Cbegin%7Bbmatrix%7D%20%5Cmathbf%7Br%7D_%7B1%7D%20%26%20%5Cmathbf%7Br%7D_%7B2%7D%20%26%20%5Cmathbf%7Bt%7D%20%5Cend%7Bbmatrix%7D,根据前面注释的内容,我们可以知道外参旋转矩阵中的列向量相互正交且模相等,即:

(王婆卖瓜)这里用了范数的符号,如果你对范数有兴趣了解的话,可以阅读我的这篇博客【数值分析】学习笔记1——范数与条件数

%5Cleft%5C%7B%5Cbegin%7Bmatrix%7D%20%5Cmathbf%7Br%7D_%7B1%7D%20%5E%7BT%7D%5Ccdot%20%5Cmathbf%7Br%7D_%7B2%7D%3D0%5C%5C%5C%5C%20%5Cleft%20%5C%7C%20%5Cmathbf%7Br%7D_%7B1%7D%20%5Cright%20%5C%7C%20%3D%5Cleft%20%5C%7C%20%5Cmathbf%7Br%7D_%7B1%7D%20%5Cright%20%5C%7C%20%5Cend%7Bmatrix%7D%5Cright. 根据H的方程和表达式,我们可以得到两个约束:
%5Cleft%5C%7B%5Cbegin%7Bmatrix%7D%20%5Cmathbf%7Bh%7D_%7B1%7D%20%5E%7BT%7D%5Ccdot%20M%5E%7B-T%7DM%5E%7B-1%7D%5Ccdot%5Cmathbf%7Bh%7D_%7B2%7D%3D0%5C%5C%5C%5C%20%5Cmathbf%7Bh%7D_%7B1%7D%20%5E%7BT%7D%5Ccdot%20M%5E%7B-T%7DM%5E%7B-1%7D%5Ccdot%5Cmathbf%7Bh%7D_%7B1%7D%3D%5Cmathbf%7Bh%7D_%7B2%7D%20%5E%7BT%7D%5Ccdot%20M%5E%7B-T%7DM%5E%7B-1%7D%5Ccdot%5Cmathbf%7Bh%7D_%7B2%7D%20%5Cend%7Bmatrix%7D%5Cright.假设B%3DM%5E%7B-T%7DM%5E%7B-1%7D,我们可以将其展开为:
【相机标定与三维重建原理及实现】学习笔记2——标定的算法与方法
可以看出B是一个3×3的对称矩阵,因此只需要求出其中的6个元素即可,设主对角线上方的这6个元素为向量%5Cmathbf%7Bb%7D,则可以将刚刚约束中的式子转换为如下的形式:
%5Cbegin%7Baligned%7D%20%5Cmathbf%7Bh%7D_%7Bi%7D%20%5E%7BT%7D%5Ccdot%20B%5Ccdot%5Cmathbf%7Bh%7D_%7Bj%7D%26%3D%5Cmathbf%7Bv%7D_%7Bi%2Cj%7D%5E%7BT%7D%5Ccdot%5Cmathbf%7Bb%7D%5C%5C%20%26%3D%5Cleft%5Bh_%7Bi%2C%201%7D%20h_%7Bj%2C%201%7D%5Cleft%28h_%7Bi%2C%201%7D%20h_%7Bj%2C%202%7D%2Bh_%7Bi%2C%202%7D%20h_%7Bj%2C%201%7D%5Cright%29%20h_%7Bi%2C%202%7D%20h_%7Bj%2C%202%7D%5Cleft%28h_%7Bi%2C%203%7D%20h_%7Bj%2C%201%7D%2Bh_%7Bi%2C%201%7D%20h_%7Bj%2C%203%7D%5Cright%29%5Cleft%28h_%7Bi%2C%203%7D%20h_%7Bj%2C%202%7D%2Bh_%7Bi%2C%202%7D%20h_%7Bj%2C%203%7D%5Cright%29%20h_%7Bi%2C%203%7D%20h_%7Bj%2C%203%7D%5Cright%5D%5Ccdot%5Cmathbf%7Bb%7D%20%5Cend%7Baligned%7D 因此这两个约束也可以写成:
%5Cbegin%7Bbmatrix%7D%20%5Cmathbf%7Bv%7D_%7B1%2C2%7D%5E%7BT%7D%5C%5C%20%28%5Cmathbf%7Bv%7D_%7B1%2C1%7D-%5Cmathbf%7Bv%7D_%7B2%2C2%7D%29%5E%7BT%7D%20%5Cend%7Bbmatrix%7D%5Ccdot%20%5Cmathbf%7Bb%7D%3D0即一个包含两个方程的线性方程组,而每一幅图像可以提供一个新的这样的方程组,因此至少需要3张标定板图像(6个方程),才可以求解出%5Cmathbf%7Bb%7D中的6个未知量,从而计算得到4个摄像机系统的内参!

对于求解相机的内参,在OpenCV中同样有有封装好的函数

double cv::calibrateCamera	(	InputArrayOfArrays 	objectPoints,
								InputArrayOfArrays 	imagePoints,
								Size 	imageSize,
								InputOutputArray 	cameraMatrix,
								InputOutputArray 	distCoeffs,
								OutputArrayOfArrays 	rvecs,
								OutputArrayOfArrays 	tvecs,
								OutputArray 	stdDeviationsIntrinsics,
								OutputArray 	stdDeviationsExtrinsics,
								OutputArray 	perViewErrors,
								int 	flags = 0,
								TermCriteria 	criteria = TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, DBL_EPSILON) 
							)	

三.标定中的其他注意事项

上面的内容从数学的角度介绍了标定是如何求解得到相机系统针孔成像模型中的各项参数,而对于畸变模型的求解在此就不过多赘述了,可以参照”close range camera calibration”4这篇文章,这也是OpenCV的标定函数所采用的畸变参数求解算法。但这里还是要提几个关键点

  • 标定板的位置尽量放遍整幅图像(畸变校正的鲁棒性只有在特征点覆盖整个视场的情况下才会好)
  • 标定时尽量使用辅助光源,保证标定平面亮度均匀。太暗和过度曝光会导致特征点提取不准确。
  • 标定板的加工精度(特征点间距)和表面平整度对标定有很大影响。我做的校准板和我用钱做的校准板的重投影误差相差三倍以上。
  • 尽量保证标定板的姿态多一点,不要总是在平面上移动(否则生成的单应矩阵容易耦合,标定结果的鲁棒性较差)

题外话:手眼标定能不能和相机内参标定一起做的问题
思考:从算术推导来看,手眼标定和相机标定可以同时在一个标定中完成,但是我接触过的很多情况下,眼睛在手上还是眼睛在不在手边,我倾向于分别做这两个。 ,我觉得主要原因是如果要保证相机标定的质量,机械臂驱动相机或者标定板,运动范围比较有限,很多关节位置都达不到,这会导致手眼校准。从相机坐标系到机械臂坐标系的外参鲁棒性较差,单独做是比较好的选择。

参考

凯勒, 布拉德斯基, 刘昌祥, 吴雨培, and 王成龙. 学习OpenCV 3 中文版. 北京: 清华大学出版社, 2018.↩︎↩︎第六节、双目视觉之相机标定↩︎Zhang Z. A flexible new technique for camera calibration[J]. IEEE Transactions on pattern analysis and machine intelligence, 2000, 22(11): 1330-1334.↩︎Duane C B. Close-range camera calibration[J]. Photogramm. Eng, 1971, 37(8): 855-866.↩︎

版权声明:本文为博主ViolentElder原创文章,版权归属原作者,如果侵权,请联系我们删除!

原文链接:https://blog.csdn.net/weixin_43560489/article/details/123170605

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
青葱年少的头像青葱年少普通用户
上一篇 2022年3月2日
下一篇 2022年3月2日

相关推荐