00001 #include <cv.h>
00002 #include <highgui.h>
00003 #include <stdio.h>
00004 #include <stdlib.h>
00005 #include <time.h>
00006
00007 int n_boards = 0;
00008 const int board_dt = 20;
00009 int board_w;
00010 int board_h;
00011
00012 int main(int argc, char* argv[])
00013 {
00014 if (argc != 4)
00015 {
00016 printf("ERROR: Wrong number of input parameters\n");
00017 return -1;
00018 }
00019 board_w = atoi(argv[1]);
00020 board_h = atoi(argv[2]);
00021 n_boards = atoi(argv[3]);
00022 int board_n = board_w * board_h;
00023 CvSize board_sz = cvSize( board_w, board_h );
00024 CvCapture* capture = cvCreateCameraCapture( 0 );
00025 assert( capture );
00026 cvNamedWindow( "Calibration" );
00027
00028 CvMat* image_points = cvCreateMat(n_boards*board_n,2,CV_32FC1);
00029 CvMat* object_points = cvCreateMat(n_boards*board_n,3,CV_32FC1);
00030 CvMat* point_counts = cvCreateMat(n_boards,1,CV_32SC1);
00031 CvMat* intrinsic_matrix = cvCreateMat(3,3,CV_32FC1);
00032 CvMat* distortion_coeffs = cvCreateMat(5,1,CV_32FC1);
00033 CvPoint2D32f* corners = new CvPoint2D32f[ board_n ];
00034 int corner_count;
00035 int successes = 0;
00036 int step, frame = 0;
00037 IplImage *image = cvQueryFrame( capture );
00038 IplImage *gray_image = cvCreateImage(cvGetSize(image),8,1);
00039
00040
00041
00042 while (successes < n_boards)
00043 {
00044
00045 if (frame++ % board_dt == 0)
00046 {
00047
00048 int found = cvFindChessboardCorners(
00049 image, board_sz, corners, &corner_count,
00050 CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FILTER_QUADS
00051 );
00052
00053 cvCvtColor(image, gray_image, CV_BGR2GRAY);
00054 cvFindCornerSubPix(gray_image, corners, corner_count,
00055 cvSize(11,11),cvSize(-1,-1), cvTermCriteria(
00056 CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 30, 0.1 ));
00057
00058 cvDrawChessboardCorners(image, board_sz, corners,
00059 corner_count, found);
00060 cvShowImage( "Calibration", image );
00061
00062 if ( corner_count == board_n )
00063 {
00064 step = successes*board_n;
00065 for ( int i=step, j=0; j<board_n; ++i,++j )
00066 {
00067 CV_MAT_ELEM(*image_points, float,i,0) = corners[j].x;
00068 CV_MAT_ELEM(*image_points, float,i,1) = corners[j].y;
00069 CV_MAT_ELEM(*object_points,float,i,0) = j/board_w;
00070 CV_MAT_ELEM(*object_points,float,i,1) = j%board_w;
00071 CV_MAT_ELEM(*object_points,float,i,2) = 0.0f;
00072 }
00073 CV_MAT_ELEM(*point_counts, int,successes,0) = board_n;
00074 successes++;
00075 printf("Sucessfull Capture\n\n");
00076 }
00077 }
00078
00079 int c = cvWaitKey(15);
00080 if (c == 'p')
00081 {
00082 c = 0;
00083 while (c != 'p' && c != 27)
00084 {
00085 c = cvWaitKey(250);
00086 }
00087 }
00088 if (c == 27)
00089 return 0;
00090 image = cvQueryFrame( capture );
00091 }
00092 printf("Collection loop done.\n\n");
00093
00094
00095 CvMat* object_points2 = cvCreateMat(successes*board_n,3,CV_32FC1);
00096 CvMat* image_points2 = cvCreateMat(successes*board_n,2,CV_32FC1);
00097 CvMat* point_counts2 = cvCreateMat(successes,1,CV_32SC1);
00098
00099
00100
00101
00102
00103
00104
00105 for (int i = 0; i<successes*board_n; ++i)
00106 {
00107 CV_MAT_ELEM( *image_points2, float, i, 0) =
00108 CV_MAT_ELEM( *image_points, float, i, 0);
00109 CV_MAT_ELEM( *image_points2, float,i,1) =
00110 CV_MAT_ELEM( *image_points, float, i, 1);
00111 CV_MAT_ELEM(*object_points2, float, i, 0) =
00112 CV_MAT_ELEM( *object_points, float, i, 0) ;
00113 CV_MAT_ELEM( *object_points2, float, i, 1) =
00114 CV_MAT_ELEM( *object_points, float, i, 1) ;
00115 CV_MAT_ELEM( *object_points2, float, i, 2) =
00116 CV_MAT_ELEM( *object_points, float, i, 2) ;
00117 }
00118 for (int i=0; i<successes; ++i)
00119 {
00120 CV_MAT_ELEM( *point_counts2, int, i, 0) =
00121 CV_MAT_ELEM( *point_counts, int, i, 0);
00122 }
00123 cvReleaseMat(&object_points);
00124 cvReleaseMat(&image_points);
00125 cvReleaseMat(&point_counts);
00126
00127
00128
00129
00130 CV_MAT_ELEM( *intrinsic_matrix, float, 0, 0 ) = 1.0f;
00131 CV_MAT_ELEM( *intrinsic_matrix, float, 1, 1 ) = 1.0f;
00132
00133
00134 cvCalibrateCamera2(
00135 object_points2, image_points2,
00136 point_counts2, cvGetSize( image ),
00137 intrinsic_matrix, distortion_coeffs,
00138 NULL, NULL,0
00139 );
00140
00141 cvSave("Intrinsics.xml",intrinsic_matrix);
00142 cvSave("Distortion.xml",distortion_coeffs);
00143
00144
00145
00146 CvMat *intrinsic = (CvMat*)cvLoad("Intrinsics.xml");
00147 CvMat *distortion = (CvMat*)cvLoad("Distortion.xml");
00148
00149
00150
00151 IplImage* mapx = cvCreateImage( cvGetSize(image), IPL_DEPTH_32F, 1 );
00152 IplImage* mapy = cvCreateImage( cvGetSize(image), IPL_DEPTH_32F, 1 );
00153 cvInitUndistortMap(
00154 intrinsic,
00155 distortion,
00156 mapx,
00157 mapy
00158 );
00159
00160
00161
00162 cvNamedWindow( "Undistort" );
00163 while (image)
00164 {
00165 IplImage *t = cvCloneImage(image);
00166 cvShowImage( "Calibration", image );
00167 cvRemap( t, image, mapx, mapy );
00168 cvReleaseImage(&t);
00169 cvShowImage("Undistort", image);
00170
00171 int c = cvWaitKey(15);
00172 if (c == 'p')
00173 {
00174 c = 0;
00175 while (c != 'p' && c != 27)
00176 {
00177 c = cvWaitKey(250);
00178 }
00179 }
00180 if (c == 27)
00181 break;
00182 image = cvQueryFrame( capture );
00183 }
00184 return 0;
00185 }
00186