我正在尝试使用以下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
还应根据我的立体相机使用矩阵R1
,R2
,P1
和P2
来纠正输出设置,即设置与图像y轴平行的极线并裁剪图像。
这是对的吗?
然而,对src_left
和src_right
中的点执行的映射是“倾斜的”,即未失真的输出图像是倾斜的,在边界上留下空白(特别是在角落的一半)图像。我相信这种倾斜来自旋转矩阵R1
和R2
,并且对应于围绕z轴的旋转。
现在我的问题是:
答案 0 :(得分:2)
在整流和不失真期间,可以根据立体摄像机的方向平移和/或旋转图像。
显然,如果您保留转换后图像的原始分辨率 - 您将丢失边界周围的一些信息。例如。考虑到没有平移,但你必须将其中一个图像顺时针旋转45度并使用相同的分辨率 - 角落将是“空白”。
常见的解决方案是找到最大的“内切”矩形并将其缩放到原始分辨率。
您可以使用initUndistortRectifyMap
代替undistortPoints
。
对于stereoRectify
来电,对initUndistortRectifyMap
的来电将如下所示:
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);