Camera Calibration Experiment
I use 18 images of Chess Board.
I use OpenCv Cali cpp.
My Camera is Iphone4.
The Intrinsic Matrix K is:
2473.82 0 1296.06
0 2469.12 969.665
0 0 1
The code is:
// Example 11-1. Reading a chessboard¡¯s width and height, reading and collecting the // requested number of views, and calibrating the camera // #include <cv.h> #include <highgui.h> #include <stdio.h> #include <stdlib.h> #include <string> #include <sstream> #include<iomanip> #include<opencv2\core\core.hpp> #include<opencv2\highgui\highgui.hpp> #include<opencv2\imgproc\imgproc.hpp> #include<opencv2\calib3d\calib3d.hpp> #include <opencv2/features2d/features2d.hpp> #include<string> #include<vector> using namespace std; using namespace cv; void zhuanhuan(string src,char* dst) { int i; for(i=0;i<src.length();i++) dst[i]=src[i]; dst[i] = '\0'; } // /* *************** License:************************** Oct. 3, 2008 Right to use this code in any way you want without warrenty, support or any guarentee of it working. BOOK: It would be nice if you cited it: Learning OpenCV: Computer Vision with the OpenCV Library by Gary Bradski and Adrian Kaehler Published by O'Reilly Media, October 3, 2008 AVAILABLE AT: http://www.amazon.com/Learning-OpenCV-Computer-Vision-Library/dp/0596516134 Or: http://oreilly.com/catalog/9780596516130/ ISBN-10: 0596516134 or: ISBN-13: 978-0596516130 OTHER OPENCV SITES: * The source code is on sourceforge at: http://sourceforge.net/projects/opencvlibrary/ * The OpenCV wiki page (As of Oct 1, 2008 this is down for changing over servers, but should come back): http://opencvlibrary.sourceforge.net/ * An active user group is at: http://tech.groups.yahoo.com/group/OpenCV/ * The minutes of weekly OpenCV development meetings are at: http://pr.willowgarage.com/wiki/OpenCV ************************************************** */ // int n_boards = 18; //Will be set by input list int board_w=7; int board_h=7; int main() { int board_n = board_w * board_h; CvSize board_sz = cvSize( board_w, board_h ); cvNamedWindow( "Calibration" ); cvNamedWindow( "Raw Video"); //ALLOCATE STORAGE CvMat* image_points = cvCreateMat(n_boards*board_n,2,CV_32FC1); CvMat* object_points = cvCreateMat(n_boards*board_n,3,CV_32FC1); CvMat* point_counts = cvCreateMat(n_boards,1,CV_32SC1); CvMat* intrinsic_matrix = cvCreateMat(3,3,CV_32FC1); CvMat* distortion_coeffs = cvCreateMat(5,1,CV_32FC1); CvPoint2D32f* corners = new CvPoint2D32f[ board_n ]; int corner_count=0; int successes = 0; int step, frame = 0; IplImage *image1=cvLoadImage("D:\\E\\resource\\odometry experiment\\calibration\\chessImg\\nn1.jpg"); // CAPTURE CORNER VIEWS LOOP UNTIL WE¡¯VE GOT n_boards // SUCCESSFUL CAPTURES (ALL CORNERS ON THE BOARD ARE FOUND) // for (int ii = 1; ii <= n_boards; ii++) { ///¶Áȡ͌Ƭ std::stringstream s; s << "D:\\E\\resource\\odometry experiment\\calibration\\chessImg\\nn" << ii << ".jpg"; std::cout << s.str() << std::endl; string str=s.str(); char* temp=new char[str.length()]; zhuanhuan(str,temp); IplImage *image1=cvLoadImage(temp); IplImage *gray_image1 = cvCreateImage(cvGetSize(image1),8,1);//subpixel //IplImage *image1=cvLoadImage("D:\\E\\resource\\odometry experiment\\calibration\\chessImg\\nn12.jpg"); //IplImage *gray_image1 = cvCreateImage(cvGetSize(image1),8,1);//subpixel cvShowImage("Image1", image1); CvSize tt=cvGetSize(image1); cout<<"tt.width="<<tt.width<<endl; cout<<"tt.height="<<tt.height<<endl; // cvWaitKey(0); cvCvtColor(image1, gray_image1, CV_BGR2GRAY); cvShowImage("gray_image1",gray_image1); // cvWaitKey(0); // image1= cvCloneImage(gray_image1); //cvShowImage("Image1", image1); //cvWaitKey(0); int found = cvFindChessboardCorners( image1, board_sz, corners, &corner_count, CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FILTER_QUADS ); cout<<"found="<<found<<endl; cvFindCornerSubPix(gray_image1, corners, corner_count, cvSize(11,11),cvSize(-1,-1), cvTermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 30, 0.1 )); cvDrawChessboardCorners(image1, board_sz, corners, corner_count, found); cvShowImage( "Calibration", image1 ); //cvWaitKey(0); if( corner_count == board_n ) { step = successes*board_n; for( int i=step, j=0; j<board_n; ++i,++j ) { CV_MAT_ELEM(*image_points, float,i,0) = corners[j].x; CV_MAT_ELEM(*image_points, float,i,1) = corners[j].y; CV_MAT_ELEM(*object_points,float,i,0) = j/board_w; CV_MAT_ELEM(*object_points,float,i,1) = j%board_w; CV_MAT_ELEM(*object_points,float,i,2) = 0.0f; cout<<"corners["<<j<<"].x="<<corners[j].x<<endl; cout<<"corners["<<j<<"].y="<<corners[j].y<<endl; } CV_MAT_ELEM(*point_counts, int,successes,0) = board_n; successes++; } else cvShowImage( "Calibration", gray_image1 ); //Show Gray if we didn't collect the image } cout<<"successes="<<successes<<endl; cvCalibrateCamera2( object_points, image_points, point_counts, cvGetSize( image1 ), intrinsic_matrix, distortion_coeffs, NULL, NULL,0 //CV_CALIB_FIX_ASPECT_RATIO ); int u=0,v=0; for (u=0;u<3;u++) for(v=0;v<3;v++) cout<<"intrinsic_matrix["<<u<<"]["<<v<<"]= "<<CV_MAT_ELEM(*intrinsic_matrix,float,u,v)<<endl; //Skip every board_dt frames to allow user to move chessboard //Find chessboard corners: /* //Get Subpixel accuracy on those corners cvCvtColor(image, gray_image, CV_BGR2GRAY); cvFindCornerSubPix(gray_image, corners, corner_count, cvSize(11,11),cvSize(-1,-1), cvTermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 30, 0.1 )); //Draw it cvDrawChessboardCorners(image, board_sz, corners, corner_count, found); // cvShowImage( "Calibration", image ); // If we got a good board, add it to our data if( corner_count == board_n ) { cvShowImage( "Calibration", image ); //show in color if we did collect the image step = successes*board_n; for( int i=step, j=0; j<board_n; ++i,++j ) { CV_MAT_ELEM(*image_points, float,i,0) = corners[j].x; CV_MAT_ELEM(*image_points, float,i,1) = corners[j].y; CV_MAT_ELEM(*object_points,float,i,0) = j/board_w; CV_MAT_ELEM(*object_points,float,i,1) = j%board_w; CV_MAT_ELEM(*object_points,float,i,2) = 0.0f; } CV_MAT_ELEM(*point_counts, int,successes,0) = board_n; } else cvShowImage( "Calibration", gray_image ); //Show Gray if we didn't collect the image }// End of for collection /* cvDestroyWindow("Calibration"); printf("\n\n*** CALLIBRATING THE CAMERA..."); //ALLOCATE MATRICES ACCORDING TO HOW MANY CHESSBOARDS FOUND CvMat* object_points2 = cvCreateMat(successes*board_n,3,CV_32FC1); CvMat* image_points2 = cvCreateMat(successes*board_n,2,CV_32FC1); CvMat* point_counts2 = cvCreateMat(successes,1,CV_32SC1); //TRANSFER THE POINTS INTO THE CORRECT SIZE MATRICES for(int i = 0; i<9*board_n; ++i){ CV_MAT_ELEM( *image_points2, float, i, 0) = CV_MAT_ELEM( *image_points, float, i, 0); CV_MAT_ELEM( *image_points2, float,i,1) = CV_MAT_ELEM( *image_points, float, i, 1); CV_MAT_ELEM(*object_points2, float, i, 0) = CV_MAT_ELEM( *object_points, float, i, 0) ; CV_MAT_ELEM( *object_points2, float, i, 1) = CV_MAT_ELEM( *object_points, float, i, 1) ; CV_MAT_ELEM( *object_points2, float, i, 2) = CV_MAT_ELEM( *object_points, float, i, 2) ; } for(int i=0; i<9; ++i){ //These are all the same number CV_MAT_ELEM( *point_counts2, int, i, 0) = CV_MAT_ELEM( *point_counts, int, i, 0); } cvReleaseMat(&object_points); cvReleaseMat(&image_points); cvReleaseMat(&point_counts); // At this point we have all of the chessboard corners we need. // Initialize the intrinsic matrix such that the two focal // lengths have a ratio of 1.0 // CV_MAT_ELEM( *intrinsic_matrix, float, 0, 0 ) = 1.0f; CV_MAT_ELEM( *intrinsic_matrix, float, 1, 1 ) = 1.0f; //CALIBRATE THE CAMERA! cvCalibrateCamera2( object_points2, image_points2, point_counts2, cvGetSize( image ), intrinsic_matrix, distortion_coeffs, NULL, NULL,0 //CV_CALIB_FIX_ASPECT_RATIO ); // SAVE THE INTRINSICS AND DISTORTIONS printf(" *** DONE!\n\nStoring Intrinsics.xml and Distortions.xml files\n\n"); cvSave("Intrinsics.xml",intrinsic_matrix); cvSave("Distortion.xml",distortion_coeffs); // EXAMPLE OF LOADING THESE MATRICES BACK IN: // Build the undistort map which we will use for all // subsequent frames. // // Just run the camera to the screen, now showing the raw and // the undistorted image. // */ return 0; }