@@ -68,6 +68,7 @@ class Settings
68
68
node[" Write_outputFileName" ] >> outputFileName;
69
69
node[" Calibrate_AssumeZeroTangentialDistortion" ] >> calibZeroTangentDist;
70
70
node[" Calibrate_FixPrincipalPointAtTheCenter" ] >> calibFixPrincipalPoint;
71
+ node[" Calibrate_UseFisheyeModel" ] >> useFisheye;
71
72
node[" Input_FlipAroundHorizontalAxis" ] >> flipVertical;
72
73
node[" Show_UndistortedImage" ] >> showUndistorsed;
73
74
node[" Input" ] >> input;
@@ -126,11 +127,17 @@ class Settings
126
127
goodInput = false ;
127
128
}
128
129
129
- flag = 0 ;
130
+ flag = CALIB_FIX_K4 | CALIB_FIX_K5 ;
130
131
if (calibFixPrincipalPoint) flag |= CALIB_FIX_PRINCIPAL_POINT;
131
132
if (calibZeroTangentDist) flag |= CALIB_ZERO_TANGENT_DIST;
132
133
if (aspectRatio) flag |= CALIB_FIX_ASPECT_RATIO;
133
134
135
+ if (useFisheye) {
136
+ // the fisheye model has its own enum, so overwrite the flags
137
+ flag = fisheye::CALIB_FIX_SKEW | fisheye::CALIB_RECOMPUTE_EXTRINSIC |
138
+ // fisheye::CALIB_FIX_K1 |
139
+ fisheye::CALIB_FIX_K2 | fisheye::CALIB_FIX_K3 | fisheye::CALIB_FIX_K4;
140
+ }
134
141
135
142
calibrationPattern = NOT_EXISTING;
136
143
if (!patternToUse.compare (" CHESSBOARD" )) calibrationPattern = CHESSBOARD;
@@ -188,6 +195,7 @@ class Settings
188
195
string outputFileName; // The name of the file where to write
189
196
bool showUndistorsed; // Show undistorted images after calibration
190
197
string input; // The input ->
198
+ bool useFisheye; // use fisheye camera model for calibration
191
199
192
200
int cameraID;
193
201
vector<string> imageList;
@@ -287,11 +295,18 @@ int main(int argc, char* argv[])
287
295
vector<Point2f> pointBuf;
288
296
289
297
bool found;
298
+
299
+ int chessBoardFlags = CALIB_CB_ADAPTIVE_THRESH | CALIB_CB_NORMALIZE_IMAGE;
300
+
301
+ if (!s.useFisheye ) {
302
+ // fast check erroneously fails with high distortions like fisheye
303
+ chessBoardFlags |= CALIB_CB_FAST_CHECK;
304
+ }
305
+
290
306
switch ( s.calibrationPattern ) // Find feature points on the input format
291
307
{
292
308
case Settings::CHESSBOARD:
293
- found = findChessboardCorners ( view, s.boardSize , pointBuf,
294
- CALIB_CB_ADAPTIVE_THRESH | CALIB_CB_FAST_CHECK | CALIB_CB_NORMALIZE_IMAGE);
309
+ found = findChessboardCorners ( view, s.boardSize , pointBuf, chessBoardFlags);
295
310
break ;
296
311
case Settings::CIRCLES_GRID:
297
312
found = findCirclesGrid ( view, s.boardSize , pointBuf );
@@ -381,9 +396,22 @@ int main(int argc, char* argv[])
381
396
if ( s.inputType == Settings::IMAGE_LIST && s.showUndistorsed )
382
397
{
383
398
Mat view, rview, map1, map2;
384
- initUndistortRectifyMap (cameraMatrix, distCoeffs, Mat (),
385
- getOptimalNewCameraMatrix (cameraMatrix, distCoeffs, imageSize, 1 , imageSize, 0 ),
386
- imageSize, CV_16SC2, map1, map2);
399
+
400
+ if (s.useFisheye )
401
+ {
402
+ Mat newCamMat;
403
+ fisheye::estimateNewCameraMatrixForUndistortRectify (cameraMatrix, distCoeffs, imageSize,
404
+ Matx33d::eye (), newCamMat, 1 );
405
+ fisheye::initUndistortRectifyMap (cameraMatrix, distCoeffs, Matx33d::eye (), newCamMat, imageSize,
406
+ CV_16SC2, map1, map2);
407
+ }
408
+ else
409
+ {
410
+ initUndistortRectifyMap (
411
+ cameraMatrix, distCoeffs, Mat (),
412
+ getOptimalNewCameraMatrix (cameraMatrix, distCoeffs, imageSize, 1 , imageSize, 0 ), imageSize,
413
+ CV_16SC2, map1, map2);
414
+ }
387
415
388
416
for (size_t i = 0 ; i < s.imageList .size (); i++ )
389
417
{
@@ -407,7 +435,7 @@ static double computeReprojectionErrors( const vector<vector<Point3f> >& objectP
407
435
const vector<vector<Point2f> >& imagePoints,
408
436
const vector<Mat>& rvecs, const vector<Mat>& tvecs,
409
437
const Mat& cameraMatrix , const Mat& distCoeffs,
410
- vector<float >& perViewErrors)
438
+ vector<float >& perViewErrors, bool fisheye )
411
439
{
412
440
vector<Point2f> imagePoints2;
413
441
size_t totalPoints = 0 ;
@@ -416,7 +444,15 @@ static double computeReprojectionErrors( const vector<vector<Point3f> >& objectP
416
444
417
445
for (size_t i = 0 ; i < objectPoints.size (); ++i )
418
446
{
419
- projectPoints (objectPoints[i], rvecs[i], tvecs[i], cameraMatrix, distCoeffs, imagePoints2);
447
+ if (fisheye)
448
+ {
449
+ fisheye::projectPoints (objectPoints[i], imagePoints2, rvecs[i], tvecs[i], cameraMatrix,
450
+ distCoeffs);
451
+ }
452
+ else
453
+ {
454
+ projectPoints (objectPoints[i], rvecs[i], tvecs[i], cameraMatrix, distCoeffs, imagePoints2);
455
+ }
420
456
err = norm (imagePoints[i], imagePoints2, NORM_L2);
421
457
422
458
size_t n = objectPoints[i].size ();
@@ -462,23 +498,42 @@ static bool runCalibration( Settings& s, Size& imageSize, Mat& cameraMatrix, Mat
462
498
if ( s.flag & CALIB_FIX_ASPECT_RATIO )
463
499
cameraMatrix.at <double >(0 ,0 ) = s.aspectRatio ;
464
500
// ! [fixed_aspect]
465
- distCoeffs = Mat::zeros (8 , 1 , CV_64F);
501
+ if (s.useFisheye ) {
502
+ distCoeffs = Mat::zeros (4 , 1 , CV_64F);
503
+ } else {
504
+ distCoeffs = Mat::zeros (8 , 1 , CV_64F);
505
+ }
466
506
467
507
vector<vector<Point3f> > objectPoints (1 );
468
508
calcBoardCornerPositions (s.boardSize , s.squareSize , objectPoints[0 ], s.calibrationPattern );
469
509
470
510
objectPoints.resize (imagePoints.size (),objectPoints[0 ]);
471
511
472
512
// Find intrinsic and extrinsic camera parameters
473
- double rms = calibrateCamera (objectPoints, imagePoints, imageSize, cameraMatrix,
474
- distCoeffs, rvecs, tvecs, s.flag |CALIB_FIX_K4|CALIB_FIX_K5);
513
+ double rms;
514
+
515
+ if (s.useFisheye ) {
516
+ Mat _rvecs, _tvecs;
517
+ rms = fisheye::calibrate (objectPoints, imagePoints, imageSize, cameraMatrix, distCoeffs, _rvecs,
518
+ _tvecs, s.flag );
519
+
520
+ rvecs.reserve (_rvecs.rows );
521
+ tvecs.reserve (_tvecs.rows );
522
+ for (int i = 0 ; i < int (objectPoints.size ()); i++){
523
+ rvecs.push_back (_rvecs.row (i));
524
+ tvecs.push_back (_tvecs.row (i));
525
+ }
526
+ } else {
527
+ rms = calibrateCamera (objectPoints, imagePoints, imageSize, cameraMatrix, distCoeffs, rvecs, tvecs,
528
+ s.flag );
529
+ }
475
530
476
531
cout << " Re-projection error reported by calibrateCamera: " << rms << endl;
477
532
478
533
bool ok = checkRange (cameraMatrix) && checkRange (distCoeffs);
479
534
480
- totalAvgErr = computeReprojectionErrors (objectPoints, imagePoints,
481
- rvecs, tvecs, cameraMatrix, distCoeffs, reprojErrs);
535
+ totalAvgErr = computeReprojectionErrors (objectPoints, imagePoints, rvecs, tvecs, cameraMatrix,
536
+ distCoeffs, reprojErrs, s. useFisheye );
482
537
483
538
return ok;
484
539
}
@@ -512,16 +567,31 @@ static void saveCameraParams( Settings& s, Size& imageSize, Mat& cameraMatrix, M
512
567
513
568
if (s.flag )
514
569
{
515
- sprintf (buf, " flags: %s%s%s%s" ,
516
- s.flag & CALIB_USE_INTRINSIC_GUESS ? " +use_intrinsic_guess" : " " ,
517
- s.flag & CALIB_FIX_ASPECT_RATIO ? " +fix_aspect_ratio" : " " ,
518
- s.flag & CALIB_FIX_PRINCIPAL_POINT ? " +fix_principal_point" : " " ,
519
- s.flag & CALIB_ZERO_TANGENT_DIST ? " +zero_tangent_dist" : " " );
570
+ if (s.useFisheye )
571
+ {
572
+ sprintf (buf, " flags:%s%s%s%s%s%s" ,
573
+ s.flag & fisheye::CALIB_FIX_SKEW ? " +fix_skew" : " " ,
574
+ s.flag & fisheye::CALIB_FIX_K1 ? " +fix_k1" : " " ,
575
+ s.flag & fisheye::CALIB_FIX_K2 ? " +fix_k2" : " " ,
576
+ s.flag & fisheye::CALIB_FIX_K3 ? " +fix_k3" : " " ,
577
+ s.flag & fisheye::CALIB_FIX_K4 ? " +fix_k4" : " " ,
578
+ s.flag & fisheye::CALIB_RECOMPUTE_EXTRINSIC ? " +recompute_extrinsic" : " " );
579
+ }
580
+ else
581
+ {
582
+ sprintf (buf, " flags:%s%s%s%s" ,
583
+ s.flag & CALIB_USE_INTRINSIC_GUESS ? " +use_intrinsic_guess" : " " ,
584
+ s.flag & CALIB_FIX_ASPECT_RATIO ? " +fix_aspectRatio" : " " ,
585
+ s.flag & CALIB_FIX_PRINCIPAL_POINT ? " +fix_principal_point" : " " ,
586
+ s.flag & CALIB_ZERO_TANGENT_DIST ? " +zero_tangent_dist" : " " );
587
+ }
520
588
cvWriteComment (*fs, buf, 0 );
521
589
}
522
590
523
591
fs << " flags" << s.flag ;
524
592
593
+ fs << " fisheye_model" << s.useFisheye ;
594
+
525
595
fs << " camera_matrix" << cameraMatrix;
526
596
fs << " distortion_coefficients" << distCoeffs;
527
597
0 commit comments