1
votes

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!!!

1

1 Answers

0
votes

For any calibration to be accurate, you should try considering the following things :

Ensure the focus is correct by verifying it with a simple focus chart. Environment matters, the scene should be less reflective. Calibration depends on the focus chart you use. So it is highly critical to have a focus chart to be flat. Any millimetre level bulges also would affect the calibration. Consider covering the corners to get better distortion coefficients. Use different pattern positions to cover the maximum of the field of view.

Apart from all these, get the calibration error for individual images and you can observe which image has got more error and which one is good. Unfocussed images and blurred images should be simply discarded for the calibration process. It is an easy process if you give your patient time. Have a good time calibrating.