how do I know which distortion coefficients to use from my calibration

932 views Asked by At

So in the function below

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 is calculated from calibrateCamera resulting in a 1 x 5 Mat of 5 values. Is it safe to assume that these values correspond to K1 K2 P1 P2 K3, in that order? If I want to use the same values in another program that only calls for 4 distortion coefficients, would that correspond to K1 K2 P1 P2? Is it better to include as many coefficients as possible?

Here is the code as per below. My trouble starts when I try to use 5 of my coeffs instead of 4. If I uncomment this line:

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

And expand the matrix here:

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

to

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

then it will produce an exception. So I change 4 to 5 values like the above comment suggests, it breaks.

Here is whole, executable code:

#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;

    
}

0

There are 0 answers