Strange values for matrix camera and distortion values
I am trying to calibrate a fisheye camera. In order to do that I load a video take with that camera and takes frames where appears a cheesboard pattern. In order to find patterns I use:
bool found = findChessboardCorners(image_to_show, board_sz, corners, CALIB_CB_ADAPTIVE_THRESH | CALIB_CB_NORMALIZE_IMAGE | CALIB_CB_FAST_CHECK);
if(found)
{
cornerSubPix(gray_image, Mat(corners), Size(11, 11), Size(-1, -1), TermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 30, 0.001));
drawChessboardCorners(gray_image, board_sz, Mat(corners), found);
}
when I take 15 pattern I calibrate the camera as follow:
double error = fisheye::calibrate(object_points, image_points, image_to_show.size(), intrinsic, distCoeffs, rvecs, tvecs, fisheye::CALIB_RECOMPUTE_EXTRINSIC | fisheye::CALIB_CHECK_COND | fisheye::CALIB_FIX_SKEW);
In this case the error is: 1.6847, then I print the intrinsic matrix and distortion coeficients and I get
Intrinsic Matrix
[251.48312, 0, 471.14383;
0, 255.30005, 501.81467;
0, 0, 1]
Distortion coefficients
[0.055155002;
0.07189583;
-0.082159713;
0.026405662]
I think this values are wrong because the image resolution is 2048x2048, si cx and cy should be 1024 but the calibration method returns 471 and 501 for that variables.
then I try
fisheye::undistortImage(image_to_show, imageUndistorted, intrinsic, distCoeffs);
But I get a black image in imageUndistorted
This is the undistorted image that I get after calibration
Edit: I modify my program to take images instead of video stream and now I am using a flat chessboard pattern.
If I use the fisheye::undistortImage
the result is the same (more or less) than before, but if I use
Mat newCamMat;
Mat view, result, map1, map2;
fisheye::estimateNewCameraMatrixForUndistortRectify(intrinsic, distCoeffs, image_to_show.size(), Matx33d::eye(), newCamMat, 1);
fisheye::initUndistortRectifyMap(intrinsic, distCoeffs, Matx33d::eye(), newCamMat, image_to_show.size(), CV_16SC2, map1, map2);
remap(image_to_show, result, map1, map2, INTER_LINEAR);
I get something similar to this
.
so, seems that fisheye::undistortImage
doesn't work well. The result that I have obtanined is closer to solution but It still seems wrong. How can I get a better result?
When you look at the images with the detected corner points drawn on, are the detected corners in approximately the right place? And does the chessboard occupy a variety of positions in your images? Could you show some examples of the images you used?
For now i can't show image examples, but I update the question with the calibration result. I can say that the corner in the image are detected in the right place and the chessboard pattern appear in different position and also in different orientations in the input frames.
I update the question with some of the pattern detected (I cut the image to show only the chessboard pattern)
your images look terrible. the board is not plain (laminate it onto something), sometimes corners are not visible, fingers get in the way.
also, rather do this with a list of images, not a video stream, because it's much easier to replace bad images with new , better ones then.
Yes, the camera calibration process expects the chessboard pattern to be completely flat.
I updated the question, now I have modified the program to takes images instead video stream, also now I am using a flat pattern, and I change
fisheye::distortImage
byremap
function but the result still looks wrong