参考:
https://blog.csdn.net/wangxiaokun671903/article/details/37935113
https://www.cnblogs.com/riddick/p/8486223.html
https://blog.csdn.net/FUZHENQI/article/details/80092605
结构框架
首先,将整个框架搭出来,我会按上面每一个过程进行问题提问与回答。
过程1——参数整定
双目矫正矫正的最终效果?
双目校正就是通过一定的方法将两个摄像头拍摄同一个物体的图像进行处理,使得两幅图像最终达到下面的目标,同一个物体在两幅图像中的大小一样,且水平在一条直线上。
相机标定的内容?
1.内参标定:
焦距fx,fy,图像物理坐标的扭曲因子gama,图像原点相对于光心成像点的的纵横偏移量cx和cy(像素为单位)
2.外参标定:
世界坐标系转换到相机坐标系的旋转R和平移T矩阵。右相机相对于左相机的旋转矩阵R(通过一定的方法可将此矩阵分解成两个矩阵R1和R2,即左右相机各旋转一半达到水平)。
3.畸变系数:
括相机的径向畸变系数k1,k2,k3,~,和相机的切向畸变系数p1,p2,~
针孔相机的模型?
世界坐标系:就是物体在真实世界中的坐标,比如黑白棋盘格的世界坐标系原点定在第一个棋盘格的顶点,Xw,Yw,Zw互相垂直,Zw方向就是垂直于棋盘格面板的方向。可见世界坐标系是随着物体的大小和位置变化的,单位是长度单位。只要棋盘格的大小决定了,无论板子怎么动,棋盘格角点坐标一般就不再变动(因为是相对于世界坐标系原点的位置不变),且认为是Zw=0.
相机坐标系:以光心为相机坐标系的原点,以平行于图像的x和y方向为Xc轴和Yc轴,Zc轴和光轴平行,Xc,Yc,Zc互相垂直,单位是长度单位。
图像物理坐标系:以主光轴和图像平面交点为坐标原点,x和y方向如图所示,单位是长度单位。
图像像素坐标系:以图像的顶点为坐标原点,u和v方向平行于x和y方向,单位是以像素计。
从世界坐标系到图像坐标系的转换过程如下:世界坐标系通过外参矩阵转换到相机坐标系,相机坐标系通过内参矩阵转换到图像像素坐标系(这一步是通过两步完成的,一,相机坐标系通过焦距对角矩阵和畸变系数转换到图像物理坐标系,二图像物理坐标系通过像素转换矩阵转换到像素坐标系中)。转换过程和公式如下:
过程2——极线矫正
极线矫正的过程是什么?
双目平行校正,是针对图像对应的相机坐标系进行的,那么极线校正的时候应该注意就是在四中叙述的畸变校正过程中,在转换到相机坐标系后,左右图像对应的相机坐标系分别通过旋转矩阵R1和R2进行平行极线校正。步骤如下:将源图像像素坐标系通过内参矩阵转化成相机坐标系(和图像物理坐标系比较多了缩放和Z轴),通过旋转矩阵R1和R2进行平行极线校正,然后通过畸变系数校正图像的相机坐标,校正后通过内参矩阵将相机坐标系转换成图像像素坐标系,并根据源图像坐标的像素值赋值给新的图像坐标
极线矫正的目的?
为了可以得出视差图。
过程3——畸变矫正
畸变矫正过程是什么?
获取了内参矩阵和畸变系数对图像进行畸变校正时,就是解决图像的畸变问题(径向畸变是因为透镜本身工艺的问题,切向畸变是由于安装问题带来的)。畸变校正的过程是这样的,将源图像像素坐标系通过内参矩阵转化成相机坐标系(和图像物理坐标系比较多了缩放和Z轴),通过畸变系数校正图像的相机坐标,校正后通过内参矩阵将相机坐标系转换成图像像素坐标系,并根据源图像坐标的像素值赋值给新的图像坐标。
其中,k1,k2,k3径向畸变系数,p1,p2是切向畸变系数。畸变发生在相机坐标系转图像物理坐标系的过程中。操作的对象时相机坐标系。(Xc,Yc,Zc)为相机坐标系坐标。
过程4——视差图获取
视差图是什么?作用是什么?
立体校正后的左右两幅图像得到后,匹配点是在同一行上的,可以使用OpenCV中的BM算法或者SGBM算法计算视差图。由于SGBM算法的表现要远远优于BM算法,因此采用SGBM算法获取视差图。
P为空间中的点,P1和P2是点P在左右像平面上的成像点,f是焦距,OR和OT是左右相机的光心。由下图可见左右两个相机的光轴是平行的。XR和XT是两个成像点在左右两个像面上距离图像左边缘的距离。
(Xr-Xt)就可以得到P1点,在左视差图中的值,同理可以计算出整幅图像,最终获得左视差图。右视差图同理。
左边为左视差图,右边为右视差图。
过程5——空洞填补
为什么造成空洞?解决办法?
视差图中视差值不可靠的视差大多数是由于遮挡引起,或者光照不均匀引起。既然牛逼如SGBM也觉得不可靠,那与其留着做个空洞,倒不如用附近可靠的视差值填充一下。
空洞填充也有很多方法,在这里我检测出空洞区域,然后用附近可靠视差值的均值进行填充。填充后的视差图如下:
填充后左视差图:
过程6——视差图计算深度图
深度图如何获取?
视差的单位是像素(pixel),深度的单位往往是毫米(mm)表示。而根据平行双目视觉的几何关系(此处不再画图推导,很简单),可以得到下面的视差与深度的转换公式:
depth = ( f * baseline) / disp
上式中,depth表示深度图;f表示归一化的焦距,也就是内参中的fx; baseline是两个相机光心之间的距离,称作基线距离;disp是视差值。等式后面的均已知,深度值即可算出。
过程7——深度图转换点云图
转换过程是什么?
p.z = double(d) / camera_factor;
p.x = (n - camera_cx) * p.z / camera_fx;
p.y = (m - camera_cy) * p.z / camera_fy;