123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- #include "opencv2/ccalib/randpattern.hpp"
- #include "opencv2/highgui.hpp"
- #include "opencv2/imgproc.hpp"
- #include "opencv2/calib3d.hpp"
- #include <vector>
- #include <iostream>
- #include <time.h>
- using namespace std;
- using namespace cv;
- const char * usage =
- "\n example command line for calibrate a camera by random pattern. \n"
- " random_pattern_calibration -pw 600 -ph 850 -mm 20 image_list.xml \n"
- "\n"
- " the file image_list.xml is generated by imagelist_creator as\n"
- "imagelist_creator image_list.xml *.*";
- static void help()
- {
- printf("\n This is a sample for camera calibration by a random pattern.\n"
- "Usage: random_pattern_calibration\n"
- " -pw <pattern_width> # the physical width of random pattern\n"
- " -ph <pattern_height> # the physical height of random pattern\n"
- " -mm <minimal_match> # minimal number of matches\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 bool readStringList( const string& filename, vector<string>& l )
- {
- l.resize(0);
- FileStorage fs(filename, FileStorage::READ);
- if( !fs.isOpened() )
- return false;
- FileNode n = fs.getFirstTopLevelNode();
- if( n.type() != FileNode::SEQ )
- return false;
- FileNodeIterator it = n.begin(), it_end = n.end();
- for( ; it != it_end; ++it )
- l.push_back((string)*it);
- return true;
- }
- static void saveCameraParams(const string& filename, Size imageSize, float patternWidth,
- float patternHeight, int flags, const Mat& cameraMatrix, const Mat& distCoeffs,
- const vector<Mat>& rvecs, const vector<Mat>& tvecs, double rms)
- {
- FileStorage fs (filename, FileStorage::WRITE );
- time_t tt;
- time( &tt );
- struct tm *t2 = localtime( &tt );
- char buf[1024];
- strftime( buf, sizeof(buf)-1, "%c", t2 );
- fs << "calibration_time" << buf;
- if( !rvecs.empty())
- fs << "nframes" << (int)rvecs.size();
- fs << "image_width" << imageSize.width;
- fs << "image_height" << imageSize.height;
- fs << "pattern_width" << patternWidth;
- fs << "pattern_height" << patternHeight;
- fs << "flags" <<flags;
- fs << "camera_matrix" << cameraMatrix;
- fs << "distortion_coefficients" << distCoeffs;
- fs << "rms" << rms;
- if( !rvecs.empty() && !tvecs.empty() )
- {
- CV_Assert(rvecs[0].type() == tvecs[0].type());
- Mat bigmat((int)rvecs.size(), 6, rvecs[0].type());
- for( int i = 0; i < (int)rvecs.size(); i++ )
- {
- Mat r = bigmat(Range(i, i+1), Range(0,3));
- Mat t = bigmat(Range(i, i+1), Range(3,6));
- CV_Assert(rvecs[i].rows == 3 && rvecs[i].cols == 1);
- CV_Assert(tvecs[i].rows == 3 && tvecs[i].cols == 1);
- //*.t() is MatExpr (not Mat) so we can use assignment operator
- r = rvecs[i].t();
- t = tvecs[i].t();
- }
- //cvWriteComment( *fs, "a set of 6-tuples (rotation vector + translation vector) for each view", 0 );
- fs << "extrinsic_parameters" << bigmat;
- }
- }
- int main(int argc, char** argv)
- {
- const char* inputFilename = 0;
- const char* outputFilename = "out_camera_params.xml";
- vector<string> imglist;
- vector<Mat> vecImg;
- int flags = 0;
- float patternWidth = 0.0f, patternHeight = 0.0f;
- int nMiniMatches = 0;
- if(argc < 2)
- {
- help();
- return 1;
- }
- for (int i = 1; i < argc; ++i)
- {
- const char* s = argv[i];
- if(strcmp(s, "-pw") == 0)
- {
- if(sscanf(argv[++i], "%f", &patternWidth) != 1 || patternWidth <= 0)
- return fprintf( stderr, "Invalid pattern width\n"), -1;
- }
- else if(strcmp(s, "-ph") == 0)
- {
- if(sscanf(argv[++i], "%f", &patternHeight) != 1 || patternHeight <= 0)
- return fprintf( stderr, "Invalid pattern height\n"), -1;
- }
- else if (strcmp(s, "-mm") == 0)
- {
- if (sscanf(argv[++i], "%d", &nMiniMatches) != 1 || nMiniMatches < 15)
- return fprintf( stderr, "Invalid number of minimal matches or number is too small"), -1;
- }
- else if( strcmp( s, "-fp" ) == 0 )
- {
- flags |= CALIB_FIX_PRINCIPAL_POINT;
- }
- else if( s[0] != '-')
- {
- inputFilename = s;
- }
- else
- {
- return fprintf( stderr, "Unknown option %s\n", s ), -1;
- }
- }
- readStringList(inputFilename, imglist);
- // the first image is the pattern
- Mat pattern = cv::imread(imglist[0], cv::IMREAD_GRAYSCALE);
- for (int i = 1; i < (int)imglist.size(); ++i)
- {
- Mat img;
- img = cv::imread(imglist[i], cv::IMREAD_GRAYSCALE);
- vecImg.push_back(img);
- }
- randpattern::RandomPatternCornerFinder finder(patternWidth, patternHeight, nMiniMatches);
- finder.loadPattern(pattern);
- finder.computeObjectImagePoints(vecImg);
- vector<Mat> objectPoints = finder.getObjectPoints();
- vector<Mat> imagePoints = finder.getImagePoints();
- Mat K;
- Mat D;
- vector<Mat> rvec, tvec;
- double rms = calibrateCamera(objectPoints, imagePoints, vecImg[0].size(), K, D, rvec, tvec);
- saveCameraParams(outputFilename, vecImg[0].size(), patternWidth, patternHeight, flags, K, D, rvec, tvec, rms);
- }
|