|
|
@ -75,7 +75,7 @@ void help() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
enum { DETECTION = 0, CAPTURING = 1, CALIBRATED = 2 }; |
|
|
|
enum { DETECTION = 0, CAPTURING = 1, CALIBRATED = 2 }; |
|
|
|
enum Pattern { CHESSBOARD, CIRCLESGRID }; |
|
|
|
enum Pattern { CHESSBOARD, CIRCLES_GRID, ASYMMETRIC_CIRCLES_GRID }; |
|
|
|
|
|
|
|
|
|
|
|
static double computeReprojectionErrors( |
|
|
|
static double computeReprojectionErrors( |
|
|
|
const vector<vector<Point3f> >& objectPoints, |
|
|
|
const vector<vector<Point3f> >& objectPoints, |
|
|
@ -103,18 +103,34 @@ static double computeReprojectionErrors( |
|
|
|
return std::sqrt(totalErr/totalPoints); |
|
|
|
return std::sqrt(totalErr/totalPoints); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void calcChessboardCorners(Size boardSize, float squareSize, vector<Point3f>& corners) |
|
|
|
static void calcChessboardCorners(Size boardSize, float squareSize, vector<Point3f>& corners, Pattern patternType = CHESSBOARD) |
|
|
|
{ |
|
|
|
{ |
|
|
|
corners.resize(0); |
|
|
|
corners.resize(0); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
switch(patternType) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
case CHESSBOARD: |
|
|
|
|
|
|
|
case CIRCLES_GRID: |
|
|
|
for( int i = 0; i < boardSize.height; i++ ) |
|
|
|
for( int i = 0; i < boardSize.height; i++ ) |
|
|
|
for( int j = 0; j < boardSize.width; j++ ) |
|
|
|
for( int j = 0; j < boardSize.width; j++ ) |
|
|
|
corners.push_back(Point3f(float(j*squareSize), |
|
|
|
corners.push_back(Point3f(float(j*squareSize), |
|
|
|
float(i*squareSize), 0)); |
|
|
|
float(i*squareSize), 0)); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case ASYMMETRIC_CIRCLES_GRID: |
|
|
|
|
|
|
|
for( int i = 0; i < boardSize.height; i++ ) |
|
|
|
|
|
|
|
for( int j = 0; j < boardSize.width; j++ ) |
|
|
|
|
|
|
|
corners.push_back(Point3f(float((2*j + i % 2)*squareSize), |
|
|
|
|
|
|
|
float(i*squareSize), 0)); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
default: |
|
|
|
|
|
|
|
CV_Error(CV_StsBadArg, "Unknown pattern type\n"); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static bool runCalibration( vector<vector<Point2f> > imagePoints, |
|
|
|
static bool runCalibration( vector<vector<Point2f> > imagePoints, |
|
|
|
Size imageSize, Size boardSize, |
|
|
|
Size imageSize, Size boardSize, Pattern patternType, |
|
|
|
float squareSize, float aspectRatio, |
|
|
|
float squareSize, float aspectRatio, |
|
|
|
int flags, Mat& cameraMatrix, Mat& distCoeffs, |
|
|
|
int flags, Mat& cameraMatrix, Mat& distCoeffs, |
|
|
|
vector<Mat>& rvecs, vector<Mat>& tvecs, |
|
|
|
vector<Mat>& rvecs, vector<Mat>& tvecs, |
|
|
@ -128,7 +144,7 @@ static bool runCalibration( vector<vector<Point2f> > imagePoints, |
|
|
|
distCoeffs = Mat::zeros(8, 1, CV_64F); |
|
|
|
distCoeffs = Mat::zeros(8, 1, CV_64F); |
|
|
|
|
|
|
|
|
|
|
|
vector<vector<Point3f> > objectPoints(1); |
|
|
|
vector<vector<Point3f> > objectPoints(1); |
|
|
|
calcChessboardCorners(boardSize, squareSize, objectPoints[0]); |
|
|
|
calcChessboardCorners(boardSize, squareSize, objectPoints[0], patternType); |
|
|
|
|
|
|
|
|
|
|
|
objectPoints.resize(imagePoints.size(),objectPoints[0]); |
|
|
|
objectPoints.resize(imagePoints.size(),objectPoints[0]); |
|
|
|
|
|
|
|
|
|
|
@ -240,7 +256,7 @@ static bool readStringList( const string& filename, vector<string>& l ) |
|
|
|
|
|
|
|
|
|
|
|
bool runAndSave(const string& outputFilename, |
|
|
|
bool runAndSave(const string& outputFilename, |
|
|
|
const vector<vector<Point2f> >& imagePoints, |
|
|
|
const vector<vector<Point2f> >& imagePoints, |
|
|
|
Size imageSize, Size boardSize, float squareSize, |
|
|
|
Size imageSize, Size boardSize, Pattern patternType, float squareSize, |
|
|
|
float aspectRatio, int flags, Mat& cameraMatrix, |
|
|
|
float aspectRatio, int flags, Mat& cameraMatrix, |
|
|
|
Mat& distCoeffs, bool writeExtrinsics, bool writePoints ) |
|
|
|
Mat& distCoeffs, bool writeExtrinsics, bool writePoints ) |
|
|
|
{ |
|
|
|
{ |
|
|
@ -248,7 +264,7 @@ bool runAndSave(const string& outputFilename, |
|
|
|
vector<float> reprojErrs; |
|
|
|
vector<float> reprojErrs; |
|
|
|
double totalAvgErr = 0; |
|
|
|
double totalAvgErr = 0; |
|
|
|
|
|
|
|
|
|
|
|
bool ok = runCalibration(imagePoints, imageSize, boardSize, squareSize, |
|
|
|
bool ok = runCalibration(imagePoints, imageSize, boardSize, patternType, squareSize, |
|
|
|
aspectRatio, flags, cameraMatrix, distCoeffs, |
|
|
|
aspectRatio, flags, cameraMatrix, distCoeffs, |
|
|
|
rvecs, tvecs, reprojErrs, totalAvgErr); |
|
|
|
rvecs, tvecs, reprojErrs, totalAvgErr); |
|
|
|
printf("%s. avg reprojection error = %.2f\n", |
|
|
|
printf("%s. avg reprojection error = %.2f\n", |
|
|
@ -313,9 +329,12 @@ int main( int argc, char** argv ) |
|
|
|
} |
|
|
|
} |
|
|
|
else if( strcmp( s, "-pt" ) == 0 ) |
|
|
|
else if( strcmp( s, "-pt" ) == 0 ) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if( !strcmp( argv[++i], "circles" ) ) |
|
|
|
i++; |
|
|
|
pattern = CIRCLESGRID; |
|
|
|
if( !strcmp( argv[i], "circles" ) ) |
|
|
|
else if( !strcmp( argv[++i], "chessboard" ) ) |
|
|
|
pattern = CIRCLES_GRID; |
|
|
|
|
|
|
|
else if( !strcmp( argv[i], "acircles" ) ) |
|
|
|
|
|
|
|
pattern = ASYMMETRIC_CIRCLES_GRID; |
|
|
|
|
|
|
|
else if( !strcmp( argv[i], "chessboard" ) ) |
|
|
|
pattern = CHESSBOARD; |
|
|
|
pattern = CHESSBOARD; |
|
|
|
else |
|
|
|
else |
|
|
|
return fprintf( stderr, "Invalid pattern type: must be chessboard or circles\n" ), -1; |
|
|
|
return fprintf( stderr, "Invalid pattern type: must be chessboard or circles\n" ), -1; |
|
|
@ -423,7 +442,7 @@ int main( int argc, char** argv ) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if( imagePoints.size() > 0 ) |
|
|
|
if( imagePoints.size() > 0 ) |
|
|
|
runAndSave(outputFilename, imagePoints, imageSize, |
|
|
|
runAndSave(outputFilename, imagePoints, imageSize, |
|
|
|
boardSize, squareSize, aspectRatio, |
|
|
|
boardSize, pattern, squareSize, aspectRatio, |
|
|
|
flags, cameraMatrix, distCoeffs, |
|
|
|
flags, cameraMatrix, distCoeffs, |
|
|
|
writeExtrinsics, writePoints); |
|
|
|
writeExtrinsics, writePoints); |
|
|
|
break; |
|
|
|
break; |
|
|
@ -444,9 +463,12 @@ int main( int argc, char** argv ) |
|
|
|
found = findChessboardCorners( view, boardSize, pointbuf, |
|
|
|
found = findChessboardCorners( view, boardSize, pointbuf, |
|
|
|
CV_CALIB_CB_ADAPTIVE_THRESH & CV_CALIB_CB_FAST_CHECK & CV_CALIB_CB_NORMALIZE_IMAGE); |
|
|
|
CV_CALIB_CB_ADAPTIVE_THRESH & CV_CALIB_CB_FAST_CHECK & CV_CALIB_CB_NORMALIZE_IMAGE); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case CIRCLESGRID: |
|
|
|
case CIRCLES_GRID: |
|
|
|
found = findCirclesGrid( view, boardSize, pointbuf ); |
|
|
|
found = findCirclesGrid( view, boardSize, pointbuf ); |
|
|
|
break; |
|
|
|
break; |
|
|
|
|
|
|
|
case ASYMMETRIC_CIRCLES_GRID: |
|
|
|
|
|
|
|
found = findCirclesGrid( view, boardSize, pointbuf, CALIB_CB_ASYMMETRIC_GRID ); |
|
|
|
|
|
|
|
break; |
|
|
|
default: |
|
|
|
default: |
|
|
|
return fprintf( stderr, "Unknown pattern type\n" ), -1; |
|
|
|
return fprintf( stderr, "Unknown pattern type\n" ), -1; |
|
|
|
} |
|
|
|
} |
|
|
@ -510,7 +532,7 @@ int main( int argc, char** argv ) |
|
|
|
if( mode == CAPTURING && imagePoints.size() >= (unsigned)nframes ) |
|
|
|
if( mode == CAPTURING && imagePoints.size() >= (unsigned)nframes ) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if( runAndSave(outputFilename, imagePoints, imageSize, |
|
|
|
if( runAndSave(outputFilename, imagePoints, imageSize, |
|
|
|
boardSize, squareSize, aspectRatio, |
|
|
|
boardSize, pattern, squareSize, aspectRatio, |
|
|
|
flags, cameraMatrix, distCoeffs, |
|
|
|
flags, cameraMatrix, distCoeffs, |
|
|
|
writeExtrinsics, writePoints)) |
|
|
|
writeExtrinsics, writePoints)) |
|
|
|
mode = CALIBRATED; |
|
|
|
mode = CALIBRATED; |
|
|
|