Modified the calibration sample to work with asymmetric pattern
authorIlya Lysenkov <no@email>
Mon, 7 Feb 2011 07:59:01 +0000 (07:59 +0000)
committerIlya Lysenkov <no@email>
Mon, 7 Feb 2011 07:59:01 +0000 (07:59 +0000)
samples/cpp/calibration.cpp

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