SLProject  4.2.000
A platform independent 3D computer graphics framework for desktop OS, Android, iOS and online in web browsers
CVCalibration.h
Go to the documentation of this file.
1 /**
2  * \file CVCalibration.h
3  * \date Winter 2016
4  * \remarks Please use clangformat to format the code. See more code style on
5  * https://github.com/cpvrlab/SLProject4/wiki/SLProject-Coding-Style
6  * \authors Michael Goettlicher, Marcus Hudritsch
7  * \copyright http://opensource.org/licenses/GPL-3.0
8 */
9 
10 #ifndef CVCALIBRATION_H
11 #define CVCALIBRATION_H
12 
13 /*
14 The OpenCV library version 3.4 or above with extra module must be present.
15 If the application captures the live video stream with OpenCV you have
16 to define in addition the constant APP_USES_CVCAPTURE.
17 All classes that use OpenCV begin with CV.
18 See also the class docs for CVCapture, CVCalibration and CVTracked
19 for a good top down information.
20 */
21 
22 #include <CVTypedefs.h>
23 #include <CVTypes.h>
24 
25 using std::string;
26 using std::vector;
27 
28 //-----------------------------------------------------------------------------
29 //! OpenCV Calibration state
31 {
32  CS_uncalibrated, //!< The camera is not calibrated (no calibration found)
33  CS_calibrated, //!< The camera is calibrated
34  CS_guessed, //!< The camera intrinsics where estimated from FOV
35 };
36 
37 //-----------------------------------------------------------------------------
38 //! Live video camera calibration class with OpenCV an OpenCV calibration.
39 /*! The camera calibration can determine the inner or intrinsic parameters such
40 as the focal length and the lens distortion and external or extrinsic parameter
41 such as the camera pose towards a known geometry.
42 \n
43 For a good calibration we have to make 15-20 images from a chessboard pattern.
44 The chessboard pattern can be printed from the CalibrationChessboard_8x5_A4.pdf
45 in the folder data/calibration. It is important that one side has an odd number
46 of inner corners. Like this it is unambiguous and can be rotated in any direction.
47 \n
48 The different calibration states are handled within AppDemoTracking::onUpdateTracking:
49 \n
50 - CS_uncalibrated: The camera is not calibrated (no calibration found found)
51 - CS_calibrated: The camera is calibrated
52 - CS_guessed
53 \n
54 The core of the intrinsic calibration is stored in the members _cameraMat and
55 _distortion. For the calibration internals see the OpenCV documentation:
56 http://docs.opencv.org/3.1.0/dc/dbb/tutorial_py_calibration.html
57 After a successfully calibration the parameters are stored in a config file on
58 the SL::configPath. If it exists, it is loaded from there at startup.
59 If doesn't exist a simple calibration from a default field of view angle is
60 estimated.
61 \n
62 The CVCapture instance has two video camera calibrations, one for a main camera
63 (CVCapture::mainCam) and one for the selfie camera on mobile devices
64 (CVCapture::scndCam). The member CVCapture::activeCamera points to the active
65 one and is set by the CVCapture::videoType (VT_NONE, VT_MAIN, VT_SCND) during the
66 scene assembly in AppDemoLoad. On mobile devices the front camera is the
67 selfie camera (our secondary) and the back camera is the our main camera.
68 */
69 
71 {
72 public:
73  // default constructor with uncalibrated state (this is not good because
74  // it is not a valid state so everybody who uses it has to check the calibration state first)
76 
77  // creates a fully defined calibration
78  CVCalibration(const cv::Mat& cameraMat,
79  const cv::Mat& distortion,
80  cv::Size imageSize,
81  cv::Size boardSize,
82  float boardSquareMM,
83  float reprojectionError,
84  int numCaptured,
85  const string& calibrationTime,
86  int camSizeIndex,
87  bool mirroredH,
88  bool mirroredV,
90  string computerInfos,
91  int calibFlags,
92  bool calcUndistortionMaps);
93 
94  // creates a guessed calibration using image size and fovV angle
95  CVCalibration(const cv::Size& imageSize,
96  float fovH,
97  bool mirroredH,
98  bool mirroredV,
100  string computerInfos);
101 
102  // create a guessed calibration using sensor size, camera focal length and captured image size
103  CVCalibration(float sensorWMM,
104  float sensorHMM,
105  float focalLengthMM,
106  const cv::Size& imageSize,
107  bool mirroredH,
108  bool mirroredV,
110  string computerInfos);
111 
112  bool load(const string& calibDir,
113  const string& calibFileName,
114  bool calcUndistortionMaps);
115  bool save(const string& calibDir,
116  const string& calibFileName);
117 
118  void remap(CVMat& inDistorted,
119  CVMat& outUndistorted);
120 
121  //! Adapts an already calibrated camera to a new resolution (cropping and scaling)
122  void adaptForNewResolution(const CVSize& newSize, bool calcUndistortionMaps);
123  void buildUndistortionMaps();
124 
125  // Getters
126  CVSize imageSize() const { return _imageSize; }
128 
129  // int camSizeIndex() { return _camSizeIndex;}
130  float imageAspectRatio() const { return (float)_imageSize.width / (float)_imageSize.height; }
131  const CVMat& cameraMat() const { return _cameraMat; }
133  const CVMat& distortion() const { return _distortion; }
134  float cameraFovVDeg() const { return _cameraFovVDeg; }
135  float cameraFovHDeg() const { return _cameraFovHDeg; }
136 
137  int calibrationFlags() { return _calibFlags; }
138  bool calibFixPrincipalPoint() { return _calibFlags & cv::CALIB_FIX_PRINCIPAL_POINT; }
139  bool calibFixAspectRatio() { return _calibFlags & cv::CALIB_FIX_ASPECT_RATIO; }
140  bool calibZeroTangentDist() { return _calibFlags & cv::CALIB_ZERO_TANGENT_DIST; }
141  bool calibRationalModel() { return _calibFlags & cv::CALIB_RATIONAL_MODEL; }
142  bool calibTiltedModel() { return _calibFlags & cv::CALIB_TILTED_MODEL; }
143  bool calibThinPrismModel() { return _calibFlags & cv::CALIB_THIN_PRISM_MODEL; }
144  bool isMirroredH() { return _isMirroredH; }
145  bool isMirroredV() { return _isMirroredV; }
146 
147  float fx() const { return _cameraMat.cols == 3 && _cameraMat.rows == 3 ? (float)_cameraMat.at<double>(0, 0) : 0.0f; }
148  float fy() const { return _cameraMat.cols == 3 && _cameraMat.rows == 3 ? (float)_cameraMat.at<double>(1, 1) : 0.0f; }
149  float cx() const { return _cameraMat.cols == 3 && _cameraMat.rows == 3 ? (float)_cameraMat.at<double>(0, 2) : 0.0f; }
150  float cy() const { return _cameraMat.cols == 3 && _cameraMat.rows == 3 ? (float)_cameraMat.at<double>(1, 2) : 0.0f; }
151  float k1() const { return _distortion.rows >= 4 ? (float)_distortion.at<double>(0, 0) : 0.0f; }
152  float k2() const { return _distortion.rows >= 4 ? (float)_distortion.at<double>(1, 0) : 0.0f; }
153  float p1() const { return _distortion.rows >= 4 ? (float)_distortion.at<double>(2, 0) : 0.0f; }
154  float p2() const { return _distortion.rows >= 4 ? (float)_distortion.at<double>(3, 0) : 0.0f; }
155  float k3() const { return _distortion.rows >= 5 ? (float)_distortion.at<double>(4, 0) : 0.0f; }
156  float k4() const { return _distortion.rows >= 6 ? (float)_distortion.at<double>(5, 0) : 0.0f; }
157  float k5() const { return _distortion.rows >= 7 ? (float)_distortion.at<double>(6, 0) : 0.0f; }
158  float k6() const { return _distortion.rows >= 8 ? (float)_distortion.at<double>(7, 0) : 0.0f; }
159  float s1() const { return _distortion.rows >= 9 ? (float)_distortion.at<double>(8, 0) : 0.0f; }
160  float s2() const { return _distortion.rows >= 10 ? (float)_distortion.at<double>(9, 0) : 0.0f; }
161  float s3() const { return _distortion.rows >= 11 ? (float)_distortion.at<double>(10, 0) : 0.0f; }
162  float s4() const { return _distortion.rows >= 12 ? (float)_distortion.at<double>(11, 0) : 0.0f; }
163  float tauX() const { return _distortion.rows >= 13 ? (float)_distortion.at<double>(12, 0) : 0.0f; }
164  float tauY() const { return _distortion.rows >= 14 ? (float)_distortion.at<double>(13, 0) : 0.0f; }
165 
166  CVCameraType camType() const { return _camType; }
167  CVCalibState state() const { return _state; }
168  int numCapturedImgs() const { return _numCaptured; }
169  float reprojectionError() const { return _reprojectionError; }
170  CVSize boardSize() const { return _boardSize; }
171  float boardSquareMM() const { return _boardSquareMM; }
172  float boardSquareM() const { return _boardSquareMM * 0.001f; }
173  string calibrationTime() const { return _calibrationTime; }
174  string calibFileName() const { return _calibFileName; }
175  string computerInfos() const { return _computerInfos; }
176  string stateStr() const
177  {
178  switch (_state)
179  {
180  case CS_uncalibrated: return "CS_uncalibrated";
181  case CS_calibrated: return "CS_calibrated";
182  case CS_guessed: return "CS_guessed";
183  default: return "unknown";
184  }
185  }
186 
187 private:
190  void createFromGuessedFOV(int imageWidthPX, int imageHeightPX, float fovH);
191 
192  ///////////////////////////////////////////////////////////////////////////////////
193  CVMat _cameraMat; //!< 3x3 Matrix for intrinsic camera matrix
194  CVMat _distortion; //!< 4x1 Matrix for intrinsic distortion
195  ///////////////////////////////////////////////////////////////////////////////////
196 
197  // original data used for adaption:
198  CVMat _cameraMatOrig; //!< 3x3 Matrix for intrinsic camera matrix (original from loading or calibration estimation)
199  CVSize _imageSizeOrig; //!< original image size (original from loading or calibration estimation)
200 
201  CVCalibState _state = CS_uncalibrated; //!< calibration state enumeration
202  float _cameraFovVDeg = 0.0f; //!< Vertical field of view in degrees
203  float _cameraFovHDeg = 0.0f; //!< Horizontal field of view in degrees
204  string _calibFileName; //!< name for calibration file
205  int _calibFlags = 0; //!< OpenCV calibration flags
206  bool _isMirroredH = false; //!< Flag if image must be horizontally mirrored
207  bool _isMirroredV = false; //!< Flag if image must be vertically mirrored
208 
209  int _numCaptured = 0; //!< NO. of images captured
210  CVSize _boardSize; //!< NO. of inner chessboard corners.
211  float _boardSquareMM = 20.f; //!< Size of chessboard square in mm
212  float _reprojectionError = -1.0f; //!< Reprojection error after calibration
213  CVSize _imageSize; //!< Input image size in pixels (after cropping)
214  int _camSizeIndex = -1; //!< The requested camera size index
215 
216  CVMat _undistortMapX; //!< Undistortion float map in x-direction
217  CVMat _undistortMapY; //!< Undistortion float map in y-direction
218  CVMat _cameraMatUndistorted; //!< Camera matrix that defines scene camera and may also be used for reprojection of undistorted image
219  string _calibrationTime = "-"; //!< Time stamp string of calibration
222 
223  static const int _CALIBFILEVERSION; //!< Global const file format version
224 };
225 //-----------------------------------------------------------------------------
226 
227 #endif // CVCalibration_H
CVCalibState
OpenCV Calibration state.
Definition: CVCalibration.h:31
@ CS_calibrated
The camera is calibrated.
Definition: CVCalibration.h:33
@ CS_uncalibrated
The camera is not calibrated (no calibration found)
Definition: CVCalibration.h:32
@ CS_guessed
The camera intrinsics where estimated from FOV.
Definition: CVCalibration.h:34
cv::Size CVSize
Definition: CVTypedefs.h:55
cv::Mat CVMat
Definition: CVTypedefs.h:38
CVCameraType
Definition: CVTypes.h:62
Live video camera calibration class with OpenCV an OpenCV calibration.
Definition: CVCalibration.h:71
float _boardSquareMM
Size of chessboard square in mm.
float _cameraFovVDeg
Vertical field of view in degrees.
float tauY() const
void calculateUndistortedCameraMat()
Calculate a camera matrix that we use for the scene graph and for the reprojection of the undistorted...
float s3() const
bool _isMirroredV
Flag if image must be vertically mirrored.
bool calibFixAspectRatio()
int calibrationFlags()
float fx() const
CVSize boardSize() const
float _reprojectionError
Reprojection error after calibration.
CVMat _undistortMapX
Undistortion float map in x-direction.
static const int _CALIBFILEVERSION
Global const file format version.
float s4() const
void calcCameraFovFromUndistortedCameraMat()
Calculates the vertical field of view angle in degrees.
bool calibThinPrismModel()
bool calibZeroTangentDist()
CVCameraType _camType
float k4() const
CVSize imageSize() const
const CVMat & cameraMat() const
float boardSquareMM() const
const CVMat & distortion() const
CVCalibState _state
calibration state enumeration
void remap(CVMat &inDistorted, CVMat &outUndistorted)
Undistorts the inDistorted image into the outUndistorted.
string _calibFileName
name for calibration file
CVSize imageSizeOriginal() const
CVMat _cameraMatUndistorted
Camera matrix that defines scene camera and may also be used for reprojection of undistorted image.
const CVMat & cameraMatUndistorted() const
float s2() const
void createFromGuessedFOV(int imageWidthPX, int imageHeightPX, float fovH)
Calculates camera intrinsics from a guessed FOV angle.
float fy() const
CVCameraType camType() const
float boardSquareM() const
bool isMirroredH()
float k3() const
bool isMirroredV()
float p1() const
CVMat _undistortMapY
Undistortion float map in y-direction.
bool calibTiltedModel()
CVSize _imageSize
Input image size in pixels (after cropping)
float reprojectionError() const
bool calibRationalModel()
string _computerInfos
float cx() const
float imageAspectRatio() const
int numCapturedImgs() const
CVCalibration(CVCameraType camType, string computerInfos)
float p2() const
void adaptForNewResolution(const CVSize &newSize, bool calcUndistortionMaps)
Adapts an already calibrated camera to a new resolution (cropping and scaling)
float cameraFovHDeg() const
float cameraFovVDeg() const
CVMat _distortion
4x1 Matrix for intrinsic distortion
float _cameraFovHDeg
Horizontal field of view in degrees.
float k2() const
bool calibFixPrincipalPoint()
string _calibrationTime
Time stamp string of calibration.
string stateStr() const
float k6() const
float s1() const
bool load(const string &calibDir, const string &calibFileName, bool calcUndistortionMaps)
Loads the calibration information from the config file.
CVMat _cameraMat
3x3 Matrix for intrinsic camera matrix
float k5() const
int _camSizeIndex
The requested camera size index.
CVSize _imageSizeOrig
original image size (original from loading or calibration estimation)
float tauX() const
float k1() const
string computerInfos() const
float cy() const
string calibFileName() const
int _numCaptured
NO. of images captured.
bool _isMirroredH
Flag if image must be horizontally mirrored.
string calibrationTime() const
CVMat _cameraMatOrig
3x3 Matrix for intrinsic camera matrix (original from loading or calibration estimation)
bool save(const string &calibDir, const string &calibFileName)
Saves the camera calibration parameters to the config file.
CVSize _boardSize
NO. of inner chessboard corners.
void buildUndistortionMaps()
Builds undistortion maps after calibration or loading.
CVCalibState state() const
int _calibFlags
OpenCV calibration flags.