Ocean
Loading...
Searching...
No Matches
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"
15#include "ocean/math/Vector2.h"
16#include "ocean/math/Vector3.h"
17
18namespace Ocean
19{
20
21// Forward declaration.
22template <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 */
52template <typename T>
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>
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>
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
408template <typename T>
409T 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
416template <typename T>
417T 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
424template <typename T>
425T 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
435template <typename T>
437{
438 ocean_assert(extrinsic.isValid());
439
440 return objectPoint2normalizedImagePointIF(standard2InvertedFlipped(extrinsic), objectPoint);
441}
442
443template <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
460template <typename T>
461inline 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
469template <typename T>
470void 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
495template <typename T>
496template <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
504template <typename T>
505template <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
521template <typename T>
522template <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
530template <typename T>
531template <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
560template <typename T>
561template <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
586template <typename T>
587template <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
614template <typename T>
615template <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
640template <typename T>
641template <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
655template <typename T>
656template <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
679template <typename T>
680template <typename U>
682{
683 return flipQuaternion<U>() * left_Q_right;
684}
685
686template <typename T>
687template <typename U>
689{
690 return left_Q_right * flipQuaternion<U>();
691}
692
693template <typename T>
694template <typename U>
696{
697 return flipQuaternion<U>() * left_Q_right * flipQuaternion<U>();
698}
699
700template <typename T>
701template <typename U>
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
715template <typename T>
716template <typename U>
717inline 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
725template <typename T>
726template <typename U>
728{
729 return standard2InvertedFlipped<U>(world_T_cameras.data(), world_T_cameras.size());
730}
731
732template <typename T>
733template <typename U>
735{
736 ocean_assert(world_T_camera.isValid());
737
738 return flippedTransformationRightSide<U>(world_T_camera).inverted();
739}
740
741template <typename T>
742template <typename U>
744{
745 return flippedTransformationRightSide<U>(world_R_camera).inverted();
746}
747
748template <typename T>
749template <typename U>
751{
752 return flippedTransformationRightSide<U>(world_Q_camera).inverted();
753}
754
755template <typename T>
756template <typename U>
758{
759 ocean_assert(flippedCamera_T_world.isValid());
760
761 return flippedTransformationRightSide<U>(flippedCamera_T_world.inverted());
762}
763
764template <typename T>
765template <typename U>
767{
768 return flippedTransformationRightSide<U>(flippedCamera_R_world.inverted());
769}
770
771template <typename T>
772template <typename U>
774{
775 return flippedTransformationRightSide<U>(flippedCamera_Q_world.inverted());
776}
777
778template <typename T>
779template <typename U>
780inline 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
793template <typename T>
794template <typename U>
795inline 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
803template <typename T>
804template <typename U>
806{
807 return invertedFlipped2Standard<U>(flippedCameras_T_world.data(), flippedCameras_T_world.size());
808}
809
810template <typename T>
811inline 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
822template <typename T>
823inline 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
This class implements the base class for all cameras.
Definition Camera.h:54
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:710
const T & y() const noexcept
Returns the y value.
Definition Vector2.h:722
This class implements a vector with three elements.
Definition Vector3.h:97
const T & y() const noexcept
Returns the y value.
Definition Vector3.h:824
const T & x() const noexcept
Returns the x value.
Definition Vector3.h:812
const T & z() const noexcept
Returns the z value.
Definition Vector3.h:836
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:29
The namespace covering the entire Ocean framework.
Definition Accessor.h:15