Ocean
CameraCalibration.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) Meta Platforms, Inc. and affiliates.
3  *
4  * This source code is licensed under the MIT license found in the
5  * LICENSE file in the root directory of this source tree.
6  */
7 
8 #ifndef META_OCEAN_GEOMETRY_CAMERA_CALIBRATION_H
9 #define META_OCEAN_GEOMETRY_CAMERA_CALIBRATION_H
10 
12 
13 #include "ocean/base/Accessor.h"
14 #include "ocean/base/Timestamp.h"
15 
18 
19 #include <vector>
20 
21 namespace Ocean
22 {
23 
24 namespace Geometry
25 {
26 
27 /**
28  * This class implements functions to calibrate a camera, to determine the profile of a camera.
29  * Use CameraCalibration::determineCameraCalibrationPlanar() for groups of 2D/3D point correspondences with all 3D object points located on one plane.<br>
30  * Use CameraCalibration::determineCameraCalibration() for groups of 2D/3D point correspondences with any kind of 3D object points.
31  * @ingroup geometry
32  */
33 class OCEAN_GEOMETRY_EXPORT CameraCalibration
34 {
35  public:
36 
37  /**
38  * Definition of a class holding the information about one calibration pattern.
39  */
40  class OCEAN_GEOMETRY_EXPORT Pattern
41  {
42  public:
43 
44  /**
45  * Definition of a (row) vector holding 2D positions.
46  */
48 
49  /**
50  * Definition of a vector holding rows.
51  */
52  typedef std::vector<PatternRow> PatternRows;
53 
54  public:
55 
56  /**
57  * Creates an empty pattern object.
58  */
60 
61  /**
62  * Creates a new pattern object.
63  * @param rows Pattern rows defining the pattern
64  * @param timestamp Timestamp of the pattern
65  */
66  Pattern(const PatternRows& rows, const Timestamp timestamp);
67 
68  /**
69  * Returns the rows of this pattern.
70  * @return Pattern rows
71  */
72  inline const PatternRows& rows() const;
73 
74  /**
75  * Returns the four corners of this pattern.
76  * @return Four corners
77  */
78  inline const Vector2* corners() const;
79 
80  /**
81  * Returns the bounding box of this pattern
82  * @return 2D bounding box
83  */
84  Box2 boundingBox() const;
85 
86  /**
87  * Returns the timestmap of this pattern.
88  * @return Pattern timestamp
89  */
90  inline Timestamp timestamp() const;
91 
92  /**
93  * Returns whether the pattern object holds not valid corners.
94  * @return True, if so
95  */
96  inline bool isEmpty() const;
97 
98  /**
99  * Returns the minimal sum of square distances between the corners of two calibration patterns.
100  * @return Sum of square distances
101  */
102  Scalar distance(const Pattern& pattern) const;
103 
104  /**
105  * Applies a size factor to resize the entire pattern.
106  * All corner positions will be changed by the given factor.
107  * @param sizeFactor Size factor to be applied, with range (0, infinity)
108  */
109  void changeSize(const Scalar sizeFactor);
110 
111  private:
112 
113  /**
114  * Compares the first elements of two pairs.
115  * @param first First pair to compare
116  * @param second Second pair to compare
117  * @return True, if the first element of the first pair is lesser than the first element of the second pair
118  */
119  template <typename TF, typename TS> static inline bool compareFirst(const std::pair<TF, TS>& first, const std::pair<TF, TS>& second);
120 
121  private:
122 
123  /// Pattern rows.
125 
126  /// Pattern corners.
127  Vector2 patternCorners[4];
128 
129  /// Pattern timestamp.
131  };
132 
133  /**
134  * Definition of a vector holding calibration patterns.
135  */
136  typedef std::vector<Pattern> Patterns;
137 
138  public:
139 
140  /**
141  * Determines the camera calibration for several individual groups of 3D object points all lying on the same 3D plane and corresponding 2D image points.
142  * The camera calibration is determines by usage of all given correspondences.<br>
143  * The individual groups of image points can e.g., be the result of individual images of a calibration pattern observed from different viewing positions.<br>
144  * The camera profile must not change between individual groups (images of the calibration pattern).<br>
145  * Each group must provide at least 10 points.
146  * @param width The width of the camera frame in pixel, with range [1, infinity)
147  * @param height The height of the camera frame in pixel, with range [1, infinity)
148  * @param objectPointGroups The groups of object points (all points lie in the Z == 0 plane), each group has a corresponding group of image points, at least 3
149  * @param imagePointGroups The groups of image points, each group has a corresponding group of object points
150  * @param pinholeCamera Resulting pinhole camera profile holding all extracted calibration information like e.g. intrinsic camera and distortion parameters
151  * @param iterations Number of iterations the camera parameters will be improved after the initial model has been determined, using a non linear optimization approach, with range [0, infinity)
152  * @param sqrAccuracy Optional resulting average square pixel error for all point correspondences
153  * @return True, if succeeded
154  * @see determineCameraCalibration().
155  */
156  static bool determineCameraCalibrationPlanar(const unsigned int width, const unsigned int height, const ConstIndexedAccessor<Vectors3>& objectPointGroups, const ConstIndexedAccessor<Vectors2>& imagePointGroups, PinholeCamera& pinholeCamera, const unsigned int iterations = 20u, Scalar* sqrAccuracy = nullptr);
157 
158  /**
159  * Determines the intrinsic camera matrix for several groups of corresponding 2D/3D points.
160  * All 3D object points must be located on a plane.
161  * Each group must provide at least 10 points.
162  * @param objectPointGroups Groups of object points, each group corresponds to a group of image points, at least three
163  * @param imagePointGroups Groups of image points, each group corresponds to a group of object points, at least three
164  * @param intrinsic Resulting intrinsic camera matrix
165  * @param homographies Optional resulting homographies, one for each given group for which a valid homography could be determined, may be less than the provided number of groups
166  * @param validGroupIndices Optional resulting indices of the valid groups for which a valid homography could be determined
167  * @return True, if succeeded
168  */
169  static bool determineIntrinsicCameraMatrixPlanar(const ConstIndexedAccessor<Vectors3>& objectPointGroups, const ConstIndexedAccessor<Vectors2>& imagePointGroups, SquareMatrix3& intrinsic, SquareMatrices3* homographies = nullptr, Indices32* validGroupIndices = nullptr);
170 
171  /**
172  * Determines the camera calibration while a rough camera calibration is already known.
173  * The camera calibration is improved by usage of all given groups of point correspondences.<br>
174  * The individual groups of image points can be arbitrary and do not need to be based on a planar calibration pattern.<br>
175  * The camera profile must not change between individual groups (images of the calibration pattern).
176  * @param roughCamera Rough camera object already determined, must be valid
177  * @param objectPointGroups Groups of object points, each group corresponds to a group of image points, at least one
178  * @param imagePointGroups Groups of image points, each group corresponds to a group of object points, at least one
179  * @param pinholeCamera Resulting pinhole camera holding all extracted calibration information like e.g. intrinsic camera and distortion parameters
180  * @param sqrAccuracy Optional resulting average square pixel error, if defined
181  * @return True, if succeeded
182  * @see determineCameraCalibrationPlanar().
183  */
184  static bool determineCameraCalibration(const PinholeCamera& roughCamera, const ObjectPointGroups& objectPointGroups, const ImagePointGroups& imagePointGroups, PinholeCamera& pinholeCamera, Scalar* sqrAccuracy = nullptr);
185 
186  /**
187  * Creates point correspondences from a given calibration pattern.
188  * @param pattern Calibration patter to create the correspondences from
189  * @param boxSize Size of one calibration box in m
190  * @param objectPoints Resulting object points
191  * @param imagePoints Resulting image points
192  * @return True, if succeeded
193  */
194  static bool createCorrespondences(const Pattern& pattern, const Vector2& boxSize, ObjectPoints& objectPoints, ImagePoints& imagePoints);
195 
196  /**
197  * Determines the horizontal field of view that matches best to a set of poses, object point and image points.
198  * @param width The width of the camera in pixel, with range [1, infinity)
199  * @param height The height of the camera in pixel, with range [1, infinity)
200  * @param posesAccessor The accessor for the poses that match to the number of given object point groups (and image point groups)
201  * @param objectPointGroupAccessor The accessor for the individual groups of object points, one group for each group of image points
202  * @param imagePointGroupAccessor The accessor for the individual groups of image points, one group for each group of object points with same nubmer of elements
203  * @param twoIterations True, to apply a two-iteration approach, otherwise a faster one-iteration approach will be applied
204  * @param idealFovX Resulting best matching horizontal field of view, in radian
205  * @param lowestFovX Lowest field of view that will be tested in radian, with range (0, highestFovX)
206  * @param highestFovX Highest field of view that will be tested in radian, with range (lowestFovX, PI)
207  * @param steps Number of angles that will be tested, with range [1, infinity)
208  * @param idealPoses Optional resulting poses corresponding to the given sets of object and image points and the found fovX
209  * @return True, if succeeded
210  */
211  static bool determineBestMatchingFovX(const unsigned int width, const unsigned int height, const ConstIndexedAccessor<HomogenousMatrix4>& posesAccessor, const ConstIndexedAccessor<Vectors3>& objectPointGroupAccessor, const ConstIndexedAccessor<Vectors2>& imagePointGroupAccessor, Scalar& idealFovX, const bool twoIterations = true, const Scalar lowestFovX = Numeric::deg2rad(25), const Scalar highestFovX = Numeric::deg2rad(75), const unsigned int steps = 20u, NonconstIndexedAccessor<HomogenousMatrix4>* idealPoses = nullptr);
212 
213  /**
214  * Applies one camera and one pose optimization successively for a given set of poses and corresponding image and object points.
215  * @param pinholeCamera The initial pinhole camera object that has to be optimized according to the projection error of the given point sets
216  * @param poses A set of camera poses, each pose corresponds to a group of image and object points
217  * @param objectPointGroups Groups of object points, each group corresponds to one camera pose and the group of image points
218  * @param imagePointGroups Groups of image points, each group corresponds to one camera pose and the group of object points
219  * @param optimizedCamera Resulting optimized camera
220  * @param optimizedPoses Resulting optimized poses
221  * @param initialSqrError Optional initial average sqr projection error
222  * @param finalSqrError Optional resulting final average sqr projection error
223  * @return True, if succeeded
224  */
225  static bool successiveCameraPoseOptimization(const PinholeCamera& pinholeCamera, const HomogenousMatrices4& poses, const ObjectPointGroups& objectPointGroups, const ImagePointGroups& imagePointGroups, PinholeCamera& optimizedCamera, HomogenousMatrices4& optimizedPoses, Scalar* initialSqrError = nullptr, Scalar* finalSqrError = nullptr);
226 };
227 
229 {
230  return patternRows;
231 }
232 
234 {
235  return patternCorners;
236 }
237 
239 {
240  return patternTimestamp;
241 }
242 
244 {
245  return patternRows.empty();
246 }
247 
248 template <typename TF, typename TS>
249 inline bool CameraCalibration::Pattern::compareFirst(const std::pair<TF, TS>& first, const std::pair<TF, TS>& second)
250 {
251  return first.first < second.first;
252 }
253 
254 }
255 
256 }
257 
258 #endif // META_OCEAN_GEOMETRY_CAMERA_CALIBRATION_H
This class implements a base class for all indexed-based accessors allowing a constant reference acce...
Definition: Accessor.h:241
Definition of a class holding the information about one calibration pattern.
Definition: CameraCalibration.h:41
Pattern(const PatternRows &rows, const Timestamp timestamp)
Creates a new pattern object.
Timestamp patternTimestamp
Pattern timestamp.
Definition: CameraCalibration.h:130
Pattern()
Creates an empty pattern object.
PatternRows patternRows
Pattern rows.
Definition: CameraCalibration.h:124
Vectors2 PatternRow
Definition of a (row) vector holding 2D positions.
Definition: CameraCalibration.h:47
static bool compareFirst(const std::pair< TF, TS > &first, const std::pair< TF, TS > &second)
Compares the first elements of two pairs.
Definition: CameraCalibration.h:249
std::vector< PatternRow > PatternRows
Definition of a vector holding rows.
Definition: CameraCalibration.h:52
const PatternRows & rows() const
Returns the rows of this pattern.
Definition: CameraCalibration.h:228
bool isEmpty() const
Returns whether the pattern object holds not valid corners.
Definition: CameraCalibration.h:243
const Vector2 * corners() const
Returns the four corners of this pattern.
Definition: CameraCalibration.h:233
Box2 boundingBox() const
Returns the bounding box of this pattern.
Timestamp timestamp() const
Returns the timestmap of this pattern.
Definition: CameraCalibration.h:238
Scalar distance(const Pattern &pattern) const
Returns the minimal sum of square distances between the corners of two calibration patterns.
void changeSize(const Scalar sizeFactor)
Applies a size factor to resize the entire pattern.
This class implements functions to calibrate a camera, to determine the profile of a camera.
Definition: CameraCalibration.h:34
static bool determineCameraCalibration(const PinholeCamera &roughCamera, const ObjectPointGroups &objectPointGroups, const ImagePointGroups &imagePointGroups, PinholeCamera &pinholeCamera, Scalar *sqrAccuracy=nullptr)
Determines the camera calibration while a rough camera calibration is already known.
static bool successiveCameraPoseOptimization(const PinholeCamera &pinholeCamera, const HomogenousMatrices4 &poses, const ObjectPointGroups &objectPointGroups, const ImagePointGroups &imagePointGroups, PinholeCamera &optimizedCamera, HomogenousMatrices4 &optimizedPoses, Scalar *initialSqrError=nullptr, Scalar *finalSqrError=nullptr)
Applies one camera and one pose optimization successively for a given set of poses and corresponding ...
static bool determineIntrinsicCameraMatrixPlanar(const ConstIndexedAccessor< Vectors3 > &objectPointGroups, const ConstIndexedAccessor< Vectors2 > &imagePointGroups, SquareMatrix3 &intrinsic, SquareMatrices3 *homographies=nullptr, Indices32 *validGroupIndices=nullptr)
Determines the intrinsic camera matrix for several groups of corresponding 2D/3D points.
static bool determineCameraCalibrationPlanar(const unsigned int width, const unsigned int height, const ConstIndexedAccessor< Vectors3 > &objectPointGroups, const ConstIndexedAccessor< Vectors2 > &imagePointGroups, PinholeCamera &pinholeCamera, const unsigned int iterations=20u, Scalar *sqrAccuracy=nullptr)
Determines the camera calibration for several individual groups of 3D object points all lying on the ...
std::vector< Pattern > Patterns
Definition of a vector holding calibration patterns.
Definition: CameraCalibration.h:136
static bool determineBestMatchingFovX(const unsigned int width, const unsigned int height, const ConstIndexedAccessor< HomogenousMatrix4 > &posesAccessor, const ConstIndexedAccessor< Vectors3 > &objectPointGroupAccessor, const ConstIndexedAccessor< Vectors2 > &imagePointGroupAccessor, Scalar &idealFovX, const bool twoIterations=true, const Scalar lowestFovX=Numeric::deg2rad(25), const Scalar highestFovX=Numeric::deg2rad(75), const unsigned int steps=20u, NonconstIndexedAccessor< HomogenousMatrix4 > *idealPoses=nullptr)
Determines the horizontal field of view that matches best to a set of poses, object point and image p...
static bool createCorrespondences(const Pattern &pattern, const Vector2 &boxSize, ObjectPoints &objectPoints, ImagePoints &imagePoints)
Creates point correspondences from a given calibration pattern.
This class implements a base class for all indexed-based accessors allowing a non-constant reference ...
Definition: Accessor.h:284
static constexpr T deg2rad(const T deg)
Converts deg to rad.
Definition: Numeric.h:3232
This class implements a timestamp.
Definition: Timestamp.h:36
std::vector< Index32 > Indices32
Definition of a vector holding 32 bit index values.
Definition: Base.h:96
std::vector< ObjectPoint > ObjectPoints
Definition of a vector holding 3D object points.
Definition: geometry/Geometry.h:129
std::vector< ObjectPoints > ObjectPointGroups
Definition of a vector holding object points, so we have groups of object points.
Definition: geometry/Geometry.h:135
std::vector< ImagePoint > ImagePoints
Definition of a vector holding 2D image points.
Definition: geometry/Geometry.h:123
std::vector< ImagePoints > ImagePointGroups
Definition of a vector holding image points, so we have groups of image points.
Definition: geometry/Geometry.h:141
float Scalar
Definition of a scalar type.
Definition: Math.h:128
std::vector< HomogenousMatrix4 > HomogenousMatrices4
Definition of a vector holding HomogenousMatrix4 objects.
Definition: HomogenousMatrix4.h:73
std::vector< SquareMatrix3 > SquareMatrices3
Definition of a vector holding SquareMatrix3 objects.
Definition: SquareMatrix3.h:71
std::vector< Vector2 > Vectors2
Definition of a vector holding Vector2 objects.
Definition: Vector2.h:64
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15