From d1cbfa3bbf651b7b4952d07b5e253a31bdbccab9 Mon Sep 17 00:00:00 2001 From: mshabunin Date: Thu, 12 Jan 2017 16:54:25 +0300 Subject: [PATCH] ccalib omni_calibration sample updates: - changed default parameter values fr sw, sh - switched to CommandLineParser - added console status messages --- modules/ccalib/samples/omni_calibration.cpp | 135 ++++++++------------ 1 file changed, 50 insertions(+), 85 deletions(-) diff --git a/modules/ccalib/samples/omni_calibration.cpp b/modules/ccalib/samples/omni_calibration.cpp index 578a8803b..594feb532 100644 --- a/modules/ccalib/samples/omni_calibration.cpp +++ b/modules/ccalib/samples/omni_calibration.cpp @@ -11,31 +11,7 @@ using namespace cv; using namespace std; -const char * usage = -"\n example command line for omnidirectional camera calibration.\n" -" omni_calibration -w 6 -h 9 -sw 80 -sh 80 imagelist.xml \n" -" \n" -" the file imagelist.xml is generated by imagelist_creator as\n" -"imagelist_creator imagelist.xml *.*"; - -static void help() -{ - printf("\n This is a sample for omnidirectional camera calibration.\n" - "Usage: omni_calibration\n" - " -w # the number of inner corners per one of board dimension\n" - " -h # the number of inner corners per another board dimension\n" - " [-sw ] # the width of square in some user-defined units (1 by default)\n" - " [-sh ] # the height of square in some user-defined units (1 by default)\n" - " [-o ] # the output filename for intrinsic [and extrinsic] parameters\n" - " [-fs ] # fix skew\n" - " [-fp ] # fix the principal point at the center\n" - " input_data # input data - text file with a list of the images of the board, which is generated by imagelist_creator" - ); - printf("\n %s", usage); -} - -static void calcChessboardCorners(Size boardSize, double square_width, double square_height, - Mat& corners) +static void calcChessboardCorners(const Size &boardSize, const Size2d &squareSize, Mat& corners) { // corners has type of CV_64FC3 corners.release(); @@ -46,7 +22,7 @@ static void calcChessboardCorners(Size boardSize, double square_width, double sq { for (int j = 0; j < boardSize.width; ++j) { - ptr[i*boardSize.width + j] = Vec3d(double(j * square_width), double(i * square_height), 0.0); + ptr[i*boardSize.width + j] = Vec3d(double(j * squareSize.width), double(i * squareSize.height), 0.0); } } } @@ -60,6 +36,7 @@ static bool detecChessboardCorners(const vector& list, vector& l Mat img; for(int i = 0; i < n_img; ++i) { + cout << list[i] << "... "; Mat points; img = imread(list[i], IMREAD_GRAYSCALE); bool found = findChessboardCorners( img, boardSize, points); @@ -70,6 +47,7 @@ static bool detecChessboardCorners(const vector& list, vector& l imagePoints.push_back(points); list_detected.push_back(list[i]); } + cout << (found ? "FOUND" : "NO") << endl; } if (!img.empty()) imageSize = img.size(); @@ -95,8 +73,8 @@ static bool readStringList( const string& filename, vector& l ) } static void saveCameraParams( const string & filename, int flags, const Mat& cameraMatrix, - const Mat& distCoeffs, const double xi, const vector& rvecs, const vector& tvecs, - vector detec_list, const Mat& idx, const double rms, const vector& imagePoints) + const Mat& distCoeffs, const double xi, const vector& rvecs, const vector& tvecs, + vector detec_list, const Mat& idx, const double rms, const vector& imagePoints) { FileStorage fs( filename, FileStorage::WRITE ); @@ -152,7 +130,7 @@ static void saveCameraParams( const string & filename, int flags, const Mat& cam fs << "extrinsic_parameters" << rvec_tvec; } - fs << "rms" << rms; + fs << "rms" << rms; if ( !imagePoints.empty() ) { @@ -169,78 +147,64 @@ static void saveCameraParams( const string & filename, int flags, const Mat& cam int main(int argc, char** argv) { - Size boardSize, imageSize; - int flags = 0; - double square_width = 0.0, square_height = 0.0; - const char* outputFilename = "out_camera_params.xml"; - const char* inputFilename = 0; - vector objectPoints; - vector imagePoints; - - if(argc < 2) + cv::CommandLineParser parser(argc, argv, + "{w||board width}" + "{h||board height}" + "{sw|1.0|square width}" + "{sh|1.0|square height}" + "{o|out_camera_params.xml|output file}" + "{fs|false|fix skew}" + "{fp|false|fix principal point at the center}" + "{@input||input file - xml file with a list of the images, created with cpp-example-imagelist_creator tool}" + "{help||show help}" + ); + parser.about("This is a sample for omnidirectional camera calibration. Example command line:\n" + " omni_calibration -w=6 -h=9 -sw=80 -sh=80 imagelist.xml \n"); + if (parser.has("help") || !parser.has("w") || !parser.has("h")) { - help(); - return 1; + parser.printMessage(); + return 0; } - for(int i = 1; i < argc; i++) + Size boardSize(parser.get("w"), parser.get("h")); + Size2d squareSize(parser.get("sw"), parser.get("sh")); + int flags = 0; + if (parser.get("fs")) + flags |= omnidir::CALIB_FIX_SKEW; + if (parser.get("fp")) + flags |= omnidir::CALIB_FIX_CENTER; + const string outputFilename = parser.get("o"); + const string inputFilename = parser.get(0); + + if (!parser.check()) { - const char* s = argv[i]; - if( strcmp( s, "-w") == 0) - { - if( sscanf( argv[++i], "%u", &boardSize.width ) != 1 || boardSize.width <= 0 ) - return fprintf( stderr, "Invalid board width\n" ), -1; - } - else if( strcmp( s, "-h" ) == 0 ) - { - if( sscanf( argv[++i], "%u", &boardSize.height ) != 1 || boardSize.height <= 0 ) - return fprintf( stderr, "Invalid board height\n" ), -1; - } - else if( strcmp( s, "-sw" ) == 0 ) - { - if( sscanf( argv[++i], "%lf", &square_width ) != 1 || square_width <= 0 ) - return fprintf(stderr, "Invalid square width\n"), -1; - } - else if( strcmp( s, "-sh" ) == 0 ) - { - if( sscanf( argv[++i], "%lf", &square_height) != 1 || square_height <= 0 ) - return fprintf(stderr, "Invalid square height\n"), -1; - } - else if( strcmp( s, "-o" ) == 0 ) - { - outputFilename = argv[++i]; - } - else if( strcmp( s, "-fs" ) == 0 ) - { - flags |= omnidir::CALIB_FIX_SKEW; - } - else if( strcmp( s, "-fp" ) == 0 ) - { - flags |= omnidir::CALIB_FIX_CENTER; - } - else if( s[0] != '-') - { - inputFilename = s; - } - else - { - return fprintf( stderr, "Unknown option %s\n", s ), -1; - } + parser.printErrors(); + return -1; } // get image name list vector image_list, detec_list; if(!readStringList(inputFilename, image_list)) - return fprintf( stderr, "Failed to read image list\n"), -1; + { + cout << "Can not read imagelist" << endl; + return -1; + } // find corners in images // some images may be failed in automatic corner detection, passed cases are in detec_list + cout << "Detecting chessboards (" << image_list.size() << ")" << endl; + vector imagePoints; + Size imageSize; if(!detecChessboardCorners(image_list, detec_list, imagePoints, boardSize, imageSize)) - return fprintf(stderr, "Not enough corner detected images\n"), -1; + { + cout << "Not enough corner detected images" << endl; + return -1; + } // calculate object coordinates + vector objectPoints; Mat object; - calcChessboardCorners(boardSize, square_width, square_height, object); + calcChessboardCorners(boardSize, squareSize, object); for(int i = 0; i < (int)detec_list.size(); ++i) objectPoints.push_back(object); @@ -252,6 +216,7 @@ int main(int argc, char** argv) TermCriteria criteria(3, 200, 1e-8); rms = omnidir::calibrate(objectPoints, imagePoints, imageSize, K, xi, D, rvecs, tvecs, flags, criteria, idx); _xi = xi.at(0); + cout << "Saving camera params to " << outputFilename << endl; saveCameraParams(outputFilename, flags, K, D, _xi, rvecs, tvecs, detec_list, idx, rms, imagePoints); }