Modified the calibration sample to work with asymmetric pattern

This commit is contained in:
Ilya Lysenkov 2011-02-07 07:59:01 +00:00
parent f8e9f65ea8
commit 3e43bc579b

View File

@ -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;