我注意到opencv stereoCalibrate()改变了相机矩阵中的焦距,即使我已经设置了适当的标志(即CV_CALIB_FIX_FOCAL_LENGTH).我正在使用相同焦距的两个相同的相机在镜头上机械设置,而且我知道传感器的大小,所以我可以手动计算内在的相机矩阵,实际上我做了什么.
在这里你有一些立体声校准程序的输出 – stereoCalibrate()之前和之后的相机矩阵.
std::cout << "Before calibration: " << std::endl;
std::cout << "C1: " << _cameraMatrixA << std::endl;
std::cout << "C2: " << _cameraMatrixB << std::endl;
double error = cv::stereoCalibrate(objectPoints, imagePointsA, imagePointsB, _cameraMatrixA, _distCoeffsA, _cameraMatrixB, _distCoeffsB, _imageSize,
R, T, E, F,
cv::TermCriteria((cv::TermCriteria::COUNT + cv::TermCriteria::EPS), 30, 9.999999999999e-7), CV_CALIB_FIX_FOCAL_LENGTH | CV_CALIB_FIX_PRINCIPAL_POINT);
std::cout << "After calibration: " << std::endl;
std::cout << "C1: " << _cameraMatrixA << std::endl;
std::cout << "C2: " << _cameraMatrixB << std::endl;
Before calibration:
C1: [6203.076923076923, 0, 1280; 0,
6203.076923076923, 960; 0, 0, 1]C2: [6203.076923076923, 0, 1280; 0, 6203.076923076923, 960; 0, 0,
1]After calibration:
C1: [6311.77650416514, 0, 1279.5; 0, 6331.34531760757, 959.5; 0,
0, 1]C2: [6152.655897294907, 0, 1279.5; 0, 6206.591406832492, 959.5; 0,
0, 1]
我认为这是奇怪的opencv行为.有人遇到类似问题吗?我知道它很容易解决,我可以在立体声校准后将焦距设置为相机矩阵.
最佳答案 为了做你想做的事,你必须使用flags调用stereoCalibrate:
CV_CALIB_USE_INTRINSIC_GUESS | CV_CALIB_FIX_FOCAL_LENGTH | CV_CALIB_FIX_PRINCIPAL_POINT
如果您不使用CV_CALIB_USE_INTRINSIC_GUESS标志,stereoCalibrate将首先初始化相机矩阵和失真系数本身,然后在随后的优化中修复它们的一部分.这是在documentation中陈述的,虽然相当不清楚,并且没有提到关键标志:
Besides the stereo-related information, the function can also perform a full calibration of each of two cameras. However, due to the high dimensionality of the parameter space and noise in the input data, the function can diverge from the correct solution. If the intrinsic parameters can be estimated with high accuracy for each of the cameras individually (for example, using calibrateCamera() ), you are recommended to do so […].
除了任何CV_CALIB_FIX_ *标志之外,使用CV_CALIB_USE_INTRINSIC_GUESS会告诉函数使用您传递的内容作为输入,否则,此输入将被忽略并被覆盖.