I'm new here and if I broke any rule please help me to improve.
I'm doing some work on visual localization with a working radius about 300m. So I use a big camera with 4912*3684 resolution. But my camera calibration with a chessboard end up with a high reprojection error over 3.6 pix. The camera_matrix is
[ 3.0126352098515147e+05, 0., 2456.,
0., 4.3598609578377334e+05, 1842.,
0., 0., 1. ]
I realized that fx is far from fy. And the nominal pixel size is 1.25um, the focal length is 755mm. And I refer to some suggestion from this question FindChessboardCorners cannot detect chessboard on very large images by long focal length lens
The likely correct way to proceed is to start at a lower resolution (i.e. downsizing), then scale up the positions of the corners thus found, and use them as the initial estimates for a run of cvFindCornersSubpix at full resolution.
So I resize the input image before cv::findChessboardCorners()
as the code below:
cv::Size msize(1228, 921); //for resolution 4912*3684
int downsize = 4; //downsize scale factor
cv::Mat small; // temp file to downsize the image
cv::resize(imageInput, small, msize);
bool ok = findChessboardCorners(small, board_size, image_points, CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_NORMALIZE_IMAGE);
if(ok){
//rectify the corner
for (size_t j = 0; j < image_points.size(); j++)
{
image_points[j].x = image_points[j].x * downsize;
image_points[j].y = image_points[j].y * downsize;
}
Mat view_gray;
cout << "imageInput.channels()=" << imageInput.channels() << endl;
cvtColor(imageInput, view_gray, CV_RGB2GRAY);
cv::cornerSubPix(view_gray, image_points, cv::Size(11, 11), cv::Size(-1, -1), cv::TermCriteria(CV_TERMCRIT_ITER + CV_TERMCRIT_EPS, 40, 0.01));
image_points_seq.push_back(image_points);
}
double err_first = calibrateCamera(object_points_seq, image_points_seq, image_size, cameraMatrix, distCoeffs, rvecsMat, tvecsMat, CV_CALIB_FIX_K3 | CALIB_FIX_PRINCIPAL_POINT);
And here are my input images: images for calibration
Please tell me how to get an accurate calibration result!!!