Skip to content

Commit 6208ab4

Browse files
committed
Merge pull request opencv#5304 from paroj:calib_feye
2 parents 79100ef + d0e16b2 commit 6208ab4

File tree

1 file changed

+88
-18
lines changed

1 file changed

+88
-18
lines changed

samples/cpp/tutorial_code/calib3d/camera_calibration/camera_calibration.cpp

Lines changed: 88 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ class Settings
6868
node["Write_outputFileName"] >> outputFileName;
6969
node["Calibrate_AssumeZeroTangentialDistortion"] >> calibZeroTangentDist;
7070
node["Calibrate_FixPrincipalPointAtTheCenter"] >> calibFixPrincipalPoint;
71+
node["Calibrate_UseFisheyeModel"] >> useFisheye;
7172
node["Input_FlipAroundHorizontalAxis"] >> flipVertical;
7273
node["Show_UndistortedImage"] >> showUndistorsed;
7374
node["Input"] >> input;
@@ -126,11 +127,17 @@ class Settings
126127
goodInput = false;
127128
}
128129

129-
flag = 0;
130+
flag = CALIB_FIX_K4 | CALIB_FIX_K5;
130131
if(calibFixPrincipalPoint) flag |= CALIB_FIX_PRINCIPAL_POINT;
131132
if(calibZeroTangentDist) flag |= CALIB_ZERO_TANGENT_DIST;
132133
if(aspectRatio) flag |= CALIB_FIX_ASPECT_RATIO;
133134

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+
}
134141

135142
calibrationPattern = NOT_EXISTING;
136143
if (!patternToUse.compare("CHESSBOARD")) calibrationPattern = CHESSBOARD;
@@ -188,6 +195,7 @@ class Settings
188195
string outputFileName; // The name of the file where to write
189196
bool showUndistorsed; // Show undistorted images after calibration
190197
string input; // The input ->
198+
bool useFisheye; // use fisheye camera model for calibration
191199

192200
int cameraID;
193201
vector<string> imageList;
@@ -287,11 +295,18 @@ int main(int argc, char* argv[])
287295
vector<Point2f> pointBuf;
288296

289297
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+
290306
switch( s.calibrationPattern ) // Find feature points on the input format
291307
{
292308
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);
295310
break;
296311
case Settings::CIRCLES_GRID:
297312
found = findCirclesGrid( view, s.boardSize, pointBuf );
@@ -381,9 +396,22 @@ int main(int argc, char* argv[])
381396
if( s.inputType == Settings::IMAGE_LIST && s.showUndistorsed )
382397
{
383398
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+
}
387415

388416
for(size_t i = 0; i < s.imageList.size(); i++ )
389417
{
@@ -407,7 +435,7 @@ static double computeReprojectionErrors( const vector<vector<Point3f> >& objectP
407435
const vector<vector<Point2f> >& imagePoints,
408436
const vector<Mat>& rvecs, const vector<Mat>& tvecs,
409437
const Mat& cameraMatrix , const Mat& distCoeffs,
410-
vector<float>& perViewErrors)
438+
vector<float>& perViewErrors, bool fisheye)
411439
{
412440
vector<Point2f> imagePoints2;
413441
size_t totalPoints = 0;
@@ -416,7 +444,15 @@ static double computeReprojectionErrors( const vector<vector<Point3f> >& objectP
416444

417445
for(size_t i = 0; i < objectPoints.size(); ++i )
418446
{
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+
}
420456
err = norm(imagePoints[i], imagePoints2, NORM_L2);
421457

422458
size_t n = objectPoints[i].size();
@@ -462,23 +498,42 @@ static bool runCalibration( Settings& s, Size& imageSize, Mat& cameraMatrix, Mat
462498
if( s.flag & CALIB_FIX_ASPECT_RATIO )
463499
cameraMatrix.at<double>(0,0) = s.aspectRatio;
464500
//! [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+
}
466506

467507
vector<vector<Point3f> > objectPoints(1);
468508
calcBoardCornerPositions(s.boardSize, s.squareSize, objectPoints[0], s.calibrationPattern);
469509

470510
objectPoints.resize(imagePoints.size(),objectPoints[0]);
471511

472512
//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+
}
475530

476531
cout << "Re-projection error reported by calibrateCamera: "<< rms << endl;
477532

478533
bool ok = checkRange(cameraMatrix) && checkRange(distCoeffs);
479534

480-
totalAvgErr = computeReprojectionErrors(objectPoints, imagePoints,
481-
rvecs, tvecs, cameraMatrix, distCoeffs, reprojErrs);
535+
totalAvgErr = computeReprojectionErrors(objectPoints, imagePoints, rvecs, tvecs, cameraMatrix,
536+
distCoeffs, reprojErrs, s.useFisheye);
482537

483538
return ok;
484539
}
@@ -512,16 +567,31 @@ static void saveCameraParams( Settings& s, Size& imageSize, Mat& cameraMatrix, M
512567

513568
if (s.flag)
514569
{
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+
}
520588
cvWriteComment(*fs, buf, 0);
521589
}
522590

523591
fs << "flags" << s.flag;
524592

593+
fs << "fisheye_model" << s.useFisheye;
594+
525595
fs << "camera_matrix" << cameraMatrix;
526596
fs << "distortion_coefficients" << distCoeffs;
527597

0 commit comments

Comments
 (0)