0

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;

    
}

user121903
  • 57
  • 1
  • 1
  • 5
  • I think that in order to properly answer this question you're going to need to look carefully at what version of OpenCV you're using, and which distortion model is being used by each function you're calling. For example, in one case I found that the four distortion coefficients expected were actually obtained by dividing K2, K3, K4, and K5 by K1, which the function being called "assumed" was equal to 1 – Tim Randall Sep 30 '21 at 15:38
  • OpenCV version : 4.4.0. Fisheye lens. – user121903 Sep 30 '21 at 15:45
  • The only way you can be sure you've got the correct meaning for the various constants, I think, is look at the source code for the functions you're calling. Do you have access to that? It should be available online, if I recall. – Tim Randall Sep 30 '21 at 16:45
  • From [documentation](https://docs.opencv.org/4.5.3/d9/d0c/group__calib3d.html#ga3207604e4b1a1758aa66acb6ed5aa65d): "distCoeffs Input/output vector of distortion coefficients (k1,k2,p1,p2[,k3[,k4,k5,k6[,s1,s2,s3,s4[,τx,τy]]]]) of 4, 5, 8, 12 or 14 elements." | Doesn't anyone read that anymore? – Dan Mašek Sep 30 '21 at 16:51
  • I saw that but I am getting an exception when I expand the code to try to include 5 coeffs instead of 4. Will post the code. – user121903 Sep 30 '21 at 20:39
  • I've commented out the problem lines and it works as-as. Uncommenting the lines e.g. where I expand the coefficients from 4 to 5 results in an exception. I guess fisheye module only uses 4 elements? – user121903 Oct 01 '21 at 20:41

0 Answers0