在结构光三维重建中,最常见的方法就是相移法,相移是通过投影一系列相移光栅图像编码,从而得到物体表面一点在投影仪图片上的相对位置或者绝对位置。下面,笔者将详细介绍如何制作相移编码图片,以及如何对获取的相移图片进行解码,最后笔者将粗浅的谈谈相移相比其他方法(如格雷码)有什么优势。
常见的三步相移法公式如下所示:
其中
是相位图的灰度值,
是条纹光强的背景值,
为条纹光强的调制强度,
是相位主值。由于cos的取值范围是[-1,1],在制作编码图片的时候,我们可以把
和
都设置成127,这样就可以保证制作的相位图片的灰度值在0-255之间,以及一个高动态的范围。实际上由于投影仪投射出来的光的灰度值并不是线性变化的,为了消除这种非线性变化问题,有不少人提出了各种针对投影光的伽马矫正方法。如果精度要求不是特别严苛的话,投影仪投影的光在某个动态区间(通常是中间灰度值那一段,比如50-200的区间)会逼近于线性变化,我们也可以在制作图片的时候把动态区间调整至逼近线性变换区间的范围来消除这种非线性变化的干扰。
如下图所示,是用三步相移公式做的相移图片,为了更加清楚地描述,这里使用的是0-55的灰度值范围。
三步相移法示例图片
由之前我们知道,编码主要是为了标记投影仪的图片的实际位置,在相移中,我们用相位主值 编码投影仪图片的像素,对于某一个周期内的投影坐标,我们可以这样把相位主值换成其在周期内的实际坐标:
Pixel即该点在周期内的实际坐标,period即一个相位周期所占的像素列数,实际上,我们不可能仅用一个周期标记一整张相位图片,其实很正常,我们的图片列数常常是几百甚至上千,而灰度值的动态范围只有255, 所以我们通常会设计一个周期所占像素列数,如上图所示,一个相位周期占图片12列, 一张图片约有10个周期。想要知道某个相位解码点在投影图片的实际坐标,我们除了知道其相位主值,还需要知道其是第几个周期的相位。一个像素点的实际列坐标如下所示:
是相位所在的周期数(通常对第一个相位周期用0来编码),
的数值常用格雷码编码或者其他编码方法辅助得到。又可以根据相位展开后的主值在空域上的分布来求解其是第几个周期,不过这样通常不准。
把相移编码光投影到物体表面后,我们就可以解码了,如上面的方程所示,
是相机图片的灰度值,那么上述三个方程就只剩三个未知数,
三个方程解三个未知数在满秩的情况下一定是可解的,而且对于这三个未知数来说,我们其实只需要关心 ,相位主值的大小。解码公式如下所示:
如果
解成
,则需要把其换算到
区间。上述相移编码的解码结果如下图所示:
解码后的相位主值图
除了三步相移法,我们还可以设计四步甚至更多步相移法,具体编码和解码方式如下,对于N步相移法,我们需要N幅编码图片,对于第 ( )幅编码图片(通常我们用0标记第一幅图片), 其编码如下:
其对应的N步相移法的解码公式为:
如何选定相移步长呢? 一般来说,步长越多越精确和稳定,但是在实际的应用中,考虑到三维成像帧率等原因,用三步或四步像移方法的较多。如果不考虑帧率的话,在论文[1]中有提到,如果能使用饱和式的相移图片(saturated fringe patterns),即让相移步长 N等于一个相位周期编码列数的整数倍,如果编码列数是偶数m的话,相移步长N可以是 m/2 的整数倍,这样的话,解相移的时候对高反光表面相位主值也能解出比较好的结果。不过要对高反光表面的相移解码得到非常好的效果,相移步长N通常都要在10以上,对于追求速度的三维重建,可能没有那么吸引人。
最后,笔者想和大家聊聊相移法比起格雷码的优势,首先,相移可以看成连续变化的值,比如说我们解相位换算成像素点坐标的时候,通常可以达到小数级(亚像素级)的精度,如果我们用格雷码,在不使用插值的情况下,通常只能达到像素级的精度。为什么相移达到的亚像素级的精度是正确的呢?笔者个人认为和光本身就是一种正弦波有关,光打在物体表面上,会以正弦波的形式向周边散开,所以使用相移时得到的亚像素级的解码精度往往是比较准确的。此外,我们用的相移是时序,利用光的在时间中(不同投影图片下)的变化量来解码,相比格雷码用阈值二值化,受到物体纹理的影响会更小。比如相移光打在暗色物体上,可能解出来的 会比较小,但是不影响我们解出正确的相位主值 。
论文[1]:High-quality 3D shape measurement using saturated fringe patterns.
上述内容,如有侵犯版权,请联系作者,会自行删文。