我们看到红色线条上三个不同远近的黑色的点在下方相机上投影在同一个位置,因此单目相机无法分辨成的像到底是远的那个还是近的那个。
可求得深度值Z为:
B:双目相机之间的距离,称为基线。
f:双目相机的焦距(该焦距要转换为以像素为单位的焦距)。
d:称为视差,即物体在左右相机中成像的点距成像平面边缘的距离(成像点的在图像平面上的像素坐标的行像素)。
假设目标点在左视图中的坐标为(x,y)--为像素坐标系下的坐标值,在左右视图上形成的视差为d,
目标点在以左摄像头光心为原点的世界坐标系中的坐标为(X,Y,Z),则存在所示的变换矩阵Q,使
'
上式中的负号,是因为为两台相机投影中心间的平移值,定义为复值,所以添加负号。
在清楚了上述原理之后,我们也就知道了,所有的这几步:标定、校准和匹配,都是围绕着如何更精确地获得 f,d,B,cx 和cy 而设计的。
选择张氏标定法对相机进行标定获取相机内外参数
单目相机,或者双目相机的标定可以直接通过matlab中的相机标定模块。
极限约束:
什么是极线呢?如下图所示,两个相机,p是空间中一点,P和两个相机中心点形成了三维空间中的一个平面,称为极平面。极平面和两幅图像相交于两条直线,这两条直线为极线。p在相机C1中的成像点是P1,在相机C2中的成像点是P2,但p的位置事先是未知的。
我们的目标是:对于左图中的P1点,寻找它在右图中的对应点P2,这样就可以获取视差d。这样就能确定P点的空间位置,也就是我们想要的空间物体和相机的距离。
首先要把该点在左右视图上两个对应的像点匹配起来。
然而,在二维空间上匹配对应点是非常耗时的,为了减少匹配搜索范围,我们可以利用极线约束使得对应点的匹配由二维搜索降为一维搜索。
极线约束:就是指当同一个空间点在两幅图像上分别成像时,已知左图投影点P1,那么对应右图投影点P2一定在相对于P1的极线上,这样可以极大的缩小匹配范围。
非理想双目相机成像模型
有些场景下两个相机,很难保证光心C1、C2完全水平,即使是固定在同一基板上也会因为装配的原因导致光心不水平,如上图所示。
把不理想的转化为理想情况,这就是图像矫正技术。
图像立体校正技术:就是要把消除畸变后的两幅图像严格地行对应,使得两幅图像的对极线恰好在同一水平线上,这样一幅图像上任意一点与其在另一幅图像上的对应点就必然具有相同的行号,只需在该行进行一维搜索即可匹配到对应点。
可采用OpenCV中自有的函数stereoCalibrate() ,stereoRectify() ,initUndistort RectifyMap() 等进行图像校正。
函数stereoCalibrate() 作用是获取左右相机的内外参数,且求出左右两个相机的相对位置关系;
函数stereoRectify() 作用是计算左右相机进行图像矫正所需要的映射矩阵;
函数initUndistort RectifyMap() 函数用于计算无畸变和修正的转换关系。
立体匹配是寻找同一个目标在左相机上的成像点和右相机的成像点,进而求出左,右图像中的视差值的算法。
可采用OpenCV中的自有函数BM(),SGBM()等其它函数实现立体匹配。
对于左图的一个像素点点,沿着它在右图中水平极线方向寻找和它最匹配的像素点,说起来简单,实际操作起来却不容易。这是因为上述都是理想情况下的假设。实际进行像素点匹配的时候会发现几个问题:
(1)、实际上要保证两个相机完全共面且参数一致是非常困难的,而且计算过程中也会产生误差累积,因此对于左图的一个点,其在右图的对应点不一定恰好在极线上。但是应该是在极线附近,所以搜索范围需要适当放宽。
(2)、单个像素点进行比较鲁棒性很差,很容易受到光照变化和视角不同的影响。
基于滑动窗口的图像匹配:
上述问题的解决方法:
使用滑动窗口来进行匹配。如下图所示。对于左图中的一个像素点(左图中红色方框中心),在右图中从左到右用一个同尺寸滑动窗口内的像素和它计算相似程度,相似度的度量有很多种方法,比如 误差平方和法(Sum of Squared Differences,简称SSD),左右图中两个窗口越相似,SSD越小。SSD值最小的位置对应的像素点就是最佳的匹配结果。
具体操作中还有很多实际问题,比如滑动窗口尺寸。滑动窗口的大小选取还是很有讲究的。
小尺寸的窗口:精度更高、细节更丰富;但是对噪声特别敏感。大尺寸的窗口:精度不高、细节不够;但是对噪声比较鲁棒
由于要逐点进行滑动窗口匹配,计算效率也很低。
基于能量优化的图像匹配
目前比较主流的方法都是基于能量优化的方法来实现匹配的。能量优化通常会先定义一个能量函数。
对环境光照非常敏感。双目立体视觉法依赖环境中的自然光线采集图像,而由于光照角度变化、光照强度变化等环境因素的影响,拍摄的两张图片亮度差别会比较大,这会对匹配算法提出很大的挑战。
不适用于单调缺乏纹理的场景。由于双目立体视觉法根据视觉特征进行图像匹配,所以对于缺乏视觉特征的场景(如天空、白墙、沙漠等)会出现匹配困难,导致匹配误差较大甚至匹配失败。
计算复杂度高。该方法需要逐像素匹配等方法;又因为上述多种因素的影响,为保证匹配结果的鲁棒性,需要在算法中增加大量的错误剔除策略,因此对算法要求较高,想要实现可靠商用难度大,计算量较大。
相机基线限制了测量范围。测量范围和基线(两个摄像头间距)关系很大:基线越大,测量范围越远;基线越小,测量范围越近。所以基线在一定程度上限制了该深度相机的测量范围。
为了提高最终视差图的质量,往往通过视差求精来对视差图进行进一步处理,在保证物体内部视差较为平滑而又能较好地保持物体的边缘的情况下去除奇异数据的影响。
常见的求精方法包括左右一致性检测(Left-Right Consistency(LRC) check)、视差图滤波和连通区域检测,孔洞填充。
经过立体匹配求解的视差结果是一个离散的整数序列,这与真实世界中情况是不相符的,所以往往通过亚像素插值来进一步使视差结果精细化,常用插值法来进行视差值求精。
左右一致性检测:
有些点可能只在双目相机中其一的相机可以看到,但对于另一相机看不到的点。在立体匹配算法中如果不针对遮挡区域做一些特殊处理是不可能通过单幅图提供的有限信息得到遮挡点的正确视差的。遮挡点通常是一块连续的区域,记作occluded region/area。
左右一致性检测作用是实现遮挡检测(Occlusion Detection),得到左图对应的遮挡图像,以实现对遮挡点的视差的计算。
根据左右两幅输入图像,分别得到左右两幅视差图。对于左图中的一个点p,求得的视差值是d1,那么p在右图里的对应点应该是(p-d1),(p-d1)的视差值记作d2。若|d1-d2|>threshold(一般为1个像素),p标记为遮挡点(occluded point)。
得到了二值的遮挡图像,之后是为所有的遮挡点赋予合理的视差值。对于左图而言,遮挡点一般存在于背景区域和前景区域接触的地方。遮挡的产生正是因为前景比背景的偏移量更大,从而将背景遮盖。
具体赋值方法是:对于一个遮挡点p,分别水平往左和往右找到第一个非遮挡点,记作pl、pr。点p的视差值赋成pl和pr两者中视差值中较小的那一个。d(p)= min (d(pl),d(pr))。
视差图滤波:滤波去躁主要用于去除视差图中由于误匹配造成的孤立噪点,视差图后处理中常用的两种滤波方法有中值滤波和双边滤波。
中值滤波是一种典型的非线性滤波技术,其基本思想是用像素点邻域灰度值的中值来代替该像素点的灰度值,该方法在去除脉冲噪声、椒盐噪声的同时又能保留图像的边缘细节。
双边滤波是结合图像的空间邻近度和像素值相似度的一种折中处理,同时考虑空域信息和灰度相似性,达到保边去噪的目的。
亚像素:
像素是成像面的基本单位也是最小单位,通常被称为图像的物理分辨率。
如130万像素为1280*1024;如果成像系统要显示的对象尺寸小于物理分辨率时,成像系统是无法正常辨识出来的。
实际上,“亚像素”应该是存在的,只是硬件上没有比像素更细微的传感器把它检测出来而已,于是在软件上通过亚像素细分算法对物理分辨率的近似优化结果。
例如:某CMOS成像芯片,其像素间距为4.5um。在成像时,对物理世界中连续的图像进行了离散化处理,这时成像面上每一个像素点只代表其附近的颜色。
而两个像素之间有4.5um的距离,在宏观上可以看作是连在一起的,但在微观上它们之间还有无限更小的东西存在,是两个物理像素之间的“像素”,这些更小的东西就称为“亚像素”。
亚像素精度是指相邻两像素之间细分情况。输入值通常为二分之一,三分之一或四分之一。这意味着每个像素将被分为更小的单元从而对这些更小的单元实施插值算法。例如,如果选择四分之一,就相当于每个像素在横向和纵向上都被当作四个像素来计算。也就是上面图里的红色点之间有三个黑色点。这样通过亚像素插值的方法可以实现从小矩形到大矩形的映射,从而提高分辨率。