- 操作系统:ubuntu22.04
- OpenCV版本:OpenCV4.9
- IDE:Visual Studio Code
- 编程语言:C++11
算法描述
为已校准的立体相机的每个头计算校正变换。
cv::stereoRectify 是 OpenCV 中用于立体校正的函数,它基于已知的相机参数和相对位置(通过 cv::stereoCalibrate 或其他方法获得),计算出两个相机的投影矩阵和重映射变换,使得从两个相机获取的图像能够被矫正为仿佛它们是并排且光学轴平行的状态。这样做的目的是为了简化后续的视差图计算。
函数原型
void cv::stereoRectify
(
InputArray cameraMatrix1,
InputArray distCoeffs1,
InputArray cameraMatrix2,
InputArray distCoeffs2,
Size imageSize,
InputArray R,
InputArray T,
OutputArray R1,
OutputArray R2,
OutputArray P1,
OutputArray P2,
OutputArray Q,
int flags = CALIB_ZERO_DISPARITY,
double alpha = -1,
Size newImageSize = Size(),
Rect * validPixROI1 = 0,
Rect * validPixROI2 = 0
)
参数
- 参数cameraMatrix1:第一个相机的内参矩阵。
- 参数distCoeffs1:第一个相机的畸变参数。
- 参数cameraMatrix2:第二个相机的内参矩阵。
- 参数distCoeffs2:第二个相机的畸变参数。
- 参数imageSize:用于立体校准的图像尺寸。
- 参数R:从第一个相机坐标系到第二个相机坐标系的旋转矩阵,详见 stereoCalibrate。
- 参数T:从第一个相机坐标系到第二个相机坐标系的平移向量,详见 stereoCalibrate。
- 参数R1:第一个相机的输出3x3校正变换(旋转矩阵)。该矩阵将未校正的第一个相机坐标系中的点转换为校正后的第一个相机坐标系中的点。更技术性地说,它执行了从未校正的第一个相机坐标系到校正后的第一个相机坐标系的基础变换。
- 参数R2:第二个相机的输出3x3校正变换(旋转矩阵)。该矩阵将未校正的第二个相机坐标系中的点转换为校正后的第二个相机坐标系中的点。同样地,它执行了从未校正的第二个相机坐标系到校正后的第二个相机坐标系的基础变换。
- 参数P1:第一个相机在新的(校正后)坐标系中的输出3x4投影矩阵,即它将校正后的第一个相机坐标系中的点投影到校正后的第一个相机的图像中。
- 参数P2:第二个相机在新的(校正后)坐标系中的输出3x4投影矩阵,即它将校正后的第一个相机坐标系中的点投影到校正后的第二个相机的图像中。
- 参数Q:输出4×4视差到深度映射矩阵(见 reprojectImageTo3D)。
- 参数flags:操作标志,可以是零或 CALIB_ZERO_DISPARITY。如果设置了该标志,则函数会使每个相机的主点在校正后的视图中具有相同的像素坐标。如果没有设置该标志,函数可能会沿水平或垂直方向(取决于极线的方向)移动图像,以最大化有用图像区域。
- 参数alpha:自由缩放参数。如果它是 -1 或未指定,函数将执行默认缩放。否则,参数应在 0 和 1 之间。alpha=0 表示校正后的图像被缩放和移动,使得只有有效的像素可见(校正后没有黑色区域)。alpha=1 表示校正后的图像被减少和移动,使得来自原始图像的所有像素都保留在校正后的图像中(不丢失源图像像素)。任何中间值都会产生这两个极端情况之间的中间结果。
- 参数newImageSize:校正后的新图像分辨率。应该传递给 initUndistortRectifyMap(见 OpenCV 示例目录中的 stereo_calib.cpp 样本)。当传递 (0,0)(默认值)时,它被设置为原始 imageSize。设置为更大的值可以帮助保留原始图像中的细节,尤其是在存在较大径向畸变的情况下。
- 参数validPixROI1:可选输出矩形,在校正后的图像中包含所有有效像素的区域。如果 alpha=0,则 ROI 覆盖整个图像。否则,它们可能较小(见下图)。
- 参数validPixROI2:同上,适用于第二个相机。
该函数计算每个相机的旋转矩阵,这些矩阵(虚拟地)使两个相机的图像平面成为同一平面。因此,这使得所有的极线平行,从而简化了密集立体对应问题。函数以 stereoCalibrate 计算的矩阵作为输入,并提供两个旋转矩阵以及两个新坐标系中的投影矩阵作为输出。根据相机的相对位置,函数区分以下两种情况:
水平立体
第一个和第二个相机视图主要沿 x 轴相对偏移(可能有小的垂直偏移)。在校正后的图像中,左右相机中的对应极线是水平的并且具有相同的 y 坐标。P1 和 P2 的形式如下:
P1 = [ f 0 c x 1 0 0 f c y 0 0 0 1 0 ] \texttt{P1} = \begin{bmatrix} f & 0 & cx_1 & 0 \\ 0 & f & cy & 0 \\ 0 & 0 & 1 & 0 \end{bmatrix} P1=
f000f0cx1cy1000
P2 = [ f 0 c x 2 T x ⋅ f 0 f c y 0 0 0 1 0 ] , \texttt{P2} = \begin{bmatrix} f & 0 & cx_2 & T_x \cdot f \\ 0 & f & cy & 0 \\ 0 & 0 & 1 & 0 \end{bmatrix} , P2=
f000f0cx2