// 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>
using namespace std;
void help(){
printf("\n\n"
" Calling convention:\n"
" ch11_ex11_1 board_w board_h number_of_boards skip_frames\n"
"\n"
" WHERE:\n"
" board_w, board_h -- are the number of corners along the row and columns respectively\n"
" number_of_boards -- are the number of chessboard views to collect before calibration\n"
" skip_frames -- are the number of frames to skip before trying to collect another\n"
" good chessboard. This allows you time to move the chessboard. \n"
" Move it to many different locations and angles so that calibration \n"
" space will be well covered. \n"
"\n"
" Hit ‘p’ to pause/unpause, ESC to quit\n"
"\n");
}
//
/* *************** 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 = 0; //Will be set by input list
int board_dt = 90; //Wait 90 frames per chessboard view
int board_w;
int board_h;
int main(int argc, char* argv[]) {
//CvCapture* capture_l;//= cvCreateCameraCapture( 0 );
// CvCapture* capture_r;//= cvCreateCameraCapture( 1 );
// assert( capture );
if(argc != 5){
printf("\nERROR: Wrong number of input parameters");
help();
return -1;
}
board_w = atoi(argv[1]);
board_h = atoi(argv[2]);
n_boards = atoi(argv[3]);
board_dt = atoi(argv[4]);
int board_n = board_w * board_h;
CvSize board_sz = cvSize( board_w, board_h );
CvCapture* capture_l = cvCreateCameraCapture( 0 );
CvCapture* capture_r = cvCreateCameraCapture( 1 );
if(!capture_l) { printf("\nCouldn't open the camera\n"); help(); return -1;}
if(!capture_r) { printf("\nCouldn't open the camera\n"); help(); return -1;}
cvNamedWindow( "Calibration_l" );
cvNamedWindow( "Calibration_r" );
cvNamedWindow( "Raw Video_l");
cvNamedWindow( "Raw Video_r");
//ALLOCATE STORAGE
CvMat* image_points_l = cvCreateMat(n_boards*board_n,2,CV_32FC1);
CvMat* image_points_r = 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);
////////////////////////摄像头l参数/////////////////////
CvMat* intrinsic_matrix_l = cvCreateMat(3,3,CV_32FC1);
CvMat* distortion_coeffs_l = cvCreateMat(4,1,CV_32FC1);
////////////////////////摄像头r参数/////////////////////
CvMat* intrinsic_matrix_r = cvCreateMat(3,3,CV_32FC1);
CvMat* distortion_coeffs_r = cvCreateMat(4,1,CV_32FC1);
CvPoint2D32f* corners_l = new CvPoint2D32f[ board_n ];
CvPoint2D32f* corners_r = new CvPoint2D32f[ board_n ];
int corner_count_l;
int corner_count_r;
int successes = 0;
int step, frame = 0;
IplImage *image_l = cvQueryFrame( capture_l );
IplImage *image_r = cvQueryFrame( capture_r );
IplImage *gray_image_l = cvCreateImage(cvGetSize(image_l),8,1);//subpixel
IplImage *gray_image_r = cvCreateImage(cvGetSize(image_r),8,1);
// CAPTURE CORNER VIEWS LOOP UNTIL WE’VE GOT n_boards
// SUCCESSFUL CAPTURES (ALL CORNERS ON THE BOARD ARE FOUND)
//
help();
while(successes < n_boards) {
//Skip every board_dt frames to allow user to move chessboard
if(frame++ % board_dt == 0) {
//Find chessboard corners:
int found_l = cvFindChessboardCorners(
image_l, board_sz, corners_l, &corner_count_l,
CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FILTER_QUADS
);
//Get Subpixel accuracy on those corners
cvCvtColor(image_l, gray_image_l, CV_BGR2GRAY);
cvFindCornerSubPix(gray_image_l, corners_l, corner_count_l,
cvSize(11,11),cvSize(-1,-1), cvTermCriteria(
CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 30, 0.1 ));
//Draw it
cvDrawChessboardCorners(image_l, board_sz, corners_l,
corner_count_l, found_l);
int found_r = cvFindChessboardCorners(
image_r, board_sz, corners_r, &corner_count_r,
CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FILTER_QUADS
);
//Get Subpixel accuracy on those corners
cvCvtColor(image_r, gray_image_r, CV_BGR2GRAY);
cvFindCornerSubPix(gray_image_r, corners_r, corner_count_r,
cvSize(11,11),cvSize(-1,-1), cvTermCriteria(
CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 30, 0.1 ));
//Draw it
cvDrawChessboardCorners(image_r, board_sz, corners_r,
corner_count_r, found_r);
// cvShowImage( "Calibration", image );
// If we got a good board, add it to our data
if(( corner_count_l == board_n )&&( corner_count_r == board_n )) {
cvShowImage( "Calibration_l", image_l ); //show in color if we did collect the image
cvShowImage( "Calibration_r", image_r );
step = successes*board_n;
for( int i=step, j=0; j<board_n; ++i,++j ) {
CV_MAT_ELEM(*image_points_l, float,i,0) = corners_l[j].x;
CV_MAT_ELEM(*image_points_l, float,i,1) = corners_l[j].y;
CV_MAT_ELEM(*image_points_r, float,i,0) = corners_r[j].x;
CV_MAT_ELEM(*image_points_r, float,i,1) = corners_r[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;
successes++;
printf("Collected our %d of %d needed chessboard images\n",successes,n_boards);
}
else
cvShowImage( "Calibration_l", gray_image_l ); //Show Gray if we didn't collect the image
cvShowImage( "Calibration_r", gray_image_r );
} //end skip board_dt between chessboard capture
//Handle pause/unpause and ESC
int c = cvWaitKey(15);
if(c == 'p'){
c = 0;
while(c != 'p' && c != 27){
c = cvWaitKey(250);
}
}
if(c == 27)
return 0;
image_l = cvQueryFrame( capture_l ); //Get next image
image_r = cvQueryFrame( capture_r ); //Get next image
cvShowImage("Raw Video_l", image_l);
cvShowImage("Raw Video_r", image_r);
} //END COLLECTION WHILE LOOP.
cvDestroyWindow("Calibration_l");
cvDestroyWindow("Calibration_r");
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_l = cvCreateMat(successes*board_n,2,CV_32FC1);
CvMat* image_points2_r = 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<su