在上篇文章——系列篇|结构光三维重建基本原理中,笔者介绍了单目结构光三维成像系统把投影仪“看成”相机的模型。基于这个模型,单目结构光三维成像系统可以像双目三维成像系统那样来获取空间中物体的三维信息。不过,要真正计算出物体的三维解,需要对单目结构光系统进行精确的标定。
当把投影仪“看成”相机时,单目结构光系统需要计算的标定参数和双目成像系统类似,分别是相机的内参矩阵Kc和投影仪的内参矩阵Kp,以及相机和投影仪之间的外参矩阵:旋转矩阵R和平移矩阵T。此外,由于相机和投影仪的镜头都不可避免的存在畸变,我们还需要标定出相机和投影仪的畸变系数dc和dp。
同样地,我们可以像标定双目成像系统那样标定单目结构光系统。根据张正友标定法,我们可以用棋盘格标定板标定出相机的内参矩阵和畸变系数。同理,如果我们能够知道标定板在投影仪下的“成像”,我们就可以像标定相机那样求出投影仪的内参矩阵和畸变系数。如果能够知道标定板在相机和投影仪中同时成像的位置,我们就可以对相机和投影仪进行双目标定计算,求得投影仪和相机之间的外参矩阵R和T。
由于张正友标定法及双目标定计算在网上的资料有很多,笔者就不在这里赘述。在这篇文章中,笔者将详细介绍如何准确获取标定板在投影仪下的“成像”,从而精确的标定出投影仪的参数。
投影仪是无法直接“看”到三维空间中的标定板的,更不要说提取棋盘格标定板的角点。所以要完成投影仪的标定,我们还是要依赖于相机。首先,我们用相机拍摄空间中的棋盘格标定板,并提取出拍摄到的棋盘格标定板的角点,然后,我们需要使用投影仪把编码后的光依序投射在棋盘格标定板上,并对相机图片拍摄的投影仪的光编码进行解码。最后,我们要找到相机图片中棋盘格标定板的角点所对应的投影仪“图片”中的像素。这样就可以使投影仪“看到”标定板,或者说看到标定板上有效的特征点(角点)。
在上述过程中,找棋盘格角点本来就是相机标定必须经历的步骤,光的编码和解码方式也有很多,原则上可以使用任何光编码,包括格雷码,相移,多频外差,甚至彩色光编码等。只要能保证编码和解码的准确性都可。重要的是,如何使得投影仪能够精确“看到”棋盘格标定板上的角点,或者说如何保证相机图片中获取的角点到投影仪“看到”的角点的映射的准确性。
通过对相机的每个像素进行光解码,我们可以得到每个相机像素点对应的投影仪像素点。最简单的想法是,直接把相机棋盘格图片上每个角点对应的相机像素点直接对应到其解出的投影仪编码位置上。然而这样做通常无法得到棋盘格角点在投影仪图片上的准确映射,原因如下:
1)我们相机上找到的特征点(棋盘格角点)通常是亚像素级的,而解码只能得到相机图片上每个像素对应的投影仪编码位置。
2)对于某些编码方法,如格雷码,只能对投影仪的每个像素进行编码,即解码后的精度也只能是像素级的。
3) 通常情况下,投影仪的分辨率会比相机低,这意味着,相机上相邻几行可能对应投影仪图片上同一行,相机上相邻几列可能对应投影仪图片上同一列。
4)对单个像素而言,解码可能存在误差或者解码结果是不确定的(即该点由于种种原因无法解码)。
如果刚好在角点位置处的解码被判断为不确定点,事实上这种情况非常有可能(稍后会介绍),会导致部分角点位置没有解码结果,从而不能被投影仪“看到”或者“看到”的角点误差特别大,导致标定结果误差很大甚至无法使用。
为了解决上述问题,布朗大学团队提出了一个简单易行的方案,通过对相机中看到的每个特征点(棋盘格角点)求局部单应性矩阵,再通过每个特征点(棋盘格角点)求到的局部单应性矩阵把相机图片上棋盘格角点映射到投影仪图片上,这样就可以得到棋盘格角点在投影仪图片上的准确成像位置,且每个角点在投影仪图片上的成像坐标是亚像素级的。
局部单应性矩阵求解示例图
如图所示,captured image 表示的是相机图片,projected image 表示的是假想的投影仪图片。利用相机图片中每个角点附近的像素点集及其对应的解码坐标,计算一个局部单应性矩阵H,然后把相机图片上的角点P与单应性矩阵相乘,就可以得到棋盘格角点在投影仪图片上的成像位置q。需要注意的是,我们要对一幅棋盘格图片上的每个角点都单独计算一个局部单应性矩阵H,如图中所示,如果棋盘格上有n个角点,则每幅棋盘格图像要计算n个局部单应性矩阵。
局部单应性矩阵的计算方式如下,对相机图片上一个角点,假设其在邻域上有m个像素存在有效的解码坐标,则利用这m个像素点集{p}及其对应的投影仪图片像素坐标集{q}(解码结果),我们可以建立如下方程:(p和q均为齐次坐标)
即找到一个3x3的矩阵H,使得这m个有效像素点p乘上H后和实际的解码坐标q的距离和最小。其实这个很好理解,就是找到一个矩阵,使得角点附近每个像素点p经过转换后和其实际在投影仪图片上的真实值q误差最小。这个H就是我们要计算的局部单应性矩阵。
关于棋盘格角点邻域的范围,笔者的建议是,适量,且不宜过少。过少的话,结果偏差过大,过大的话有可能你的邻域出了棋盘格标定板边界,如果存在一个点不和棋盘格标定板在同一个三维平面上却被用来计算单应性矩阵则会引入较大误差。有读者应该已经注意到,这里一直强调的是局部单应性矩阵,为什么不用全局单应性矩阵呢?即对整个标定板上的点计算一个单应性矩阵,然后拿每个角点乘同一个单应性矩阵不行吗?我们知道,像这种求最小H,越多合适的点引入计算其实结果越稳定。不过撇开计算量不说,也存在如下所述的不适宜只求一个全局单应性矩阵的原因。
简单来说,由于镜头畸变的存在,在三维空间中的不经过光心的直线在投影仪中的“成像”并不是一条直线,这种畸变导致的直线形变是非线性的。因此我们的标定不仅仅只是一个线性参数,我们要求得的标定结果中除了有投影仪内参矩阵(线性),还有一个很重要的参数是畸变系数,畸变系数是非线性的,而我们求的单应性矩阵H是一个线性变换。如果每个点都用同一个H变换,会无法保持角点成像本身排列的非线性特性,直接影响我们求得投影仪的畸变系数的准确性。
至此,我们就可以很轻易的标定投影仪了,因为投影仪可以准确“看到”空间中棋盘格标定板的角点,我们只需要把投影仪放到相机模型里进行参数求解就可以了。
在实际应用中,由于投影光容易受到外界环境影响,具体体现在光投射在黑色物体上容易显得过暗,而光投射在白色物体上就会显得很亮,棋盘格标定板因为其既有黑色格子又有白色格子,无法保证在同一投影仪光强下,同时满足黑色棋盘格区域和白色棋盘格区域的解码需求。实际上,黑色物体的光解码是结构光的挑战之一。棋盘格的这种特性,给实际的解码提出了比较大的挑战。在实际应用时,有些论文会主张蓝白棋盘格,并投影红光,来避开棋盘格黑色部分带来的挑战。更多的是使用黑底白圆的棋盘格,如下图所示,圆心附近的点是白色,很适合光解码,可以有效避开黑色带来的解码困难问题。
圆点棋盘格标定板示例
最后笔者在这里总结下单目结构光系统的标定步骤
步骤一:获取相机拍摄的标定板图片,保持标定板不动,依序投影结构光编码到标定板上
步骤二:找到标定板图片中的特征点坐标
步骤三:对相机拍摄到的投影结构光进行解码
步骤四:对每个找到的标定板图片中的特征点坐标求局部的单应性矩阵,并使用局部单应性矩阵计算出特征点在投影仪图片上的坐标
步骤五:改变标定板位姿,重复步骤一到步骤四
步骤六:重复步骤五至少三次,并利用找到的特征点在相机和投影仪中的坐标分别计算出相机内参矩阵和畸变系数,投影仪内参矩阵和畸变系数。
步骤七:利用找到的特征点在相机和投影仪中的坐标值进行双目标定计算,得到相机和投影仪之间的外参矩阵:旋转矩阵R和平移矩阵T。
本篇文章主要介绍的是布朗大学团队提供的方法,他们也提供了方法介绍的网站,且网站上有他们写标定源码供参考。
参考文献:Simple,Accurate,and Robust Projector-Camera Calibration。
代码链接:http://mesh.brown.edu/calibration/
小凡备注:本文作者为我们星球的特邀嘉宾,期待更多有识之士来稿,对于结构光系统的标定,也欢迎大家多多探讨,一起进步~
上述内容,如有侵犯版权,请联系作者,会自行删文。