2.2 双目相机

在自然界中,绝大部分动物有两只眼睛,有的甚至更多,但没有只有一只眼睛的动物,这是生物经过长期的生存竞争和进化之后的结果。因为两只眼睛观察世界的角度不同,所以看到的场景会有微小的差别,大脑接收到这种差别后,通过中枢神经系统的分析处理,可以判断物体的远近,因此感知到的世界就会是立体的,所以用双眼观察到的信息会更加精细和准确。

随着图像处理技术和计算机视觉技术的发展,2D的图像信息已经不能满足需求,人们希望计算机拥有获取物体3D特征的能力,于是双目相机应运而生。双目测距法是一种被动测距方法,双目相机获取图像的过程就是简单的拍照过程,因此成本较低。

2.2.1 双目相机原理

一个典型的双目相机由一组(2个)摄像头和计算机处理模块组成,双目测距法是由左右相机拍摄不同角度的场景,将其传输到计算机中,由计算机处理模块计算对应的视差,进而得到深度值的测距方法。如图2.2-1所示为具有视差的两幅图像的叠加图。空间中某一点的双目视差为该点在左右图像中位置的差别,双目视觉基于图像处理技术,通过立体匹配获得空间中的点在两幅图像中的对应点,进而得到空间点的视差。

图2.2-1 具有视差的两幅图像的叠加

双目相机感知深度的能力是形成立体视觉的基础,这种能力是由“视差”提供的,换句话说,视差是实现立体视觉的条件。例如,当我们用一只眼睛去观察周围时,虽然在大部分时候并不会有什么问题,但穿针引线等细活往往很难完成,因为此时没有视差存在,所以我们无法获得准确的距离信息。

那么双目相机是如何利用视差感知深度的呢?这要从双目的成像过程[1]说起。如图2.2-2所示为双目立体视觉原理图,两相机镜头的间距(基线)为b,对于人眼的双目系统,基线距即为双眼眼球的距离;相机坐标系的原点O位于相机镜头的光心;左右图像坐标系的原点为相机光轴与像平面的交点O1O2

图2.2-2 双目立体视觉原理图

实际上,相机的成像平面在镜头后f处(f为相机焦距),为便于理解,在图中将成像平面绘制在镜头前f处。选取世界坐标系与左相机坐标系重合,空间中一点Pxcyczc)在左右图像中相应的坐标分别为P1u1v1)和P2u2v2)。左右相机坐标系x轴及左右图像坐标系的u轴分别重合,且相机坐标系的x轴与图像坐标系的u轴平行,那么由几何约束关系可知,P1P2O1O2平行,于是点P1和点P2v坐标相同,即v1=v2

由图2.2-2中的空间几何关系得到点P的3D空间坐标与2D像素坐标之间的关系:

其中,f为相机焦距,(xcyczc)为点P在左相机坐标系(世界坐标系)中的坐标,P1P2在对应图像中像素位置的差别(P点的视差)为

由公式(2.2.1)与公式(2.2.2)可得点P的坐标表达式为

公式(2.2.3)中的未知量仅有视差d,所以只要得到P点的视差,就可以求出其空间坐标。利用视差计算深度的过程称为“三角化”。

但是在以上的推导过程中出现的视差都是图像坐标系中的视差,是以实际距离为单位的,如mm、cm等。但是在一张图片中,我们只能知道一个像素在第几行、第几列,也就是只知道其在像素坐标系中的位置,因此基于图像得到的视差也只能以像素的个数为单位。那么如何实现以像素为单位的视差与以实际距离为单位的视差的转换呢?这就涉及图像坐标系和像素坐标系的变换。

图像坐标系和像素坐标系的位置关系如图2.2-3所示。图像坐标系为OI-uv,像素坐标系为OP-xy。两者的原点不重合:像素坐标系的原点一般在最终形成的图像的左上角处,图像坐标系的原点在像素坐标系中的坐标为(x0y0)。此外,由于相机感光器件的分辨率一定,所以两者的坐标变换为线性的。

图2.2-3 图像坐标系和像素坐标系的位置关系

图像坐标系中的点(u,v)和像素坐标系中的点(x,y)的对应关系为

其中,(x0y0)为图像坐标系的原点在像素坐标系中的坐标,PxPy为相机感光器件在单位长度内包含的像素个数,单位为“pixel/length”,如在Nikon D610相机中,Px=0.168pixel/μm,Py=0.167pixel/μm。

为了得到某一点在像素坐标系中的视差,首先需要进行立体匹配,即得到空间中的点在左右图像中的对应位置。人眼的匹配在观看场景物体的同时自然发生,以至于我们根本不会意识到此过程;但双目相机与人眼不同,需要经过专门的立体匹配过程才可得到左右两幅图像中的对应点。双目立体匹配是双目视觉领域最复杂的问题,将在2.2.2节重点介绍。

2.2.2 立体匹配方法

立体匹配是双目立体视觉中最困难也是最关键的步骤,其效果直接决定了重建结果的好坏,目前国内外在双目立体匹配方面已积累了大量研究成果,提出了很多立体匹配算法。根据算法运行时匹配约束的作用范围,可将其分为局部立体匹配算法、全局立体匹配算法和半全局立体匹配算法。其中,局部立体匹配算法计算量较小、运行速度较快,能满足实时性要求,但是匹配精度无法保证;全局立体匹配算法准确性较高,但是计算速度慢,不适合实时运行;半全局立体匹配算法在匹配效果和复杂度方面性能居中。

2.2.2.1 局部(Local)立体匹配算法

局部立体匹配算法又称为基于窗口或基于支持区域的立体匹配算法,如图2.2-4所示,该算法独立地对左图像中的每个像素设定一个合适大小的窗口,然后依据一定的相似度测量准则,在右图像中寻找与此窗口最相似的子窗口,该子窗口所对应的像素即为匹配点[2]

图2.2-4 局部立体匹配算法

由于双目相机得到的图像具有2.2.1节中所述的“P1P2(匹配点)的v坐标相同”的约束,所以匹配点一定是同一行的像素点;且右图像的拍摄位置偏右,所以同一空间点在右图像中的对应点一定会偏左;此外,寻优过程一般会设置一个最大搜索范围maxoffset。对于左图像的每一像素,从右图像的同一位置开始,计算同一行内左侧maxoffset个像素的相似程度,并从中寻找最相似的像素作为匹配点,匹配点与初始搜索位置的距离就是视差。

但是现在得到的视差是以像素为单位的,可利用2.2.1节中的公式(2.2.4),得到以实际距离为单位的视差。

常用的相似度测量准则有灰度差的绝对值和(Sum of Absolute Differences,SAD)、灰度差的平方和(Sum of Squared Differences,SSD)、归一化交叉相关(Normalized Cross Correlation,NCC)等。

算法复杂度分析:根据前面的分析,局部匹配需要为左图像中的每个像素设置支持窗口,并在右图像中匹配最接近的支持窗口,计算相似度要求遍历两个窗口内的所有像素。在局部匹配算法中,支持窗口一般为滑动性支持窗口,也就是说,每个像素都会依次与同一行中最大搜索范围内的所有像素进行比较。假设支持窗口的边长为kernel,规定匹配点的搜索范围为maxoffset,那么复杂度为OH×W×maxoffset×kernel2)=OH×W×maxoffset),其中,HW分别是图像的高度和宽度,需要说明的是,O(·)表示与括号内的变量同量级的变量,所以当kernel不为1时,以上等式仍成立。

2.2.2.2 全局(Global)立体匹配算法

相比于局部立体匹配算法,全局立体匹配算法引入了相邻像素视差之间的约束关系,保证相邻像素之间视差的变化较平缓,这就是其中“全局”的含义。该算法定义了由数据项和平滑项组成的能量函数,能量函数的自变量为左图像中各像素的视差,也就是说,在使用全局立体匹配算法之前,需要给定各像素初始的“试探性”视差。

在给定视差之后,每个像素的数据项表示在该视差下的匹配代价,也就是该视差对应的右图像中的像素与此像素的相似度,视差与右图像中像素的对应关系:假设该像素在左图像中的坐标为(u1v1),视差为d,则对应的右图像像素的坐标为(u1-d,v1)。与局部立体匹配算法不同,最终得到的视差对应的相似度不一定是最大的,因为还会有“平滑项”的影响;平滑项表示该像素的视差与邻近点视差的差别,邻近点是指该像素邻域内的点,这里的“差别”一般用“差的绝对值和”来度量。

整个全局匹配过程就是求解能量函数最小时各像素的视差值。计算过程:根据当前输入的视差值,计算出各像素的数据项和平滑项,从而得到当前的全局能量函数,然后逐步调整视差输入,重新计算能量函数,直到能量函数的值最低,此时的视差输入即对应最佳匹配。

算法复杂度分析:能量函数在2D图像中寻找最优解的问题是多项式复杂级别的非确定性问题,即NP-complete问题,非确定性问题是只能用假设—验证的方法解决的问题,在实际中需要进行迭代求解;与此相对,确定性问题就是可以直接求解的问题。

2.2.2.3 半全局立体匹配算法(Semi-Global Matching,SGM)[3]

局部立体匹配算法快速简单,全局立体匹配算法精度高,半全局立体匹配算法在一定程度上结合了二者的优点,该算法数据项的计算与全局匹配算法类似,而将平滑项的计算简化到若干个(一般为8个或16个)一维路径上去,将计算得到的视差的平均值作为最终的视差,从而避免了2D平面上的计算,提升了效率,同时将非确定性问题转化为确定性问题。对于每个一维路径,某一像素的平滑项只与该路径上的前一像素的视差有关,而全局立体匹配中的平滑项与该点邻域内的所有点均相关,因此半全局立体匹配算法既不需要给定初始视差,也不需要迭代,从而大大简化了计算。假设使用8个一维路径计算平滑项,其中的四个路径如图2.2-5所示,另外四个路径与该四个路径方向相反,图中圆圈代表像素,箭头代表像素视差依次计算的顺序,每个圆圈的能量函数由它本身确定的数据项和它与前一个圆圈共同确定的平滑项给出,该能量函数取最小值时的视差为该像素的最终视差。

图2.2-5 半全局算法的四个路径

算法复杂度分析:数据项计算复杂度等同于局部算法;对于平滑项,在每一搜索路径上都只保证当前像素与前一像素视差接近,所以单个搜索路径计算平滑项的复杂度为OH×W×maxoffset),算法总的复杂度为OH×W×maxoffset×(kernel2+N))=OH×W×maxoffset),半全局立体匹配算法的复杂度与局部立体匹配算法的复杂度为同一数量级。

以上三种算法在不同的场景和目标下均有各自的应用。局部立体匹配算法简单地将相似度作为匹配的唯一准则,而未考虑相邻像素视差的平滑问题,所以其运行速度最快,而准确度却无法保证,所以适用于对匹配准确性要求不高的场景。全局立体匹配算法保证了像素视差与周围像素视差的平滑变化,使得各点视差不再孤立,但是这也导致了视差无法独立求解,需要进行全局假设和迭代,所以运行速度非常慢,而准确度很高,适用于对准确性要求很高的非实时系统。半全局立体匹配算法使用若干次一维平滑来代替全局平滑,既保证了相邻视差的平滑性,又使得计算量不至于太大,所以半全局立体匹配算法是目前商业软件中使用最多的立体匹配算法。

在各类3D相机中,双目相机的结构最为简单,只需两个普通的相机和一个处理器,所以其成本也较低;并且双目相机直接采集环境光来形成图像,所以在室内和室外均可使用。

但是双目相机也有一些固有的局限,其中最重要的是计算量的问题。双目相机采用纯视觉的方法,需要逐像素进行匹配,因此双目匹配算法的计算量普遍较大;而且双目相机对光照非常敏感,在光照较强(会出现过度曝光)和较暗的情况下,匹配算法的效果都会急剧下降。

另外,双目相机不适用于单调、缺乏纹理的场景。因为双目视觉根据视觉特征进行图像匹配,所以对于缺乏视觉特征的场景(如天空、白墙、沙漠等),会出现匹配困难甚至匹配失败的情况。纹理丰富和纹理缺乏的场景对比如图2.2-6所示。

图2.2-6 纹理丰富和纹理缺乏的场景对比

对物体本身特征的依赖是双目视觉的一大固有问题,为此人们想到了主动向场景中投射特征化光源的方法——结构光法,结构光自带大量特征点,从而可以摆脱对物体本身特征的依赖。