首页 > 解决方案 > 如何从校准中知道要使用哪些失真系数

问题描述

所以在下面的函数中

Mat intrinsic = Mat(3, 3, CV_32FC1);
        Mat distCoeffs;
        vector<Mat> rvecs;
        vector<Mat> tvecs;
        calibrateCamera(object_points, image_points, gray_image.size(), intrinsic, distCoeffs, rvecs, tvecs);//you'll have the intrinsic matrix, distortion coefficients and 

distCoeffs 是从 calibrateCamera 计算得出的,得到 5 个值的 1 x 5 Mat。假设这些值按顺序对应于 K1 K2 P1 P2 K3 是否安全?如果我想在另一个只需要 4 个失真系数的程序中使用相同的值,那会对应于 K1 K2 P1 P2 吗?包含尽可能多的系数会更好吗?

这是下面的代码。当我尝试使用 5 个系数而不是 4 个系数时,我的麻烦就开始了。如果我取消注释这一行:

//distCoeffs.at<double>(4) = CV_P3; // 5th value

并在这里展开矩阵:

cv::Mat distCoeffs = cv::Mat(1, 4, CV_64F, double(0));

cv::Mat distCoeffs = cv::Mat(1, 5, CV_64F, double(0));

那么它会产生一个异常。因此,我将 4 到 5 个值更改为上述评论建议的值,它会中断。

这是完整的可执行代码:

#include <iostream>
#include <opencv2/highgui.hpp>
#include <opencv2/calib3d.hpp>
#include <opencv2/core/mat.hpp>

// set mats
/**/
using namespace std;
using namespace cv;

void set_camIntrinsics(Mat &cam_intrinsic, Mat &distCoeffs)
{
    //set_intriniscs 
    double  CV_CX = 386.6963736491591,
        CV_CY = 234.7746525148251,
        CV_FX = 260.257998425127,
        CV_FY = 260.1583925187085;


    cam_intrinsic.at<double>(0, 0) = CV_FX;
    cam_intrinsic.at<double>(1, 0) = 0.0;
    cam_intrinsic.at<double>(2, 0) = 0.0;

    cam_intrinsic.at<double>(0, 1) = 0.0;
    cam_intrinsic.at<double>(1, 1) = CV_FY;
    cam_intrinsic.at<double>(2, 1) = 0.0;

    cam_intrinsic.at<double>(0, 2) = CV_CX;
    cam_intrinsic.at<double>(1, 2) = CV_CY;
    cam_intrinsic.at<double>(2, 2) = 1.0;
    // new coeffs 11.29.19

    double  CV_K1 = -0.2666308246430311,
        CV_K2 = 0.06474699227144737,
        CV_P1 = 0.0003621024764932747,
        CV_P2 = -0.000726010205813438,
        CV_P3 = -0.006384634912197317;


    distCoeffs.at<double>(0) = CV_K1;
    distCoeffs.at<double>(1) = CV_K2;
    distCoeffs.at<double>(2) = CV_P1;
    distCoeffs.at<double>(3) = CV_P2;
    //distCoeffs.at<double>(4) = CV_P3; otherwise creates exception
}
int main()
{

    cv::Mat cam_intrinsic = cv::Mat(3, 3, CV_64F, double(0));
    cv::Mat distCoeffs = cv::Mat(1, 4, CV_64F, double(0));
    // cv::Mat distCoeffs = cv::Mat(1, 5, CV_64F, double(0));

    set_camIntrinsics(cam_intrinsic, distCoeffs);

    cv::Mat input_frame = cv::imread("fisheye_pic.png");
    cv::Mat output_frame;

    cv::fisheye::undistortImage(input_frame, output_frame, cam_intrinsic, distCoeffs, cv::noArray(), cv::Size(input_frame.cols, input_frame.rows));

    cv::imshow("Input Image", input_frame);
    //cv::imshow("Output Image", output_frame);
    cv::waitKey(-1);
    return 0;

    
}

标签: c++opencvcamera-calibrationcamera-intrinsics

解决方案


推荐阅读