OpenCV fisheye calibration error
I am trying to calibrate a fisheye camera with 120° angle of view. The cv::fisheye::calibrate() function returns me the following error
OpenCV(4.1.0) Error: Internal error (CALIB_CHECK_COND - Ill-conditioned matrix for input array 15) in cv::internal::CalibrateExtrinsics, file c:\build\master_winpack-build-win64-vc15\opencv\modules\calib3d\src\fisheye.cpp, line 1421
I first tried using OpenCV 3.2 and get the same error. Changing the number of chessboard images does not affect the result. Here is the call of the function
cv::fisheye::calibrate(objectPoints, imagePoints, imgSize, cameraMatrix, distCoeffs, rvecs, tvecs, cv::fisheye::CALIB_CHECK_COND);
When using the same inputs with the cv::calibrateCamera() function, I get quite a good estimation of the camera parameters but I believe a fisheye model would be more adapted.
I have done testing with the fisheye calibration vs standard calibration, and I found that the normal calibrateCamera function was much more reliable (almost always produces a reasonable result) compared to the fisheye::calibrate function (which would often fail to produce a result)
Some observations:
1. The fisheye calibration was much better at extrapolating for high distortion lenses than the standard model (I use the 8 parameter rational model)
2. I didn't like the various related functions for using the fisheye model (project points, undistort, etc) as much as the standard functions (to be used with the standard models)
3. By ensuring that I captured calibration points far into the corner of the image, the standard calibration (with rational model) worked very well.
I would also add that it is much easier to get calibration points into the far corners of the image if you use the Charuco calibration target and corresponding function. The reason is that with the standard chessboard you have to be able to see the entire chessboard, which makes it hard to get points into the corners. With the Charuco target you do not need to see the entire chessboard, so you can get points far into the corners.