Lion Kuo
Lion Kuo

Reputation: 239

cvcalibrateCamera2 in C

I am learning how to calibrate camera by using openCV now. And I have some question about how to use cvcalibrateCamera2 function that code in C, not in C++)

The question is, after find the chessboard corner,I want to derive intrinsics and distortion matrix. There is my code:

  IplImage *SrcImage, *GrayImage, *NewImage;
  SrcImage = cvLoadImage(argv[1]);     // RGB
  GrayImage = cvLoadImage(argv[1],0);
  int corner_row=6; //interior number of row corners
  int corner_col=8; //interior number of column corners
  int corner_n=corner_row*corner_col;
  CvSize pattern_size=cvSize(corner_row,corner_col);
  CvPoint2D32f* corners = new CvPoint2D32f[corner_n];
  int corner_count;

  int found=cvFindChessboardCorners(
        GrayImage,
        pattern_size,
        corners,
        &corner_count,
        CV_CALIB_CB_ADAPTIVE_THRESH|CV_CALIB_CB_FILTER_QUADS);

  cvDrawChessboardCorners(
        SrcImage,
        pattern_size,
        corners,
        corner_count,
        found);

  CvMat *object_points = cvCreateMat(corner_n, 3, CV_32FC1);
  CvMat *image_points = cvCreateMat(corner_n, 2, CV_32FC1);
  CvMat *point_counts = cvCreateMat(1, 1, CV_32SC1);
  CvMat *distortion = cvCreateMat(5,1,CV_32FC1);
  CvMat *cameraMatrix = cvCreateMat(3,3,CV_32FC1); 
  cvSet(point_counts,cvScalar(corner_n));

  CV_MAT_ELEM( *cameraMatrix, float, 0, 0 ) = 1.0;
  CV_MAT_ELEM( *cameraMatrix, float, 1, 1 ) = 1.0;

  cvCalibrateCamera2(object_points,image_points,point_counts,pattern_size,
                     cameraMatrix,distortion,NULL,NULL,0);

While I run it, it would make errors like this

For non-planar calibration rigs the initial intrinsic matrix must be specified

And if i replace cvcalibrateCamera2 's 9th parameter 0 by CV_CALIB_USE_INTRINSIC_GUESS, it would make

One of arguments' values is out of range (The intrinsic matrix must have [fx 0 cx; 0 fy cy; 0 0 1] shape)

I really have no idea about this, and all material in the internet is using C++, python or continuous capture photo by camera. So that, i don't know how to adaptive to my code.

Thanks in advance.

Upvotes: 1

Views: 1635

Answers (3)

Rohit Das
Rohit Das

Reputation: 1

I was just having the same issue in C++ and I found out that while using cv::calibrateCamera, The documentation mentions that if we use cv::CALIB_USE_INTRINSIC_GUESS we need to initialize the camera matrix. So, the solution will be

cv::Mat cameraMatrix = (cv:: Mat1d(3, 3)<<
        1,0,0,
        0,1,0,
        0,0,1);
    cv::Mat distCoeffs, R, T;

    cv::calibrateCamera(objp, imgpoints, cv::Size(rows, cols), cameraMatrix, distCoeffs, R, T,cv::CALIB_USE_INTRINSIC_GUESS);
    std::cout << cameraMatrix << std::endl;
    std::cout << distCoeffs << std::endl;
    std::cout << R << std::endl;
    std::cout << T << std::endl;

This situation is only for C++. For python it's pretty simple.

ret, matrix, distortion, r_vecs, t_vecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], camera_matrix, None,flags=cv2.CALIB_USE_EXTRINSIC_GUESS)
    print("Intrinsic Parameter")
    print(matrix)
    print("\nRotation Matrix")
    print(r_vecs)
    print("\nTranslation Matrix")
    print(t_vecs)

Upvotes: 0

Oleksii Balenko
Oleksii Balenko

Reputation: 862

I know, the question is pretty old, but I had the same error when using camera calibration function in javaCV.

If CV_CALIB_USE_INTRINSIC_GUESS and/or CV_CALIB_FIX_ASPECT_RATIO are specified, some or all of fx, fy, cx, cy must be initialized before calling the function. more here

And as error message said your instinct matrix has wrong form. You have added some parameters:

CV_MAT_ELEM( *cameraMatrix, float, 0, 0 ) = 1.0;
CV_MAT_ELEM( *cameraMatrix, float, 1, 1 ) = 1.0;

These is fx and fy parameters. But you also need to add 1 to the 3rd row. Something like this I guess:

CV_MAT_ELEM( *cameraMatrix, float, 2, 2 ) = 1.0;

In my case this helped.

Upvotes: 2

Hannes Ovr&#233;n
Hannes Ovr&#233;n

Reputation: 21831

Your calibration is failing since you are not giving any object or image points to your call to cvCalibrateCamera2. Your matrix object_points should contain the calibration pattern corner coordinates, and image_points should contain the corresponding values in corners.

The first error message is probably because your matrix object_points is uninitialized and contains garbage. These garbage points are not on a plane, which is required by the calibration method unless you give it a guess of the intrinsics.

That said, unless you have very good reasons to not use the C++ interface, I would strongly suggest switching to it.

Upvotes: 0

Related Questions