双目立体视觉三维重建

双目立体视觉的整体流程包括:图像获取、双目标定、双目矫正、立体匹配、三维重建。
双目立体视觉三维重建


图像获取

双目相机拍摄获取 左右目图像

双目标定

内参 外参
相机矩阵 K1,K2 旋转矩阵 R
畸变系数 D1,D2 平移向量 T

《Learning OpenCV》中对于 Translation 和 Rotation 的图示是这样的:
双目立体视觉三维重建

双目矫正

通过 OpenCV函数 stereoRectify,包括 畸变矫正立体矫正

输出参数
左目 矫正矩阵(旋转矩阵) R1 (3x3)
右目 矫正矩阵(旋转矩阵) R2 (3x3)
左目 投影矩阵 P1 (3x4)
右目 投影矩阵 P2 (3x4)
disparity-to-depth 映射矩阵 Q (4x4)

其中,

P1=[f0cx00fcy00010]

P2=[f0cxTxf0fcy00010]

通过 P2 可计算出 基线 长度:

baseline=Tx=P203fx

  • ethz-asl/image_undistort: A compact package for undistorting images directly from kalibr calibration files. Can also perform dense stereo estimation.

立体匹配

视差计算

通过 OpenCV函数 stereoBM (block matching algorithm),生成 视差图(Disparity Map) (CV_16S or CV_32F)

disparity map from stereoBM of OpenCV :
It has the same size as the input images. When disptype==CV_16S, the map is a 16-bit signed single-channel image, containing disparity values scaled by 16. To get the true disparity values from such fixed-point representation, you will need to divide each disp element by 16. If disptype==CV_32F, the disparity map will already contain the real disparity values on output.

So if you’ve chosen disptype = CV_16S during computation, you can access a pixel at pixel-position (X,Y) by: short pixVal = disparity.at<short>(Y,X);, while the disparity value is float disparity = pixVal / 16.0f;; if you’ve chosen disptype = CV_32F during computation, you can access the disparity directly: float disparity = disparity.at<float>(Y,X);

三维重建

深度计算

双目立体视觉三维重建

深度计算公式如下,通过遍历图像生成 深度图

Z=depth=fxbaselinedisparity

其中,disparity 代表 视差图 坐标值

图像类型

  • 单位meter –> 32FC1
  • 单位millimeter –> 16UC1

三维点坐标计算

  • 根据 小孔成像模型,已知 Z相机内参 可计算出 三维点坐标,从而生成 三维点云
    {Z=depthX=ucxfxZY=vcyfyZ