概述
参考资料:《Learning OpenCV》,Stanford University CS 131 Computer Vision Foundations and Applications 2016 - lecture10
- 相机成像是将3D信息映射到2D
- 如何从2D图像重建3D信息?
- 阴影、纹理、聚焦等
- 这里主要关注运动作为线索,使用两幅图像进行三维重建,与动物的双眼立体视觉一致
- 立体成像/三维重建的步骤:
- 双目立体标定:确定左右相机的参数和两者之间的相对几何位置
- 畸变矫正:输出无畸变的左右相机图像
- 立体校正:调整摄像机间的角度和距离,输出行对准的校正图像
- 立体匹配:匹配左右摄像机间视场中的相同特征,计算匹配特征在左右图像上的列坐标的差值,输出视差图
- 重投影:将视差图通过三角测量的方法转换成距离,输出深度图
三角测量
假设两个相机:
- 无畸变
- 图像平面共面
- 光轴平行
- 主距f相同
- 图像行对准
这样的相机布置称为frontal parallel,这样的假设实际在物理上很难达到,而校正的过程则是在数学上实现上述假设。
基于上述假设,利用三角形相似:
�−(��−��)�−�=��⇒�=��(��−���)−(��−���)=����−��−(���−���)
�=��−��或�=��−��−(���−���)称为视差
同理,可得:
�=���−��−(���−���)(��−��)�=���−��−(���−���)(��−��)
当���=���时,有:
�=����−��
此时,无穷远处的视差为0,也就是说两个相机的光轴平行且在无限远处相交;否则,有限远处的视差为0,等价于两个相机的光轴在有限远处相交,也就是说这种情况下,两个相机坐标系没有共面,即相机处于横向汇聚模式,不能用上述公式求解距离。也就是说,对于两个相机坐标系共面的情况或者立体校正过程中,必然要求���=���
当x采用像素坐标时,f应该也是像素坐标的��,��=�/��;��,���是在左相机图像坐标系下,��,���是在右相机图像坐标系下;
由公式可知距离与视差成反比,当视差大小的范围固定时,减小f,T,能对更近的物体进行测量,增大测距范围。
对上述公式求微分,有:
�=�2���
视差计算的分辨率对测量分辨率的影响:
��/��=1/�1/�=��=���2
当视差计算分辨率固定时,测量分辨率与距离的平方成反比,与f,T成正比
单位视差计算误差对测量误差的影响:
��=�2��
该公式反映了视差计算的误差造成的测量误差与距离平方成正比,与f, T成反比,即与测量分辨率相反
对极几何
好像这部分的原理在实际立体视觉应用过程中没有用到
应该是由于进行了立体校正,不需要用到基础矩阵去求解物体位置
立体标定
根据单目标定,可以得到左右相机的外参��,��,��,��,令P为物体坐标,则其对应的左右相机坐标��,��为:
��=���+����=���+��
联立并消去P可得:
�=��−1(��−��)��=����−1(��−��)+��=���−���+��=���+�
其中,�=����−1,�=��−���, 代表从右相机到左相机坐标系的几何关系
实际求解过程中,对于多对棋盘图像,先用单目标定算法标定左右相机的外参,再根据上面的公式计算左右相机间的R,T,然后以多对棋盘图像计算到的R、T的中值为初始值,使用Levenberg-Marquardt 迭代算法求解使重投影误差(局部)最小的解,这个解包括左右相机的参数和两者之间的R、T,立体标定通常可以获得比单目标定更准确的相机参数。
立体校正
校正原理
立体校正是为了使得左右相机的图像坐标系行对准,主要分两个步骤:
- 根据立体标定得到的旋转矩阵R对两个坐标系进行旋转使两者共面。
注意,此时两个图像坐标系共面但不一定行对准,即两者的x坐标轴并不共线,因为两个坐标系之间还存在偏移。 - 利用立体标定得到的平移矩阵T对两个坐标系进行变换使两者行对准
Bouguet's算法实现立体校正:
- 可以使得重投影畸变(相对于校正前)最小化,同时使得公共视野最大化
- 将旋转矩阵R对半拆分为��,��,然后左右相机分别照此进行旋转,即左右相机各旋转一半角度,得到共面坐标系
- 利用平移矩阵T构造旋转矩阵�����,然后左右相机均照此进行旋转,使得相机行对准
构造原理为是左右相机以x轴与T向量间的夹角绕z轴旋转,从而使x轴共线
令平移向量为:
�=[����0]则
�����=[��′��′0−��′��′0001]其中,��′=��/||�||,��′=��/||�||
由于此时x轴与平移向量T平行,所以校正后两个相机的主距相等,同时,两个相机间的平移向量为[��00]
总体的立体校正为:
������=�������������=�������
校正的实现
本质上是对图像进行了3维旋转,由于校正前后的内参矩阵已知,则对于归一化成像坐标系中的一点,可以由校正前后的内参矩阵得到校正前后的像素坐标。
完整的从原图得到校正图像的过程示意图如下,该图取自《Learning OpenCV》,图中的公式含义不清且可能有误,可以忽略;
Stereo rectification: for the left and right camera, the raw image (a) is undistorted (b) and rectified (c) and finally cropped (d) to focus on overlapping areas between the two cameras; the rectification computation actually works backward from (c) to (a)
校正过程如下:
- 对校正后图像像素坐标,用校正后的内参矩阵反向映射到归一化成像坐标系
- 在归一化成像坐标系恢复镜头畸变,并用校正前的内参矩阵正向映射得到原图图像坐标,从而建立校正前后像素坐标间的关系
- 在原图图像对像素进行插值,得到像素值作为校正后图像像素坐标
实际实现整个立体校正的时候,可以将undistort, rectify, crop合成一步,直接用一个map进行映射。
投影矩阵
令投影矩阵为P(也就是单应性矩阵),投影矩阵使齐次的3D世界坐标(或相机坐标)投影到2D图像坐标:
�[���1]=[���]
其中投影后的图像坐标为(�/�,�/�)
由于对图像坐标系进行了旋转,所以相机的主距和主点像素坐标都发生了变化,令左相机校正前的投影矩阵为��,则由
��������[���1]=������[���]
可得,校正后的投影矩阵������=��������
当3D点为左相机的相机坐标时,
������=��������′������=��������′
其中,������,������分别为左右相机校正后的相机矩阵,注意,这里的变量名与《Learning OpenCV》中不太一致
��′=[1000010000100000]��′=[100��010000100000]
反投影矩阵
2D点也能反投影到3D相机坐标
�[���1]=[����]
其中,反投影后的3D坐标为(�/�,�/�,�/�)
反投影矩阵Q为
�=[100−��010−��000�001/��(��−��′)/��]
其中的相机参数除��′为右相机参数外,其余均为左相机参数,另外,这里的f应该是fx,相应的,反投影方程中的x,y也是做相机中的坐标。注意,《Learning OpenCV》中,这里的1/Tx取了负号,感觉应该是书本出错了。
将矩阵乘法展开可得:
[����]=[�−���−���(�+��−��′)/��]
3D坐标为:
1/�[���]=��(�+��−��′)[�−���−���]
与 **三角测量**中一致
OpenCV提供了reprojectTo3DImage()和perspectiveTransform(),分别对视差图和离散的视差数据进行反投影。
匹配图像缩小时的反投影
如果为了减少立体匹配的计算量和计算时间,将图像缩小后再进行立体匹配得到视差图,反投影需要做调整;
假设匹配图像行列缩放因子为p,得到视差数据为[x' y' d'],其对应的原图匹配得到的视差数据为[x y d],则有对应公式
[���]=1/�[�′�′�′]
则有两种方法进行反投影:
- 视差图按缩放因子1/� resize,并且每个像素的视差乘以1/� 后,使用reprojectTo3DImage()和Q反投影,得到与原图分辨率对应的重建结果
- 对视差图中的点,按照上述对应公式得到原图视差数据,使用reprojectTo3DImage()和Q反投影,得到与缩放后图像分辨率对应的重建结果
当然,也可以考虑在双目立体标定、立体校正、立体匹配和反投影全过程中使用缩放后的图像
OpenCV立体匹配
- BM(block matching)算法
It works by using small "sum of absolute difference" (SAD) windows to find matching points between the left and right stereo-rectified images. This algorithm finds only strongly matching (high-texture) points between the two images. Thus, in a highly textured scene such as might occur outdoors in a forest, every pixel might have computed depth. In a very low-textured scene, such as an indoor hallway, very few points might register depth. - SGBM(semi-global block matching )算法
differs from BM primarily in two respects. The first is that matching is done at subpixel level using the Birchfield-Tomasi metric [Birch‐field99]. The second difference is that SGBM attempts to enforce a global smoothness constraint on the computed depth information that it approximates by considering many one-dimensional smoothness constraints through the region of interest. - 对比
These two methods are complementary, in the sense that BM is quite a bit faster, but does not provide the reliability and accuracy of SGBM.
BM算法
步骤:
- Prefiltering to normalize image brightness and enhance texture.
- Correspondence search along horizontal epipolar lines using an SAD window.
- Postfiltering to eliminate bad correspondence matches.
视差搜索范围:
从minDisparity到MaxDisparity范围内搜索,MaxDisparity=minDisparity+NumDisparities,均为像素坐标
视差搜索范围 注意,实际搜索的过程中,是以亚像素精度的视差搜索的,精度为1/16像素
视差搜索范围形成了一个双目视界(horopter),也就是确定了可能的测量范围,超过这个测量范围的物体,其深度是未知的,减小f,T,增大视差查找范围或增加像素宽度可扩大双目视界
顺序约束:点在左右视图中的顺序保持一致,计时有部分点确实(遮挡或噪声)
注意,OpenCV中,StereoMatcher::compute()函数计算得到的视差图要除以16,因为视差搜索使用亚像素精度,精度为1/16像素,而视差图输出为整形数据,所以对亚像素精度视差乘以16再取整保存为整形数据。
双目成像模式
参见《视觉测量技术基础》- 白福忠
双目横向汇聚模式(相机光轴在有限远处相交)应该是为了对远处物体有更大的重合视野,同时应该有利于减少视差计算误差造成的测量误差
《Learning OpenCV3》的Calibrated stereo rectification: Bouguet's algorithm部分指出,stereoRectify()的flags参数设置为0,即对应为汇聚模式,设置为CALIB_ZERO_DISPARITY,即对应平行模式,且指出,汇聚模式可以在接近汇聚点位置获得更好的深度分辨率,也就是能减小重建误差
《Learning OpenCV3》的Depth Maps from Three-Dimensional Reprojection部分指出,OpenCV的stereoRectify()得到的反投影矩阵Q,是可以应用于汇聚模式的,可以用reprojectImageTo3D()进行三维重建