Based on the Zhang Zhengyu calibration method of the Opencv3.1 calibration program, first use Findchessboard to find the board, with Cornersubpix sub-pixel positioning, and then use Calibratecamera to the calibration, and finally the calibration results stored in the XML file
The program is based on vs2013 and opencv3.1, to note that there are 3.1 before 2XX series many places different, many functions are different, the specific situation of the code,
Novice, it is inevitable to commit such as switch statement no default and other errors, the big God see please tap ...
/************************************************************************************ @COPYRIGHT NOTICE* @ Copyright (c), lizichuan* @All rights reserved file name: 0.0, camera open. CPP Version: Ver 1.0 Author: lizichuan Date: 2016/3/22 13:3 7 Introduction: 0.0, checker reading and calibration ***********************************************************************************//********* Function: Header file, namespace contains part description: ************************ /#include "stdafx.h" #include "windows.h"//#include "stdio.h" #include "string" #include "iostream" #include "opencv2/core.hpp" #include "opencv2/highgui/highgui.hpp" #include " Opencv2/imgproc/imgproc.hpp "#include" opencv2/opencv.hpp "#include" opencv2/calib3d.hpp "#include" opencv2/ Xfeatures2d.hpp "using namespace std;using namespace cv;using namespace cv::xfeatures2d;/**************************** function: Macro Definition part Description: *****************************************************************************/ /*********************************************** Function: Global variable declaration description: *************************************************************** //***************************************************************************** Function: global function declaration strokes *****************************************************************************///writes Matrix void UprintMatrix to an XML file ( Cvfilestorage *fs, Mat Umatrix, String uname);//write to XML file Matrix group void Uprintvectormat (Cvfilestorage *fs, vector<mat> Umatrix, string uname);//display matrix void Printfmatrix (Mat umatrix);//display Matrix group void Printfvectormat (vector<mat> umatrix); Function name: main () function function: Author: lizichuan date : 2016/3/22 13:40*****************************************************************************/int _tmain (int argc , _tchar* argv[]) {//1, calibration preparation//Parameter Preparation const DOUBLE reallengthofchess = 20.2;//Checkerboard Gertanger actual width const int chessboard_num = 32;//Checkerboard number-calibration image Read Const int board_wide_num = 9;//Checkerboard number of squares per row const int Board_heigh _num = 9;//Checkerboard number of squares per column Mat Tempimage, Tempimage_gray, TempImage1, tempimage_gray1;//define original image and grayscale map vector<point2f> Corners, corners1;//each detected corner coordinate vector<vector<point2f>> imagepoints, imagepoints1;// Defines a two-dimensional coordinate group that detects a corner in an image vector<vector<point3f>> Objectpoints, objectpoints1;//defines a two-dimensional coordinate group that detects corner points in practice BOOL flag _chess_find, flag_chess_find_1;//defines the flag bit videocapture cap (0) for the Board detection Success,//defines the video stream Namedwindow ("Checkerboard Corner Detection", window_autosize);// Create source Video window () Namedwindow ("After calibration and correction", window_autosize);//Create Corrective video window//termcriteria criteria = Termcriteria (Termcriteria:: EPS + Termcriteria::max_iter, 0.00001), Cap >> tempimage;//capture Video size imageSize = Size (Tempimage.cols, tempimage.rows);//define Capture video window size//2, calibration and display results, corrective and display image while (true) {//2.1, start calibration cout << "program ready to finish, press ' C ' to start capturing images" < < Endl;if (Waitkey (0) = = ' C ') {//2.1.1, starts nth-time image reading and detects a checkerboard chart, with calibration for (int detecttime = 0; Detecttime < ChessboarD_num; ++detecttime) {//2.1.1.1, capture image from camera cout << "Press ' V ' to start detection checker" << endl;bool Continue_flag = 0;// Defines a Boolean variable as a marker for successful checkerboard detection//continuously loops through the image until the V button is pressed for checker detection while (1) {cap >> tempimage;//capture Video Cvtcolor (Tempimage, Tempimage_ Gray, Cv_bgr2gray);//will capture the video into grayscale imshow ("Checkerboard Corner Detection", tempimage);//display source video//press V, start capture image if (Waitkey (1) = = ' V ') {//Detect checker, and generate detection success flag bit flag_chess_find = Findchessboardcorners (Tempimage, Size (9, 9), corners, Cv_calib_cb_adaptive_thresh + CV_ Calib_cb_fast_check);//If the detection succeeds, the corners are drawn according to the order of different colors, and if unsuccessful, the detected corner points are drawn in red drawchessboardcorners (Tempimage, Size (9, 9), corners , flag_chess_find);//Display corner imshow ("Checkerboard Corner Detection", tempimage) cout << "<< detecttime <<" sub-board test results as follows, v Press ' C ' Continue calibration, press ' R ' to re-detect ' << endl;//wait for key switch (Waitkey (0)) {case ' C ': Continue_flag = 1;default:break;}} Depending on the result of the previous function, if you press C to jump out of the loop to perform the next step, continue looping through the capture video if (Continue_flag) break;} 2.1.1.2, if the corner detection is successful, sub-pixel focus is positioned and the corner coordinates are stored in the coordinate group if (corners.size () > 2) {//Subpixel corner detection Cornersubpix (Tempimage_gray, corners, Size (5, 5), size ( -1,-1), Termcriteria (TermcritEria::eps + termcriteria::max_iter, 1000, 0.00001);//Draw the image and display for (int i = 0; i < corners.size (); i++) {Circle (Tempimage, Corners[i], 8, Scalar (40, 25, 255), 2, 8);} Imshow ("Checkerboard Corner Detection", tempimage);//display text prompts and cycle through the detected checkerboard corner coordinates cout << "checkerboard Geya pixel precise positioning results as follows" << endl;cout << " Number of board detection corner points: "<< corners.size () << endl;for (int i = 0; i < corners.size (); i++) {if (i%2 = = 0)//If it is even the next time you continue writing ( Corner marking starting at 0) {cout << corner << i << "exact coordinates:" << corners[i].x << "," << corners[i].y;} else//if it is an odd number, the next carriage return {cout << corner << i << "exact coordinates:" << corners[i].x << "," << corners[i ].y << Endl;}} cout << endl;cout << "First" << Detecttime + 1 << "The end of the board detection" << endl;cout << "Press ' R ' to re-perform this test, Press ' C ' for next detection << endl;//wait button, if you press C to save corner coordinates, press R to re-detect the checkerboard get corner coordinates switch (waitkey (0)) {case ' R ': detecttime = detecttime- 1;//This test result is void, re-detect case ' C '://The corner coordinates are deposited in a double coordinate group {vector<point2f> imagepoints_temp;//defines a temporary corner point two-dimensional coordinate group VectoR<point3f> objectpoints_temp;//defines a temporary corner point two-dimensional coordinate group for (int j = 0; J < corners.size (); ++j)//Use the loop to turn the detected corner coordinates into a temporary corner point coordinate group {point2f imgpoint_temp2; point3f objpoint_temp2;imgpoint_temp2.x = Corners[j].x;imgpoint_temp2.y = corners[j].y;objpoint_temp2.x = j% Board_ Wide_num * (float) reallengthofchess) objpoint_temp2.y = J/board_wide_num * ((float) reallengthofchess); Objpoint_ Temp2.z = 0;imagepoints_temp.push_back (IMGPOINT_TEMP2); Objectpoints_temp.push_back (OBJPOINT_TEMP2);} Imagepoints.push_back (imagepoints_temp);//The two-dimensional coordinate group Objectpoints.push_back (objectpoints_temp) of the temporary angular point coordinate group in the corner of the image;// The temporary corner Point coordinate group is deposited into the two-dimensional coordinate group of the actual corner point}}}//2.1.1.3, if the detection fails, wait for the next checkerboard detection or exit Else{cout << "Checker failed, press ' R ' to re-detect, press ' Q ' to exit" << " The number of detections is "<< corners.size () << endl;switch (Waitkey (0)) {case ' R ':d etecttime = Detecttime-1;default:return fals e;}}} 2.1.2, according to the previous corner point coordinates subpixel detection results, Camera calibration Mat Intrinsic_matrix (3, 3, cv_64f), Distortion_coeffs (8, 1, cv_64f);vector<mat> Rvecs, tvecs;//defines the set of rotation vector groups and the group of double TIME0 = GetTickCount ();//2.1.3, the calibration Calibratecamera (objectpoints,//angle point of the actual coordinates imagepoints,//corner of the image coordinates imagesize,//calibration image size intrinsic_matrix,// In-camera parameter matrix distortion_coeffs,//distortion parameter matrix rvecs,//rotation vector Group tvecs//translation Vector Group)//2.1.4, calibration cout << "camera calibration End, Time:" << ( GetTickCount ()-TIME0)/1000 << "milliseconds, the calibration results are as follows:" << endl;//2.1.5, Calculating calibration error: Double total_error_value = 0.0, error_ value[chessboard_num];for (int i = 0; i < chessboard_num; i++) {vector<point2f> imagepoints2;// Define a temporary image corner point two-dimensional coordinate group//calculate the actual corner point on the image coordinates based on the rotation vector, the translation vector, the internal reference matrix and the camera Distortion matrix projectpoints (objectpoints[i],//angle Point actual coordinates rvecs[i],// Rotation vector tvecs[i],//translation vector intrinsic_matrix,//the reference matrix distortion_coeffs,//distortion Matrix imagepoints2//Store the computed image corner coordinates); Mat Tempimagepointmat = Mat (1, imagepoints[i].size (), CV_32FC2);//Create a matrix of image coordinates for storing corner points Matimagepoints2mat = Mat (1, Imagepoints2.size (), CV_32FC2);//Create a matrix for (int j = 0; J < Imagepoints[i].size ()) of the image coordinate theory value used to store the corner points { Imagepoints2mat.at<vec2f> (0, j) = vec2f (imagepoints2[j].x, IMAGEPOINTS2[J].Y);// The corner image coordinates are deposited into the matrix tempimagepointmat.at<vec2f> (0, j) = vec2f (imagepoints[i][j].x, IMAGEPOINTS[I][J].Y);//The corner image coordinates theoretical value into the matrix}error_value[i] = Norm (Imagepoints2mat, Tempimagepointmat, NORM_L2);// Normalized the image coordinate and the image coordinate theory value total_error_value + = Error_value[i]/= imagepoints[i].size ();//results accumulate and divide by corner points cout << "section" < < i + 1 << "image average error:" << error_value[i] << "Pixels" << Endl;} cout << "Overall average error:" << total_error_value/chessboard_num << "Pixels" << endl;//2.1.6, showing calibration results// The results are displayed on the command desk printf ("Camera reference matrix: \ n"); Printfmatrix (Intrinsic_matrix);p rintf ("Camera distortion matrix: \ n"); Printfmatrix (distortion_coeffs);p rintf ("rotation vector Group: \ n"); Printfvectormat (rvecs);p rintf ("translation vector Group: \ n"); Printfvectormat (tvecs);//2.1.7, store calibration result//definition file storage pointer cvfilestorage *fs = cvopenfilestorage ("123.xml",//File name 0,cv_storage _write,//mode is write mode "GB2312"//Text encoding); Cvwritecomment (FS, "This file is used to record the calibration result. ", 0);//write a phrase to the file//store the calibration result cvwritecomment (FS," Calibration parameters are as follows: ", 0);//write a phrase to the file Uprintmatrix (FS, Intrinsic_matrix," Camera reference Matrix ");// Write camera Reference Uprintmatrix (FS, distortion_coeffs, "Camera distortion Matrix");//write Distortion Matrix Uprintvectormat (FS, rvecs, "rotation vector Group");//write rotation vector Group UprintvEctormat (FS, tvecs, "translation vector Group");//write translation Vector Group Cvwritecomment (FS, "Calibration parameter write end", 0);//write phrase to File//Store calibration Error cvwritecomment (FS, " The calibration error is as follows: ", 0);//write a phrase to the file Cvwritereal (FS," Total_average_error ", total_error_value/chessboard_num);// Write the average error of all pictures cvwritecomment (FS, "Each image calibration error is as follows:", 0);//write a phrase for (int i = 0; i < Chessboard_num; i++) {cvwritecomment (FS, " Photo_counter ", 0); Cvwritereal (FS," Error_value ", Error_value[i]);//write each picture error}cvwritecomment (FS," End of error write ", 0);// Write a phrase to the file//save corner coordinates cvwritecomment (FS, "Corner image coordinates:", 0);//write the phrase for (int i = 0; i < Chessboard_num; i++) {Cvwriteint (FS, "Pho Tes_counter ", I); for (int j = 0; J < Corners.size (); j + +) {Cvwriteint (FS," Corners_counter ", j);//write corner number float Temp_coord Inate[] = {imagepoints[i][j].x, imagepoints[i][j].y};//defines a temporary variable for output coordinates cvstartwritestruct (FS, "coordinates", CV_NODE_ SEQ);//start writing the struct Cvwriterawdata (FS, temp_coordinate, 2, "F");//write Coordinate cvendwritestruct (fs);//struct Write end}}cvwritecomment (FS, "Corner image coordinates write end", 0);//write a phrase to the file cvwritecomment (FS, "Corner Real Coordinates:", 0);//write a phrase for the file for (int i = 0; I &Lt Chessboard_num; i++) {cvwriteint (FS, "Photos_counter", I), for (int j = 0; J < Corners.size (); j + +) {Cvwriteint (FS, "Corners_counter", j); Write corner ordinal float temp_coordinate[] = {objectpoints[i][j].x, objectpoints[i][j].y, Objectpoints[i][j].z};// Defines a temporary variable for output coordinates cvstartwritestruct (FS, "coordinates", cv_node_seq);//start writing to struct Cvwriterawdata (FS, temp_coordinate, 3, "F" );//write Coordinate cvendwritestruct (fs);//struct Write end}}cvwritecomment (FS, "Corner actual coordinate write end", 0);//write phrase cvreleasefilestorage to file (&fs )///File write end, release the file pointer//2.1.8, use the calibration results to correct the acquisition of the image, and display it cout << "display corrective results, press ' W ' key to continue" << endl;//continuously cycle display corrected image while (true) { Mat srcimage, srcimage1;//definition temp matrix variable cap >> srcimage;//capture image from Camera//corrective Undistort (srcimage,//input source image srcimage1,// Store corrected image intrinsic_matrix,//Internal reference matrix distortion_coeffs//distortion matrix) imshow ("Checkerboard Corner Detection", srcimage);//Display Results imshow ("After calibration and correction", SRCIMAGE1); if (Waitkey (5) = = ' Q ') break; cout << "This round calibration end, press ' Q ' key to exit, ' R ' key for next round calibration" << Endl; 2.2, if press Q, then exit the loop, press R, re-calibration if (waitkey (0) = = ' Q ') {break;} Else{while (Waitkey (0)! = ' R ');}} return 0;}/***************************************************************************** function Name: UprintVectorMat () function function: By: Lizichuan Date: 2016/3/26 20:06 *****************************************************************************/ void Uprintvectormat (Cvfilestorage *fs, vector<mat> Umatrix, String uname) {cvwritecomment (FS, Uname.c_str (), 0) ;//successively by matrix, by row, by column write matrix group value for (int i = 0; i < umatrix.size (); + + i) {cvwriteint (FS, "Mat_number", I); for (int j = 0; J < um Atrix[i].rows; + + j) {for (int k = 0; k < umatrix[i].cols; ++k) {cvwritereal (FS, "Value", Umatrix[i].at<double> (J, k));}}} Cvwritecomment (FS, "Write End", 0);} /***************************************************************************** function Name: UprintMatrix () function function: By: Lizichuan Date: 2016/3/26 20:21 *****************************************************************************/void Uprintmatrix (Cvfilestorage *fs, Mat Umatrix, String uname) {cvwritecomment (FS, Uname.c_str (), 0);//row by column write matrix value for (int i = 0; i < umatrix.rows; + + i) {for (int j = 0; J < Umatrix.cols; + + j) {Cvwritereal (FS, "Value", Umatrix.at<double> (i, J));}} Cvwritecomment (FS, "Write End", 0);} /***************************************************************************** function Name: PrintfMatrix () function function: By: Lizichuan Date: 2016/3/26 20:51 *****************************************************************************/void Printfmatrix (Mat Umatrix) {for (int i = 0; i < umatrix.rows; + + i) {for (int j = 0; J < Umatrix.cols; + + j) {printf (" %lf ", Umatrix.at<double> (i, J));} printf ("\ n");} printf ("\ n");} /***************************************************************************** function Name: PrintfVectorMat () function function: By: Lizichuan Date: 2016/3/26 20:51 *****************************************************************************/V OID Printfvectormat (vector<mat> Umatrix) {for (int i = 0; i < umatrix.size (); + + i) {for (int j = 0; J < Umatrix [I].rows; + + j) {for (int k= 0; K < Umatrix[i].cols; + + k) {printf ("%lf", Umatrix[i].at<double> (J, k));} printf ("\ n");} printf ("\ n");}}
OPENCV Series "2", a simple calibration and storage of the results of the program