The code for the
use OPENCV to calibrate camera is as follows:
void Help (char *argv[]) {} int calib_camera (int argc, char* argv[]) {int n_boards = 0;//is set by input list
float IMAGE_SF = 1.0f;//0.5f;
float delay = 1.f;
int board_w = 0;
int board_h = 0;
if (argc < 4 | | argc > 6) {cout << "\nerror:wrong number of input parameters";
Help (argv);
return-1;
} Board_w = Atoi (argv[1]);
Board_h = Atoi (argv[2]);
N_boards = Atoi (argv[3]);
if (argc > 4) delay = Atof (argv[4));
if (argc > 5) image_sf = Atof (argv[5));
int board_n = Board_w * BOARD_H;
Cv::size BOARD_SZ = cv::size (Board_w, Board_h);
Cv::videocapture Capture (0);
if (!capture.isopened ()) {cout << "\ncouldn ' t open the camera\n";
Help (argv);
return-1;
}//ALLOCATE STORAGE//vector< VECTOR<CV::P oint2f> > image_points;
vector< VECTOR<CV::P oint3f> > object_points; Capture Corner Views:loop until we ' veGot n_boards Successful//captures (all corners on the board are).
Double last_captured_timestamp = 0;
Cv::size image_size;
while (Image_points.size () < (size_t) n_boards) {Cv::mat image0, image;
Capture >> Image0;
Image_size = Image0.size ();
Cv::resize (IMAGE0, Image, Cv::size (), IMAGE_SF, IMAGE_SF, cv::inter_linear);
Find the board//VECTOR<CV::P oint2f> Corners;
BOOL found = cv::findchessboardcorners (image, BOARD_SZ, corners);
Draw IT//drawchessboardcorners (image, BOARD_SZ, corners, found);
If We got a good board, add it to We data//double timestamp = (double) clock ()/clocks_per_sec;
if (found && timestamp-last_captured_timestamp > 1) {last_captured_timestamp = timestamp;
Image ^= Cv::scalar::all (255); Cv::mat mcorners (corners);
Does not copy the data Mcorners *= (1/IMAGE_SF);
Scale the corner coordinates image_points.push_back (corners);
Object_points.push_back (vector<point3f> ());
VECTOR<CV::P oint3f>& opts = Object_points.back ();
Opts.resize (Board_n);
for (int j = 0; j<board_n; j + +) {Opts[j] = CV::P oint3f (float) (J/board_w), (float) (j%board_w), 0.F); } cout << "Collected our" << (int) image_points.size () << "
"<< n_boards <<" needed chessboard images\n "<< Endl; } cv::imshow ("calibration", image);
Show in color if we did collect the image if (Cv::waitkey & 255) = =) return-1;
}//End COLLECTION while loop.
CV::d Estroywindow ("calibration");
cout << "\n\n*** calibrating the camera...\n" << Endl;
Calibrate the camera! Cv::mat Intrinsic_matrix, Distortion_coeffs; Double err = Cv::calibratecamera (object_points, image_points, Image_size, Intrinsic_matri X, Distortion_coeffs, Cv::noarray (), Cv::noarray (), Cv::calib_zero_tangent_dist |
Cv::calib_fix_principal_point);
SAVE the intrinsics and distortions cout << "* * done!\n\nreprojection error is" << err <<
"\nstoring Intrinsics.xml and Distortions.xml files\n\n";
Cv::filestorage FS ("Intrinsics.xml", filestorage::write); FS << "Image_width" << image_size.width << "image_height" << image_size.height << "c
Amera_matrix "<< intrinsic_matrix <<" distortion_coefficients "<< distortion_coeffs;
Fs.release ();
EXAMPLE of LOADING matrices back IN:fs.open ("Intrinsics.xml", Cv::filestorage::read);
cout << "\nimage width:" << (int) fs["image_width"]; cout << "\nimage Height: "<< (int) fs[" Image_height "];
Cv::mat intrinsic_matrix_loaded, distortion_coeffs_loaded;
fs["Camera_matrix"] >> intrinsic_matrix_loaded;
fs["Distortion_coefficients"] >> distortion_coeffs_loaded;
cout << "\nintrinsic matrix:" << intrinsic_matrix_loaded;
cout << "\ndistortion coefficients:" << distortion_coeffs_loaded << Endl;
Build the Undistort map which we'll use for all//subsequent frames.
Cv::mat Map1, MAP2;
Cv::initundistortrectifymap (intrinsic_matrix_loaded, distortion_coeffs_loaded, Cv::mat (),
intrinsic_matrix_loaded, Image_size, CV_16SC2, Map1, MAP2);
Just run the camera to the screens, now showing the raw and//the undistorted image. for (;;)
{Cv::mat image, image0;
Capture >> Image0;
if (Image0.empty ()) break;
Cv::remap (IMAGE0, Image, Map1, MAP2, Cv::inter_linear, Cv::border_constant,
Cv::scalar ());
Cv::imshow ("undistorted", image);
if (Cv::waitkey & 255) =) break;
return 0; }