Ocean
Camera.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_MATH_CAMERA_H
9 #define META_OCEAN_MATH_CAMERA_H
10 
11 #include "ocean/math/Math.h"
13 #include "ocean/math/Quaternion.h"
15 #include "ocean/math/Vector2.h"
16 #include "ocean/math/Vector3.h"
17 
18 namespace Ocean
19 {
20 
21 // Forward declaration.
22 template <typename T> class CameraT;
23 
24 /**
25  * Definition of an Camera object with Scalar precision.
26  * @see CameraT
27  * @ingroup math
28  */
30 
31 /**
32  * Definition of an Camera object with double precision.
33  * @see CameraT
34  * @ingroup math
35  */
37 
38 /**
39  * Definition of an Camera object with float precision.
40  * @see CameraT
41  * @ingroup math
42  */
44 
45 /**
46  * This class implements the base class for all cameras.
47  * The base class provides model independent functionalities.<br>
48  * Use AnyCamera in case an entire camera model is needed.
49  * @tparam T The data type of a scalar, 'float' or 'double'
50  * @ingroup math
51  */
52 template <typename T>
53 class CameraT
54 {
55  public:
56 
57  /**
58  * Calculates the vertical FOV from the horizontal FOV and the aspect ratio of the camera image.
59  * @param fovX The given field of view in x direction (in radian), with range (0, PI)
60  * @param aspectRatio The aspect ratio of the camera (width / height)
61  * @return The field of view in y direction (in radian)
62  */
63  static T fovX2Y(const T fovX, const T aspectRatio);
64 
65  /**
66  * Calculates the horizontal FOV from the vertical FOV and the aspect ratio of the camera image.
67  * @param fovY The given field of view in y direction (in radian), with range (0, PI)
68  * @param aspectRatio The aspect ratio of the camera (width / height)
69  * @return The field of view in x direction (in radian)
70  */
71  static T fovY2X(const T fovY, const T aspectRatio);
72 
73  /**
74  * Converts field of view (and width) to the corresponding focal length.
75  * @param width The width of the camera in pixel, with range [1, infinity)
76  * @param fovX The horizontal field of view of the camera, in radian, with range (0, PI)
77  * @return The focal length of the camera, with range (0, infinity)
78  */
79  static T fieldOfViewToFocalLength(const unsigned int width, const T fovX);
80 
81  /**
82  * Calculates the normalized image point (the normalized projected object point) for a of given object point with corresponding extrinsic camera matrix.
83  * The extrinsic matrix transforms a 3D point given in camera coordinates into 3D world coordinates.<br>
84  * The viewing direction of the camera is along the negative z-axis.<br>
85  * The extrinsic matrix will be flipped and inverted internally.
86  * @param extrinsic The extrinsic camera matrix
87  * @param objectPoint The 3D object point for that the normalized image point will be calculated
88  * @return The resulting normalized image point
89  * @see objectPoints2normalizedImagePoints().
90  */
91  static inline VectorT2<T> objectPoint2normalizedImagePoint(const HomogenousMatrixT4<T>& extrinsic, const VectorT3<T>& objectPoint);
92 
93  /**
94  * Calculates the normalized image point (the normalized projected object point) for a given object point with corresponding inverse and flipped extrinsic camera matrix.
95  * The inverse extrinsic matrix transforms a 3D point given in world coordinates into 3D camera coordinates.<br>
96  * The coordinate system of the camera is flipped meaning that the viewing direction is along the positive z-axis.<br>
97  * The flipped coordinate system can be received by a rotation around the x-axis by 180 degree.
98  * @param iFlippedExtrinsic The inverted and flipped extrinsic camera matrix
99  * @param objectPoint The 3D object point for that the normalized image point will be calculated
100  * @return The resulting normalized image point
101  * @see objectPoint2normalizedImagePoint().
102  */
103  static inline VectorT2<T> objectPoint2normalizedImagePointIF(const HomogenousMatrixT4<T>& iFlippedExtrinsic, const VectorT3<T>& objectPoint);
104 
105  /**
106  * Calculates the normalized image points (the normalized projected object points) for a set of given object points with corresponding extrinsic camera matrix.
107  * The extrinsic matrix transforms a 3D point given in camera coordinates into 3D world coordinates.<br>
108  * The viewing direction of the camera is along the negative z-axis.<br>
109  * The extrinsic matrix will be flipped and inverted internally.
110  * @param extrinsic The extrinsic camera matrix
111  * @param objectPoints The set of 3D object points for that the normalized image points will be calculated
112  * @param numberObjectPoints The number of object points to project
113  * @param normalizedImagePoints The resulting normalized image points, make sure that enough memory is provided
114  * @see objectPoint2normalizedImagePoint(), objectPoints2normalizedImagePointsIF().
115  */
116  static inline void objectPoints2normalizedImagePoints(const HomogenousMatrixT4<T>& extrinsic, const VectorT3<T>* objectPoints, const size_t numberObjectPoints, VectorT2<T>* normalizedImagePoints);
117 
118  /**
119  * Calculates the normalized image points (the normalized projected object points) for a set of given object points with corresponding inverse and flipped extrinsic camera matrix.
120  * The inverse extrinsic matrix transforms a 3D point given in world coordinates into 3D camera coordinates.<br>
121  * The coordinate system of the camera is flipped meaning that the viewing direction is along the positive z-axis.<br>
122  * The flipped coordinate system can be received by a rotation around the x-axis by 180 degree.
123  * @param iFlippedExtrinsic The inverted and flipped extrinsic camera matrix
124  * @param objectPoints The set of 3D object points for that the normalized image points will be calculated
125  * @param numberObjectPoints The number of object points to project
126  * @param normalizedImagePoints The resulting normalized image points, make sure that enough memory is provided
127  * @see objectPoints2normalizedImagePoints().
128  */
129  static void objectPoints2normalizedImagePointsIF(const HomogenousMatrixT4<T>& iFlippedExtrinsic, const VectorT3<T>* objectPoints, const size_t numberObjectPoints, VectorT2<T>* normalizedImagePoints);
130 
131  /**
132  * Returns the 3x3 transformation matrix flipping a transformation around the x-axis by 180 deg.
133  * The matrix is defined by an angle-axis rotation: Rotation(1, 0, 0, PI).
134  * @return The transformation matrix
135  * @tparam U The data type of the elements of the matrix
136  * @see flipMatrix4(), flipQuaternion().
137  */
138  template <typename U = T>
140 
141  /**
142  * Returns the 4x4 transformation matrix flipping a transformation around the x-axis by 180 deg.
143  * The matrix is defined by an angle-axis rotation: Rotation(1, 0, 0, PI).
144  * @return The transformation matrix
145  * @tparam U The data type of the elements of the matrix
146  * @see flipMatrix3(), flipQuaternion().
147  */
148  template <typename U = T>
150 
151  /**
152  * Returns the quaternion flipping a rotation around the x-axis by 180 deg.
153  * The quaternion is defined by an angle-axis rotation: Rotation(1, 0, 0, PI).
154  * @return The transformation quaternion
155  * @tparam U The data type of the elements of the quaternion
156  * @see flipMatrix3(), flipMatrix4().
157  */
158  template <typename U = T>
160 
161  /**
162  * Flips a transformation matrix around the x-axis by 180 degree.
163  * The flip transformation is applied at the left side of the given matrix.
164  * @param left_T_right The transformation matrix to flip, must be valid
165  * @return The flipped transformation matrix, will be flippedLeft_T_right
166  * @tparam U The data type of the elements of the matrix
167  */
168  template <typename U>
170 
171  /**
172  * Flips a transformation matrix around the x-axis by 180 degree.
173  * The flip transformation is applied at the right side of the given matrix.
174  * @param left_T_right The transformation matrix to flip, must be valid
175  * @return The flipped transformation matrix, will be left_T_flippedRight
176  * @tparam U The data type of the elements of the matrix
177  */
178  template <typename U>
180 
181  /**
182  * Flips a transformation matrix around the x-axis by 180 degree.
183  * The flip transformation is applied at the left and right side of the original matrix.
184  * @param left_T_right The transformation matrix to flip, must be valid
185  * @return The flipped transformation matrix, will be flippedLeft_T_flippedRight
186  * @tparam U The data type of the elements of the matrix
187  */
188  template <typename U>
190 
191  /**
192  * Flips a 3x3 rotation matrix around the x-axis by 180 degree.
193  * The flip transformation is applied at the left side of the original rotation.
194  * @param left_R_right The rotation matrix to flip, must be valid
195  * @return The flipped rotation, will be flippedLeft_R_right
196  * @tparam U The data type of the elements of the rotation
197  */
198  template <typename U>
200 
201  /**
202  * Flips a 3x3 rotation matrix around the x-axis by 180 degree.
203  * The flip transformation is applied at the right side of the original rotation.
204  * @param left_R_right The rotation matrix to flip, must be valid
205  * @return The flipped rotation, will be left_R_flippedRight
206  * @tparam U The data type of the elements of the rotation
207  */
208  template <typename U>
210 
211  /**
212  * Flips a 3x3 rotation matrix around the x-axis by 180 degree.
213  * The flip transformation is applied at the left and right side of the original rotation.
214  * @param left_R_right The rotation matrix to flip, must be valid
215  * @return The flipped rotation, will be flippedLeft_R_flippedRight
216  * @tparam U The data type of the elements of the rotation
217  */
218  template <typename U>
220 
221  /**
222  * Flips a quaternion around the x-axis by 180 degree.
223  * The flip transformation is applied at the left side of the original rotation.
224  * @param left_Q_right The quaternion to flip, must be valid
225  * @return The flipped quaternion, will be flippedLeft_Q_right
226  * @tparam U The data type of the elements of the quaternion
227  */
228  template <typename U>
229  static inline QuaternionT<U> flippedTransformationLeftSide(const QuaternionT<U>& left_Q_right);
230 
231  /**
232  * Flips a quaternion around the x-axis by 180 degree.
233  * The flip transformation is applied at the right side of the original rotation.
234  * @param left_Q_right The quaternion to flip, must be valid
235  * @return The flipped quaternion, will be left_Q_flippedRight
236  * @tparam U The data type of the elements of the quaternion
237  */
238  template <typename U>
240 
241  /**
242  * Flips a quaternion around the x-axis by 180 degree.
243  * The flip transformation is applied at the left and right side of the original rotation.
244  * @param left_Q_right The quaternion to flip, must be valid
245  * @return The flipped quaternion, will be flippedLeft_Q_flippedRight
246  * @tparam U The data type of the elements of the quaternion
247  */
248  template <typename U>
250 
251  /**
252  * Transforms a standard homogenous 4x4 viewing (extrinsic camera) matrix into an inverted and flipped camera pose.
253  * The standard matrix defines a coordinate system with negative Z-axis as viewing direction in relation to the world coordinate system.<br>
254  * The inverted and flipped camera pose defines a coordinate system with positive Z-axis as viewing direction and transforms the world in relation to the camera coordinate system.
255  * @param world_T_camera The standard camera pose to transform, must be valid
256  * @return The inverted and flipped camera pose, flippedCamera_T_world
257  * @tparam U The data type of the elements of the matrix
258  * @see invertedFlipped2Standard().
259  */
260  template <typename U>
262 
263  /**
264  * Transforms standard homogenous 4x4 viewing (extrinsic camera) matrices into an inverted and flipped camera matrices.
265  * The standard matrix defines a coordinate system with negative Z-axis as viewing direction in relation to the world coordinate system.<br>
266  * The inverted and flipped camera pose defines a coordinate system with positive Z-axis as viewing direction and transforms the world in relation to the camera coordinate system.
267  * @param world_T_cameras The standard camera poses to transform, can be nullptr if number is 0u
268  * @param number The number of provided poses, with range [0, infinity)
269  * @return The inverted and flipped camera poses, flippedCameras_T_world
270  * @tparam U The data type of the elements of the matrix
271  * @see invertedFlipped2Standard().
272  */
273  template <typename U>
274  static inline HomogenousMatricesT4<U> standard2InvertedFlipped(const HomogenousMatrixT4<U>* world_T_cameras, const size_t number);
275 
276  /**
277  * Transforms standard homogenous 4x4 viewing (extrinsic camera) matrices into an inverted and flipped camera matrices.
278  * The standard matrix defines a coordinate system with negative Z-axis as viewing direction in relation to the world coordinate system.<br>
279  * The inverted and flipped camera pose defines a coordinate system with positive Z-axis as viewing direction and transforms the world in relation to the camera coordinate system.
280  * @param world_T_cameras The standard camera poses to transform, can be nullptr if number is 0u
281  * @param flippedCameras_T_world The resulting inverted and flipped camera poses
282  * @param number The number of provided poses, with range [0, infinity)
283  * @tparam U The data type of the elements of the matrix
284  * @see invertedFlipped2Standard().
285  */
286  template <typename U>
287  static inline void standard2InvertedFlipped(const HomogenousMatrixT4<U>* world_T_cameras, HomogenousMatrixT4<U>* flippedCameras_T_world, const size_t number);
288 
289  /**
290  * Transforms standard homogenous 4x4 viewing (extrinsic camera) matrices into an inverted and flipped camera matrices.
291  * The standard matrix defines a coordinate system with negative Z-axis as viewing direction in relation to the world coordinate system.<br>
292  * The inverted and flipped camera pose defines a coordinate system with positive Z-axis as viewing direction and transforms the world in relation to the camera coordinate system.
293  * @param world_T_cameras The standard camera poses to transform
294  * @return The inverted and flipped camera poses, flippedCameras_T_world
295  * @tparam U The data type of the elements of the matrix
296  * @see invertedFlipped2Standard().
297  */
298  template <typename U>
300 
301  /**
302  * Transforms a standard 3x3 rotation matrix into an inverted and flipped rotation matrix.
303  * The standard rotation defines a coordinate system with negative Z-axis as viewing direction in relation to the world coordinate system.<br>
304  * The inverted and flipped rotation matrix defines a coordinate system with positive Z-axis as viewing direction and transforms the world in relation to the camera coordinate system.
305  * @param world_R_camera The standard rotation matrix of the camera pose to transform, must be valid
306  * @return The inverted and flipped rotation matrix of camera pose, flippedCamera_R_world
307  * @tparam U The data type of the elements of the matrix
308  * @see invertedFlipped2Standard().
309  */
310  template <typename U>
312 
313  /**
314  * Transforms a standard rotation quaternion into an inverted and flipped rotation quaternion.
315  * The standard rotation defines a coordinate system with negative Z-axis as viewing direction in relation to the world coordinate system.<br>
316  * The inverted and flipped rotation quaternion defines a coordinate system with positive Z-axis as viewing direction and transforms the world in relation to the camera coordinate system.
317  * @param world_Q_camera The standard rotation quaternion of the camera pose to transform, must be valid
318  * @return The inverted and flipped rotation quaternion of camera pose, flippedCamera_Q_world
319  * @tparam U The data type of the elements of the quaternion
320  * @see invertedFlipped2Standard().
321  */
322  template <typename U>
324 
325  /**
326  * Transforms an inverted and flipped camera pose into a standard camera pose.
327  * @param flippedCamera_T_world The inverted and flipped camera pose to transform, must be valid
328  * @return The standard camera pose, world_T_camera
329  * @tparam U The data type of the elements of the matrix
330  * @see standard2InvertedFlipped().
331  */
332  template <typename U>
333  static inline HomogenousMatrixT4<U> invertedFlipped2Standard(const HomogenousMatrixT4<U>& flippedCamera_T_world);
334 
335  /**
336  * Transforms inverted and flipped camera matrices into standard viewing (extrinsic camera) matrices.
337  * @param flippedCameras_T_world The inverted and flipped camera poses to transform, can be nullptr if number == 0
338  * @param number The number of poses, with range [0, infinity)
339  * @return The standard viewing poses, world_T_cameras
340  * @tparam U The data type of the elements of the matrix
341  * @see standard2InvertedFlipped().
342  */
343  template <typename U>
344  static inline HomogenousMatricesT4<U> invertedFlipped2Standard(const HomogenousMatrixT4<U>* flippedCameras_T_world, const size_t number);
345 
346  /**
347  * Transforms inverted and flipped camera matrices into standard viewing (extrinsic camera) matrices.
348  * @param flippedCameras_T_world The inverted and flipped camera poses to transform, can be nullptr if number == 0
349  * @param world_T_cameras The resulting standard camera poses, can be nullptr if number == 0
350  * @param number The number of poses, with range [0, infinity)
351  * @tparam U The data type of the elements of the matrix
352  * @see standard2InvertedFlipped().
353  */
354  template <typename U>
355  static inline void invertedFlipped2Standard(const HomogenousMatrixT4<U>* flippedCameras_T_world, HomogenousMatrixT4<U>* world_T_cameras, const size_t number);
356 
357  /**
358  * Transforms inverted and flipped camera matrices into standard viewing (extrinsic camera) matrices.
359  * @param flippedCameras_T_world The inverted and flipped camera poses to transform
360  * @return The standard camera poses, world_T_cameras
361  * @tparam U The data type of the elements of the matrix
362  * @see standard2InvertedFlipped().
363  */
364  template <typename U>
365  static inline HomogenousMatricesT4<U> invertedFlipped2Standard(const HomogenousMatricesT4<U>& flippedCameras_T_world);
366 
367  /**
368  * Transforms an inverted and flipped rotation matrix into a standard viewing rotation matrix.
369  * @param flippedCamera_R_world The inverted and flipped rotation matrix of camera to transform, must be valid
370  * @return The rotation matrix of standard camera pose, world_R_camera
371  * @tparam U The data type of the elements of the matrix
372  * @see standard2InvertedFlipped().
373  */
374  template <typename U>
375  static inline SquareMatrixT3<U> invertedFlipped2Standard(const SquareMatrixT3<U>& flippedCamera_R_world);
376 
377  /**
378  * Transforms an inverted and flipped rotation quaternion into a standard viewing rotation quaternion.
379  * @param flippedCamera_Q_world The inverted and flipped rotation quaternion of camera pose to transform
380  * @return The rotation quaternion of standard camera pose, world_Q_camera
381  * @tparam U The data type of the elements of the quaternion
382  * @see standard2InvertedFlipped().
383  */
384  template <typename U>
385  static inline QuaternionT<U> invertedFlipped2Standard(const QuaternionT<U>& flippedCamera_Q_world);
386 
387  /**
388  * Determines whether a given 3D object point lies in front of a camera while the location of the camera is defined by a 6-DOF pose.
389  * This function actually determined whether (iFlippedPose * objectPoint).z() > epsilon.
390  * @param flippedCamera_T_world The inverted and flipped pose of the camera, must be valid
391  * @param objectPoint The object point to check
392  * @param epsilon The minimal distance between camera and object point on the z-axis so that the object point counts as lying in front, with range [0, infinity)
393  * @return True, if so
394  */
395  static inline bool isObjectPointInFrontIF(const HomogenousMatrixT4<T>& flippedCamera_T_world, const VectorT3<T>& objectPoint, const T epsilon = NumericT<T>::eps());
396 
397  /**
398  * Determines whether a given 3D object point lies in front of a camera while the location of the camera is defined by a 3-DOF orientation.
399  * This function actually determined whether (iFlippedPose * objectPoint).z() > epsilon.
400  * @param flippedCamera_R_world The inverted and flipped orientation of the camera, must be valid
401  * @param objectPoint The object point to check
402  * @param epsilon The minimal distance between camera and object point on the z-axis so that the object point counts as lying in front, with range [0, infinity)
403  * @return True, if so
404  */
405  static inline bool isObjectPointInFrontIF(const SquareMatrixT3<T>& flippedCamera_R_world, const VectorT3<T>& objectPoint, const T epsilon = NumericT<T>::eps());
406 };
407 
408 template <typename T>
409 T CameraT<T>::fovX2Y(const T fovX, const T aspectRatio)
410 {
411  ocean_assert(aspectRatio != 0);
412 
413  return 2 * NumericT<T>::atan(NumericT<T>::tan(T(0.5) * fovX) / aspectRatio);
414 }
415 
416 template <typename T>
417 T CameraT<T>::fovY2X(const T fovY, const T aspectRatio)
418 {
419  ocean_assert(aspectRatio != 0);
420 
421  return 2 * NumericT<T>::atan(NumericT<T>::tan(T(0.5) * fovY) * aspectRatio);
422 }
423 
424 template <typename T>
425 T CameraT<T>::fieldOfViewToFocalLength(const unsigned int width, const T fovX)
426 {
427  ocean_assert(width > 0u);
428  ocean_assert(fovX > NumericT<T>::eps() && fovX < NumericT<T>::pi());
429 
430  const T width_2 = T(width) * T(0.5);
431 
432  return width_2 / NumericT<T>::tan(fovX * T(0.5));
433 }
434 
435 template <typename T>
437 {
438  ocean_assert(extrinsic.isValid());
439 
440  return objectPoint2normalizedImagePointIF(standard2InvertedFlipped(extrinsic), objectPoint);
441 }
442 
443 template <typename T>
445 {
446  ocean_assert(iFlippedExtrinsic.isValid());
447 
448  const VectorT3<T> transformedObjectPoint(iFlippedExtrinsic * objectPoint);
449 
450  ocean_assert(NumericT<T>::isNotEqualEps(transformedObjectPoint.z()));
451  if (NumericT<T>::isEqualEps(transformedObjectPoint.z()))
452  {
453  return VectorT2<T>(0, 0);
454  }
455 
456  const T factor = 1 / transformedObjectPoint.z();
457  return VectorT2<T>(transformedObjectPoint.x() * factor, transformedObjectPoint.y() * factor);
458 }
459 
460 template <typename T>
461 inline void CameraT<T>::objectPoints2normalizedImagePoints(const HomogenousMatrixT4<T>& extrinsic, const VectorT3<T>* objectPoints, const size_t numberObjectPoints, VectorT2<T>* normalizedImagePoints)
462 {
463  ocean_assert(extrinsic.isValid());
464  ocean_assert(numberObjectPoints == 0u || (objectPoints && normalizedImagePoints));
465 
466  objectPoints2normalizedImagePointsIF(standard2InvertedFlipped(extrinsic), objectPoints, numberObjectPoints, normalizedImagePoints);
467 }
468 
469 template <typename T>
470 void CameraT<T>::objectPoints2normalizedImagePointsIF(const HomogenousMatrixT4<T>& iFlippedExtrinsic, const VectorT3<T>* objectPoints, const size_t numberObjectPoints, VectorT2<T>* normalizedImagePoints)
471 {
472  ocean_assert(iFlippedExtrinsic.isValid());
473  ocean_assert(numberObjectPoints == 0u || (objectPoints && normalizedImagePoints));
474 
475  for (unsigned int n = 0u; n < numberObjectPoints; ++n)
476  {
477  const VectorT3<T> transformedObjectPoint(iFlippedExtrinsic * objectPoints[n]);
478 
479  ocean_assert(NumericT<T>::isNotEqualEps(transformedObjectPoint.z()));
480 
481  if (NumericT<T>::isNotEqualEps(transformedObjectPoint.z()))
482  {
483  const T factor = 1 / transformedObjectPoint.z();
484  normalizedImagePoints[n].x() = transformedObjectPoint.x() * factor;
485  normalizedImagePoints[n].y() = transformedObjectPoint.y() * factor;
486  }
487  else
488  {
489  normalizedImagePoints[n].x() = 0;
490  normalizedImagePoints[n].y() = 0;
491  }
492  }
493 }
494 
495 template <typename T>
496 template <typename U>
498 {
499  ocean_assert(SquareMatrixT3<U>(1, 0, 0, 0, -1, 0, 0, 0, -1) == SquareMatrixT3<U>(RotationT<U>(1, 0, 0, NumericT<U>::pi())));
500 
501  return SquareMatrixT3<U>(1, 0, 0, 0, -1, 0, 0, 0, -1);
502 }
503 
504 template <typename T>
505 template <typename U>
507 {
508  const U flipValues[16] =
509  {
510  1, 0, 0, 0,
511  0, -1, 0, 0,
512  0, 0, -1, 0,
513  0, 0, 0, 1
514  };
515 
516  ocean_assert(HomogenousMatrixT4<U>(flipValues) == HomogenousMatrixT4<U>(RotationT<U>(1, 0, 0, NumericT<U>::pi())));
517 
518  return HomogenousMatrixT4<U>(flipValues);
519 }
520 
521 template <typename T>
522 template <typename U>
524 {
525  ocean_assert(QuaternionT<U>(0, 1, 0, 0) == QuaternionT<U>(VectorT3<U>(1, 0, 0), NumericT<U>::pi()));
526 
527  return QuaternionT<U>(0, 1, 0, 0);
528 }
529 
530 template <typename T>
531 template <typename U>
533 {
534  /*
535  * | rx1 rx2 rx3 tx | | rx1 rx2 rx3 tx |
536  * | ry1 ry2 ry3 ty | -> | -ry1 -ry2 -ry3 -ty |
537  * | rz1 rz2 rz3 tz | | -rz1 -rz2 -rz3 -tz |
538  * | 0 0 0 1 | | 0 0 0 1 |
539  */
540 
541  HomogenousMatrixT4<U> result(left_T_right);
542 
543  result[1] = -result[1];
544  result[2] = -result[2];
545 
546  result[5] = -result[5];
547  result[6] = -result[6];
548 
549  result[9] = -result[9];
550  result[10] = -result[10];
551 
552  result[13] = -result[13];
553  result[14] = -result[14];
554 
555  ocean_assert(result == flipMatrix4<U>() * left_T_right);
556 
557  return result;
558 }
559 
560 template <typename T>
561 template <typename U>
563 {
564  /*
565  * | rx1 rx2 rx3 tx | | rx1 -rx2 -rx3 tx |
566  * | ry1 ry2 ry3 ty | -> | ry1 -ry2 -ry3 ty |
567  * | rz1 rz2 rz3 tz | | rz1 -rz2 -rz3 tz |
568  * | 0 0 0 1 | | 0 0 0 1 |
569  */
570 
571  HomogenousMatrixT4<U> result(left_T_right);
572 
573  result[4] = -result[4];
574  result[5] = -result[5];
575  result[6] = -result[6];
576 
577  result[8] = -result[8];
578  result[9] = -result[9];
579  result[10] = -result[10];
580 
581  ocean_assert(result == left_T_right * flipMatrix4<U>());
582 
583  return result;
584 }
585 
586 template <typename T>
587 template <typename U>
589 {
590  /*
591  * | rx1 rx2 rx3 tx | | rx1 -rx2 -rx3 tx |
592  * | ry1 ry2 ry3 ty | -> | -ry1 ry2 ry3 -ty |
593  * | rz1 rz2 rz3 tz | | -rz1 rz2 rz3 -tz |
594  * | 0 0 0 1 | | 0 0 0 1 |
595  */
596 
597  HomogenousMatrixT4<U> result(left_T_right);
598 
599  result[1] = -result[1];
600  result[2] = -result[2];
601 
602  result[4] = -result[4];
603 
604  result[8] = -result[8];
605 
606  result[13] = -result[13];
607  result[14] = -result[14];
608 
609  ocean_assert(result == flipMatrix4<U>() * left_T_right * flipMatrix4<U>());
610 
611  return result;
612 }
613 
614 template <typename T>
615 template <typename U>
617 {
618  /*
619  * | rx1 rx2 rx3 | | rx1 rx2 rx3 |
620  * | ry1 ry2 ry3 | -> | -ry1 -ry2 -ry3 |
621  * | rz1 rz2 rz3 | | -rz1 -rz2 -rz3 |
622  */
623 
624  SquareMatrixT3<U> result(left_R_right);
625 
626  result[1] = -result[1];
627  result[2] = -result[2];
628 
629  result[4] = -result[4];
630  result[5] = -result[5];
631 
632  result[7] = -result[7];
633  result[8] = -result[8];
634 
635  ocean_assert(result == left_R_right * flipMatrix3<U>());
636 
637  return result;
638 }
639 
640 template <typename T>
641 template <typename U>
643 {
644  /*
645  * | rx1 rx2 rx3 | | rx1 -rx2 -rx3 |
646  * | ry1 ry2 ry3 | -> | ry1 -ry2 -ry3 |
647  * | rz1 rz2 rz3 | | rz1 -rz2 -rz3 |
648  */
649 
650  ocean_assert(SquareMatrixT3<U>(left_R_right.xAxis(), -left_R_right.yAxis(), -left_R_right.zAxis()) == left_R_right * flipMatrix3<U>());
651 
652  return SquareMatrixT3<U>(left_R_right.xAxis(), -left_R_right.yAxis(), -left_R_right.zAxis());
653 }
654 
655 template <typename T>
656 template <typename U>
658 {
659  /*
660  * | rx1 rx2 rx3 | | rx1 -rx2 -rx3 |
661  * | ry1 ry2 ry3 | -> | -ry1 ry2 ry3 |
662  * | rz1 rz2 rz3 | | -rz1 rz2 rz3 |
663  */
664 
665  SquareMatrixT3<U> result(left_R_right);
666 
667  result[1] = -result[1];
668  result[2] = -result[2];
669 
670  result[3] = -result[4];
671 
672  result[6] = -result[5];
673 
674  ocean_assert(result == flipMatrix3<U>() * left_R_right * flipMatrix3<U>());
675 
676  return result;
677 }
678 
679 template <typename T>
680 template <typename U>
682 {
683  return flipQuaternion<U>() * left_Q_right;
684 }
685 
686 template <typename T>
687 template <typename U>
689 {
690  return left_Q_right * flipQuaternion<U>();
691 }
692 
693 template <typename T>
694 template <typename U>
696 {
697  return flipQuaternion<U>() * left_Q_right * flipQuaternion<U>();
698 }
699 
700 template <typename T>
701 template <typename U>
702 inline HomogenousMatricesT4<U> CameraT<T>::standard2InvertedFlipped(const HomogenousMatrixT4<U>* world_T_cameras, const size_t number)
703 {
704  HomogenousMatricesT4<U> flippedCameras_T_world;
705  flippedCameras_T_world.reserve(number);
706 
707  for (size_t n = 0; n < number; ++n)
708  {
709  flippedCameras_T_world.emplace_back(standard2InvertedFlipped<U>(world_T_cameras[n]));
710  }
711 
712  return flippedCameras_T_world;
713 }
714 
715 template <typename T>
716 template <typename U>
717 inline void CameraT<T>::standard2InvertedFlipped(const HomogenousMatrixT4<U>* world_T_cameras, HomogenousMatrixT4<U>* flippedCameras_T_world, const size_t number)
718 {
719  for (size_t n = 0; n < number; ++n)
720  {
721  flippedCameras_T_world[n] = standard2InvertedFlipped<U>(world_T_cameras[n]);
722  }
723 }
724 
725 template <typename T>
726 template <typename U>
728 {
729  return standard2InvertedFlipped<U>(world_T_cameras.data(), world_T_cameras.size());
730 }
731 
732 template <typename T>
733 template <typename U>
735 {
736  ocean_assert(world_T_camera.isValid());
737 
738  return flippedTransformationRightSide<U>(world_T_camera).inverted();
739 }
740 
741 template <typename T>
742 template <typename U>
744 {
745  return flippedTransformationRightSide<U>(world_R_camera).inverted();
746 }
747 
748 template <typename T>
749 template <typename U>
751 {
752  return flippedTransformationRightSide<U>(world_Q_camera).inverted();
753 }
754 
755 template <typename T>
756 template <typename U>
758 {
759  ocean_assert(flippedCamera_T_world.isValid());
760 
761  return flippedTransformationRightSide<U>(flippedCamera_T_world.inverted());
762 }
763 
764 template <typename T>
765 template <typename U>
767 {
768  return flippedTransformationRightSide<U>(flippedCamera_R_world.inverted());
769 }
770 
771 template <typename T>
772 template <typename U>
774 {
775  return flippedTransformationRightSide<U>(flippedCamera_Q_world.inverted());
776 }
777 
778 template <typename T>
779 template <typename U>
780 inline HomogenousMatricesT4<U> CameraT<T>::invertedFlipped2Standard(const HomogenousMatrixT4<U>* flippedCameras_T_world, const size_t number)
781 {
782  HomogenousMatricesT4<U> cameras_T_world;
783  cameras_T_world.reserve(number);
784 
785  for (size_t n = 0; n < number; ++n)
786  {
787  cameras_T_world.emplace_back(invertedFlipped2Standard<U>(flippedCameras_T_world[n]));
788  }
789 
790  return cameras_T_world;
791 }
792 
793 template <typename T>
794 template <typename U>
795 inline void CameraT<T>::invertedFlipped2Standard(const HomogenousMatrixT4<U>* flippedCameras_T_world, HomogenousMatrixT4<U>* world_T_camera, const size_t number)
796 {
797  for (size_t n = 0; n < number; ++n)
798  {
799  world_T_camera[n] = invertedFlipped2Standard<U>(flippedCameras_T_world[n]);
800  }
801 }
802 
803 template <typename T>
804 template <typename U>
806 {
807  return invertedFlipped2Standard<U>(flippedCameras_T_world.data(), flippedCameras_T_world.size());
808 }
809 
810 template <typename T>
811 inline bool CameraT<T>::isObjectPointInFrontIF(const HomogenousMatrixT4<T>& flippedCamera_T_world, const VectorT3<T>& objectPoint, const T epsilon)
812 {
813  ocean_assert(flippedCamera_T_world.isValid());
814  ocean_assert(epsilon >= 0);
815 
816  // the inverted flipped pose looks towards the positive z-axis, so that object points lying in front of the camera must have a positive z-value
817 
818  ocean_assert((flippedCamera_T_world[2] * objectPoint.x() + flippedCamera_T_world[6] * objectPoint.y() + flippedCamera_T_world[10] * objectPoint.z() + flippedCamera_T_world[14] > epsilon) == ((flippedCamera_T_world * objectPoint).z() > epsilon));
819  return flippedCamera_T_world[2] * objectPoint.x() + flippedCamera_T_world[6] * objectPoint.y() + flippedCamera_T_world[10] * objectPoint.z() + flippedCamera_T_world[14] > epsilon;
820 }
821 
822 template <typename T>
823 inline bool CameraT<T>::isObjectPointInFrontIF(const SquareMatrixT3<T>& flippedCamera_R_world, const VectorT3<T>& objectPoint, const T epsilon)
824 {
825  ocean_assert(!flippedCamera_R_world.isNull());
826  ocean_assert(epsilon >= 0);
827 
828  // the inverted flipped orientation looks towards the positive z-axis, so that object points lying in front of the camera must have a positive z-value
829 
830  ocean_assert((flippedCamera_R_world[2] * objectPoint.x() + flippedCamera_R_world[5] * objectPoint.y() + flippedCamera_R_world[8] * objectPoint.z() > epsilon) == ((flippedCamera_R_world * objectPoint).z() > epsilon));
831  return flippedCamera_R_world[2] * objectPoint.x() + flippedCamera_R_world[5] * objectPoint.y() + flippedCamera_R_world[8] * objectPoint.z() > epsilon;
832 }
833 
834 }
835 
836 #endif // META_OCEAN_MATH_CAMERA_H
static HomogenousMatricesT4< U > standard2InvertedFlipped(const HomogenousMatrixT4< U > *world_T_cameras, const size_t number)
Transforms standard homogenous 4x4 viewing (extrinsic camera) matrices into an inverted and flipped c...
Definition: Camera.h:702
static void invertedFlipped2Standard(const HomogenousMatrixT4< U > *flippedCameras_T_world, HomogenousMatrixT4< U > *world_T_cameras, const size_t number)
Transforms inverted and flipped camera matrices into standard viewing (extrinsic camera) matrices.
Definition: Camera.h:795
static void standard2InvertedFlipped(const HomogenousMatrixT4< U > *world_T_cameras, HomogenousMatrixT4< U > *flippedCameras_T_world, const size_t number)
Transforms standard homogenous 4x4 viewing (extrinsic camera) matrices into an inverted and flipped c...
Definition: Camera.h:717
static QuaternionT< U > flippedTransformationLeftSide(const QuaternionT< U > &left_Q_right)
Flips a quaternion around the x-axis by 180 degree.
Definition: Camera.h:681
static HomogenousMatricesT4< U > invertedFlipped2Standard(const HomogenousMatricesT4< U > &flippedCameras_T_world)
Transforms inverted and flipped camera matrices into standard viewing (extrinsic camera) matrices.
Definition: Camera.h:805
static HomogenousMatrixT4< U > standard2InvertedFlipped(const HomogenousMatrixT4< U > &world_T_camera)
Transforms a standard homogenous 4x4 viewing (extrinsic camera) matrix into an inverted and flipped c...
Definition: Camera.h:734
static void objectPoints2normalizedImagePoints(const HomogenousMatrixT4< T > &extrinsic, const VectorT3< T > *objectPoints, const size_t numberObjectPoints, VectorT2< T > *normalizedImagePoints)
Calculates the normalized image points (the normalized projected object points) for a set of given ob...
Definition: Camera.h:461
static QuaternionT< U > flipQuaternion()
Returns the quaternion flipping a rotation around the x-axis by 180 deg.
Definition: Camera.h:523
static HomogenousMatrixT4< U > flipMatrix4()
Returns the 4x4 transformation matrix flipping a transformation around the x-axis by 180 deg.
Definition: Camera.h:506
static SquareMatrixT3< U > flippedTransformationLeftSide(const SquareMatrixT3< U > &left_R_right)
Flips a 3x3 rotation matrix around the x-axis by 180 degree.
Definition: Camera.h:616
static QuaternionT< U > standard2InvertedFlipped(const QuaternionT< U > &world_Q_camera)
Transforms a standard rotation quaternion into an inverted and flipped rotation quaternion.
Definition: Camera.h:750
static VectorT2< T > objectPoint2normalizedImagePointIF(const HomogenousMatrixT4< T > &iFlippedExtrinsic, const VectorT3< T > &objectPoint)
Calculates the normalized image point (the normalized projected object point) for a given object poin...
Definition: Camera.h:444
static HomogenousMatrixT4< U > flippedTransformationRightSide(const HomogenousMatrixT4< U > &left_T_right)
Flips a transformation matrix around the x-axis by 180 degree.
Definition: Camera.h:562
static T fieldOfViewToFocalLength(const unsigned int width, const T fovX)
Converts field of view (and width) to the corresponding focal length.
Definition: Camera.h:425
static VectorT2< T > objectPoint2normalizedImagePoint(const HomogenousMatrixT4< T > &extrinsic, const VectorT3< T > &objectPoint)
Calculates the normalized image point (the normalized projected object point) for a of given object p...
Definition: Camera.h:436
static void objectPoints2normalizedImagePointsIF(const HomogenousMatrixT4< T > &iFlippedExtrinsic, const VectorT3< T > *objectPoints, const size_t numberObjectPoints, VectorT2< T > *normalizedImagePoints)
Calculates the normalized image points (the normalized projected object points) for a set of given ob...
Definition: Camera.h:470
static HomogenousMatrixT4< U > flippedTransformationLeftSide(const HomogenousMatrixT4< U > &left_T_right)
Flips a transformation matrix around the x-axis by 180 degree.
Definition: Camera.h:532
static SquareMatrixT3< U > standard2InvertedFlipped(const SquareMatrixT3< U > &world_R_camera)
Transforms a standard 3x3 rotation matrix into an inverted and flipped rotation matrix.
Definition: Camera.h:743
static QuaternionT< U > flippedTransformationLeftAndRightSide(const QuaternionT< U > &left_Q_right)
Flips a quaternion around the x-axis by 180 degree.
Definition: Camera.h:695
static HomogenousMatrixT4< U > invertedFlipped2Standard(const HomogenousMatrixT4< U > &flippedCamera_T_world)
Transforms an inverted and flipped camera pose into a standard camera pose.
Definition: Camera.h:757
static SquareMatrixT3< U > flipMatrix3()
Returns the 3x3 transformation matrix flipping a transformation around the x-axis by 180 deg.
Definition: Camera.h:497
static SquareMatrixT3< U > flippedTransformationRightSide(const SquareMatrixT3< U > &left_R_right)
Flips a 3x3 rotation matrix around the x-axis by 180 degree.
Definition: Camera.h:642
static HomogenousMatricesT4< U > standard2InvertedFlipped(const HomogenousMatricesT4< U > &world_T_cameras)
Transforms standard homogenous 4x4 viewing (extrinsic camera) matrices into an inverted and flipped c...
Definition: Camera.h:727
static SquareMatrixT3< U > invertedFlipped2Standard(const SquareMatrixT3< U > &flippedCamera_R_world)
Transforms an inverted and flipped rotation matrix into a standard viewing rotation matrix.
Definition: Camera.h:766
static QuaternionT< U > flippedTransformationRightSide(const QuaternionT< U > &left_Q_right)
Flips a quaternion around the x-axis by 180 degree.
Definition: Camera.h:688
static bool isObjectPointInFrontIF(const SquareMatrixT3< T > &flippedCamera_R_world, const VectorT3< T > &objectPoint, const T epsilon=NumericT< T >::eps())
Determines whether a given 3D object point lies in front of a camera while the location of the camera...
Definition: Camera.h:823
static HomogenousMatrixT4< U > flippedTransformationLeftAndRightSide(const HomogenousMatrixT4< U > &left_T_right)
Flips a transformation matrix around the x-axis by 180 degree.
Definition: Camera.h:588
static T fovY2X(const T fovY, const T aspectRatio)
Calculates the horizontal FOV from the vertical FOV and the aspect ratio of the camera image.
Definition: Camera.h:417
static QuaternionT< U > invertedFlipped2Standard(const QuaternionT< U > &flippedCamera_Q_world)
Transforms an inverted and flipped rotation quaternion into a standard viewing rotation quaternion.
Definition: Camera.h:773
static T fovX2Y(const T fovX, const T aspectRatio)
Calculates the vertical FOV from the horizontal FOV and the aspect ratio of the camera image.
Definition: Camera.h:409
static SquareMatrixT3< U > flippedTransformationLeftAndRightSide(const SquareMatrixT3< U > &left_R_right)
Flips a 3x3 rotation matrix around the x-axis by 180 degree.
Definition: Camera.h:657
static bool isObjectPointInFrontIF(const HomogenousMatrixT4< T > &flippedCamera_T_world, const VectorT3< T > &objectPoint, const T epsilon=NumericT< T >::eps())
Determines whether a given 3D object point lies in front of a camera while the location of the camera...
Definition: Camera.h:811
static HomogenousMatricesT4< U > invertedFlipped2Standard(const HomogenousMatrixT4< U > *flippedCameras_T_world, const size_t number)
Transforms inverted and flipped camera matrices into standard viewing (extrinsic camera) matrices.
Definition: Camera.h:780
This class implements a 4x4 homogeneous transformation matrix using floating point values with the pr...
Definition: HomogenousMatrix4.h:110
HomogenousMatrixT4< T > inverted() const noexcept
Returns the inverted of this matrix.
Definition: HomogenousMatrix4.h:1575
bool isValid() const
Returns whether this matrix is a valid homogeneous transformation.
Definition: HomogenousMatrix4.h:1806
This class provides basic numeric functionalities.
Definition: Numeric.h:57
static T atan(const T value)
Returns the arctangent of a given value.
Definition: Numeric.h:1616
static T tan(const T value)
Returns the tangent of a given value.
Definition: Numeric.h:1600
This class implements a unit quaternion rotation.
Definition: Quaternion.h:100
QuaternionT< T > inverted() const
Returns the inverted quaternion.
Definition: Quaternion.h:754
This class implements a axis-angle rotation using floating point values.
Definition: Rotation.h:79
This class implements a 3x3 square matrix.
Definition: SquareMatrix3.h:88
VectorT3< T > xAxis() const
Returns the x axis which is the first column of the matrix.
Definition: SquareMatrix3.h:1396
bool isNull() const
Returns whether this matrix is a zero matrix.
Definition: SquareMatrix3.h:1333
VectorT3< T > zAxis() const
Returns the z axis which is the last column of the matrix.
Definition: SquareMatrix3.h:1408
VectorT3< T > yAxis() const
Returns the y axis which is the middle column of the matrix.
Definition: SquareMatrix3.h:1402
SquareMatrixT3< T > inverted() const
Returns the inverted matrix of this matrix.
Definition: SquareMatrix3.h:1176
This class implements a vector with two elements.
Definition: Vector2.h:96
const T & x() const noexcept
Returns the x value.
Definition: Vector2.h:698
const T & y() const noexcept
Returns the y value.
Definition: Vector2.h:710
This class implements a vector with three elements.
Definition: Vector3.h:97
const T & y() const noexcept
Returns the y value.
Definition: Vector3.h:812
const T & x() const noexcept
Returns the x value.
Definition: Vector3.h:800
const T & z() const noexcept
Returns the z value.
Definition: Vector3.h:824
std::vector< HomogenousMatrixT4< T > > HomogenousMatricesT4
Definition of a typename alias for vectors with HomogenousMatrixT4 objects.
Definition: HomogenousMatrix4.h:66
CameraT< double > CameraD
Definition of an Camera object with double precision.
Definition: Camera.h:36
CameraT< float > CameraF
Definition of an Camera object with float precision.
Definition: Camera.h:43
CameraT< Scalar > Camera
Definition of an Camera object with Scalar precision.
Definition: Camera.h:22
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15