OpenCV立体声校准旋转矩阵

时间:2014-11-11 08:31:47

标签: c++ opencv computer-vision calibration

我正在尝试使用以下OpenCV函数取消对一对摄像机输出的影响:

cv::stereoCalibrate(object_points, image_points_left, image_points_right,cameraMatrixLeft, distCoeffsLeft, cameraMatrixRight, distCoeffsRight,cv::Size(sensor_width, sensor_height),R, T, E, F);

cv::stereoRectify(cameraMatrixLeft, distCoeffsLeft, cameraMatrixRight, distCoeffsRight, cv::Size(sensor_width, sensor_height), R, T, R1, R2, P1, P2, Q);

cv::undistortPoints(src_left, dst_left, cameraMatrixLeft, distCoeffsLeft, R1, P1);
cv::undistortPoints(src_right, dst_right, cameraMatrixRight, distCoeffsRight, R2, P2);

根据我的理解,函数cv::undistortPoints还应根据我的立体相机使用矩阵R1R2P1P2来纠正输出设置,即设置与图像y轴平行的极线并裁剪图像。

这是对的吗?

然而,对src_leftsrc_right中的点执行的映射是“倾斜的”,即未失真的输出图像是倾斜的,在边界上留下空白(特别是在角落的一半)图像。我相信这种倾斜来自旋转矩阵R1R2,并且对应于围绕z轴的旋转。

现在我的问题是:

  • 为什么(整流的)输出图像不能填满整个图像空间?

1 个答案:

答案 0 :(得分:2)

在整流和不失真期间,可以根据立体摄像机的方向平移和/或旋转图像。

显然,如果您保留转换后图像的原始分辨率 - 您将丢失边界周围的一些信息。例如。考虑到没有平移,但你必须将其中一个图像顺时针旋转45度并使用相同的分辨率 - 角落将是“空白”。

常见的解决方案是找到最大的“内切”矩形并将其缩放到原始分辨率。

您可以使用initUndistortRectifyMap代替undistortPoints

对于stereoRectify来电,对initUndistortRectifyMap的来电将如下所示:

  • left:initUndistortRectifyMap(cameraMatrixLeft, distCoeffsLeft, R1, P1, cv::Size(sensor_width, sensor_height), CV_32FC1, map_left_1, map_left_2);
  • 右:initUndistortRectifyMap(cameraMatrixRight, distCoeffsRight, R2, P2, cv::Size(sensor_width, sensor_height), CV_32FC1, map_right_1, map_right_2);

这会为您提供拨打remap

的地图
  • remap(left, left_rectified, map_left_1, map_left_2, INTER_LINEAR, BORDER_CONSTANT);
  • remap(right, right_rectified, map_right_1, map_right_2, INTER_LINEAR, BORDER_CONSTANT);