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