stereoCalibrate()即使在不应该改变焦距的情况下也会改变焦距

stereoCalibrate() changes focal lengths even when it was not supposed to

本文关键字:改变 变焦距 情况下 不应该 stereoCalibrate      更新时间:2023-10-16

我注意到opencv stereoCalibrate()会更改相机矩阵中的焦距,即使我设置了适当的标志(即CV_CALIB_FIX_OCAL_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;

校准前:

C1:[6203.076923076923,01280;0,6203.0769230769231960;0,0,1]

C2:[6203.076923076923,01280;06203.0769220769231960;0,0,1]

校准后:

C1:[6311.77650416514,0,1279.5;0,6331.34531760757,959.5;0,0,1]

C2:[6152.655897294907,0,1279.5;0,6206.591406832492959.5;0,0,1]

我认为这是一种奇怪的opencv行为。有人面临类似的问题吗?我知道这很容易解决,我可以在立体校准后将焦距设置为相机矩阵。

为了执行您想要的操作,您必须使用以下标志调用stereoCalibrate

CV_CALIB_USE_INTRINSIC_GUESS | CV_CALIB_FIX_FOCAL_LENGTH | CV_CALIB_FIX_PRINCIPAL_POINT

如果不使用CV_CALIB_USE_INTRINSIC_GUESS标志,stereoCalibrate将首先初始化相机矩阵和失真系数本身,然后在后续优化中修复其中的一部分。这在文件中有说明,尽管相当不清楚,也没有提及关键标志:

除了立体声相关信息外,该功能还可以对两台相机中的每一台进行全面校准。然而,由于参数空间的高维性和输入数据中的噪声,函数可能偏离正确的解。如果可以单独高精度地估计每个相机的内在参数(例如,使用calibrateCamera()),建议您这样做[…]

除了使用任何CV_CALIB_FIX_*标志之外,使用CV_CALIB_USE_INTRINSIC_GUESS还可以告诉函数使用您传递的内容作为输入,否则,此输入将被忽略并覆盖。

CV_CALIB_FIX_OCAL_LENGTH标志使优化例程仅使用内在矩阵中传递的Fx和Fy。