stereoCalibrate()更改焦距,即使它不应该 [英] stereoCalibrate() changes focal lengths even when it was not supposed to

查看:2208
本文介绍了stereoCalibrate()更改焦距,即使它不应该的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我注意到opencv stereoCalibrate()更改相机矩阵的焦距,即使我已设置适当的标志(即CV_CALIB_FIX_FOCAL_LENGTH)。我使用两个相同的相机,相同的焦距机械地设置在镜头上,此外我知道传感器大小,所以我可以手动计算内在的相机矩阵实际上我做什么。



这里你有一些输出形式的立体声校准程序 - 相机矩阵之前和之后的stereoCalibrate()。

  std :: cout< 校准前:< 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<< 校准后:< std :: endl;
std :: cout<< C1:<< _cameraMatrixA< std :: endl;
std :: cout<< C2:<< _cameraMatrixB< std :: endl;




校准前:



p C1:[6203.076923076923,0,1280; 0,
6203.076923076923,960; 0,0,1]



C2:[6203.076923076923,0,1280; 0,6203.076923076923,960; 0,0,
1]



校准后:



C1:[6311.77650416514, 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行为。任何人面临类似的问题?我知道这很容易解决,我可以只是立体声校准后相机矩阵设置焦距。

解决方案

您想要的,您必须使用以下标志呼叫 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 函数使用您传递的内容作为输入,否则,此输入将被忽略并覆盖。


I noticed that opencv stereoCalibrate() changes the focal lengths in camera matrices even though I've set appropriate flag (ie CV_CALIB_FIX_FOCAL_LENGTH). I'm using two identical cameras with the same focal length set mechanically on lens and furthermore I know the sensor size so I can compute intrinsic camera matrix manually what actually I do.

Here you have some output form the stereo calibration program - camera matrices before and after 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]

I think this is weird opencv behavior. Anyone faced similar problem? I know it is easy to solve, I can just set focal lengths to camera matrices after stereo calibration.

解决方案

In order to do what you want, you have to call stereoCalibrate with flags:

CV_CALIB_USE_INTRINSIC_GUESS | CV_CALIB_FIX_FOCAL_LENGTH | CV_CALIB_FIX_PRINCIPAL_POINT

If you do not use the CV_CALIB_USE_INTRINSIC_GUESS flag, stereoCalibrate will first initialize the camera matrices and distortion coefficients itself and then fix part of them in the subsequent optimization. This is stated in the documentation, although rather unclearly and without mentionning that critical flag:

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 [...].

Using CV_CALIB_USE_INTRINSIC_GUESS in addition to any of the CV_CALIB_FIX_* flags tells the function to use what you are passing as input, otherwise, this input is simply ignored and overwritten.

这篇关于stereoCalibrate()更改焦距,即使它不应该的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆