python - Opencv全向标定整改

标签 python c++ opencv camera-calibration fisheye

我有一个广角镜头(>160 度)。我已经尝试过针孔和鱼眼模型,它们似乎提供了清晰的校正图像,但牺牲了一点 FOV。所以我决定尝试一下全向模型。

使用全向模型:

double rms = cv::omnidir::stereoCalibrate(Omni_L.RealP, Omni_L.ImageP, Omni_R.ImageP, Omni_L.img.size(), Omni_R.img.size(), K1, xi1, D1, K2, xi2, D2, rvec, tvec, rvecsL, tvecsL, flags, critia);
std::cout << "RMS : " << rms << std::endl;

立体校准后得到以下结果

RMS : 0.527522

 Camera_Matrix1 :
 [773.9380049495828, 0, 394.6697338356358;
 0, 776.2094223216956, 382.016762545214;
 0, 0, 1]

 Xi-1 :[1.804945374650817]

 Distortion Parameters1:
 [0, 0, -0.009983732008104793, -0.004530718062523464]

 Camera_Matrix2:
 [783.1807043871861, 0, 393.2120687911561;
 0, 784.4790955477508, 386.7954078861521;
 0, 0, 1]

 Xi-2 :[1.837909340970556]

 Distortion Parameters2:
 [0, 0, -0.009779422171305124, -0.003723193186299092]

 rvec :[-0.003821627764900316;
 0.005567569400892289;
 0.001491183114878044]

 tvec:[-63.09243360480385;
 0.1195353275271446;
 0.9082801155496641]

 R: 
 [1, 0, 0;
 0, 1, 0;
 0, 0, 1]

 P: 
 [773.9380049495828, 0, 394.6697338356358;
 0, 776.2094223216956, 382.016762545214;
 0, 0, 1]

然后我做不失真:

    cv::Mat R = cv::Mat::eye(3, 3, CV_32FC1);
    cv::Mat Mapx, Mapy;
    cv::Mat P(3, 3, CV_32FC1);
    P = K1;
    
    cv::Mat orid = cv::imread("Left\\1.jpg");
    std::cout << orid.size();
    std::cout << "R : "<<R<<std::endl;
    std::cout << "P : " << P << std::endl;
    cv::Size s= orid.size();
    try {
        cv::omnidir::initUndistortRectifyMap(K1, D1, xi1, R, P, s, CV_32FC1, Mapx, Mapy, cv::omnidir::RECTIFY_PERSPECTIVE);// Knew, new_size);
        cv::remap(orid, DC, Mapx, Mapy, cv::INTER_CUBIC);
    }
    catch (cv::Exception & e)
    {
        std::cerr << e.msg << std::endl; // output exception message
    }
    std::string Save_Original = "Distorted_Original" + std::to_string(10) + EXT;
    cv::imwrite(Save_Original, orid);
    std::string Save_Corrected = "Distorted_Corrected" + std::to_string(10) + EXT;
    cv::imwrite(Save_Corrected, DC);

问题 1:

为什么径向畸变为零?

问题 2:

经过校正的无失真图像的输出大大降低了 FOV。我的代码有问题吗?

原图: Original Image 失真校正图像: Distortion Corrected

问题 3:

cv::omnidir::initUndistortRectifyMap()函数中的P和R做了什么?

问题 4:

需要有关如何通过全方位校准获得具有更多 FoV 的良好校正图像的想法?


试用后:

  1. @sushi 建议(在下方评论)尝试使用 RECTIFY_CYLINDRICAL 获取相同的图像,结果如下:

    cv::omnidir::RECTIFY_CYLINDRICAL -> 结果更糟

 cv::omnidir::RECTIFY_CYLINDRICAL

最佳答案

首先我建议您阅读本教程:https://docs.opencv.org/master/dd/d12/tutorial_omnidir_calib_main.html 回答您的问题:

  1. 失真系数取决于您选择的失真模型。
  2. 看教程(图像校正部分),如果你想保留所有 fov 你必须将标志更改为 RECTIFY_CYLINDRICAL
  3. P 是校正后图像的"new"相机矩阵,R 是原始空间和对象空间之间的旋转变换。如果您使用 cv::omnidir::undistortImage 对图像进行不失真处理,则可以跳过这两个参数。查看关于knew的推荐值的教程。
  4. 看第2点的答案。

这是我使用 RECTIFY_PERSPECTIVE 方法的结果,我不知道为什么 RECTIFY_CYLINDRICAL 在这种情况下不起作用:This is the result of my approach 要实现它,只需像这样不扭曲您的图像:

cv::Size s = orid.size();
cv::Mat Knew = cv::Mat(cv::Matx33f(s.width / 4, 0, s.width / 2,
        0, s.height / 4, s.width / 2,
        0, 0, 1));
cv::MAt undistorted;
cv::omnidir::undistortImage(orid, undistorted, K1, D1, xi1, cv::omnidir::RECTIFY_PERSPECTIVE, Knew, orid.size());

关于python - Opencv全向标定整改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56950956/

相关文章:

c++ - 使用 STL 在两个排序范围内查找第一个匹配项

opencv - 我如何使用opencv运行Java代码

python - 更新现有的 virtualenv 以使用 Python 3.6

python - 加快循环速度-python

python - 确定一个序列是否在另一个序列中的最佳方法?

c++ - 从不从 std::packaged_task 检索 std::future 的结果是否安全?

c++ - 查找 vector 的 vector 的最大值/最小值

opencv - 如何在 NDK 中获得权限

c++ - cmake opencv for contrib - 配置不完整,发生错误

Python进程不会调用atexit