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