Reputation: 239
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
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
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
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