Ocean
Loading...
Searching...
No Matches
AnyCamera.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_ANY_CAMERA_H
9#define META_OCEAN_MATH_ANY_CAMERA_H
10
11#include "ocean/math/Math.h"
12#include "ocean/math/Camera.h"
16#include "ocean/math/Vector2.h"
17#include "ocean/math/Vector3.h"
18
19namespace Ocean
20{
21
22// Forward declaration.
23template <typename T>
24class AnyCameraT;
25
26/**
27 * Definition of an AnyCamera object with Scalar precision.
28 * @see AnyCameraT
29 * @ingroup math
30 */
32
33/**
34 * Definition of an AnyCamera object with double precision.
35 * @see AnyCameraT
36 * @ingroup math
37 */
39
40/**
41 * Definition of an AnyCamera object with float precision.
42 * @see AnyCameraT
43 * @ingroup math
44 */
46
47/**
48 * Definition of a shared pointer holding an AnyCamera object with Scalar precision.
49 * @tparam T the data type of the scalar to be used either 'float' or 'double'
50 * @see AnyCameraT
51 * @ingroup math
52 */
53template <typename T>
54using SharedAnyCameraT = std::shared_ptr<AnyCameraT<T>>;
55
56/**
57 * Definition of a shared pointer holding an AnyCamera object with Scalar precision.
58 * @see AnyCameraT
59 * @ingroup math
60 */
61using SharedAnyCamera = std::shared_ptr<AnyCamera>;
62
63/**
64 * Definition of a shared pointer holding an AnyCamera object with double precision.
65 * @see AnyCameraT
66 * @ingroup math
67 */
68using SharedAnyCameraD = std::shared_ptr<AnyCameraD>;
69
70/**
71 * Definition of a shared pointer holding an AnyCamera object with float precision.
72 * @see AnyCameraT
73 * @ingroup math
74 */
75using SharedAnyCameraF = std::shared_ptr<AnyCameraF>;
76
77/**
78 * Definition of a typename alias for vectors with shared AnyCameraT objects.
79 * @tparam T the data type of the scalar to be used either 'float' or 'double'
80 * @see VectorT2
81 * @ingroup math
82 */
83template <typename T>
84using SharedAnyCamerasT = std::vector<std::shared_ptr<AnyCameraT<T>>>;
85
86/**
87 * Definition of a vector holding AnyCamera objects.
88 * @see AnyCamera
89 * @ingroup math
90 */
92
93/**
94 * Definition of a vector holding AnyCameraD objects.
95 * @see AnyCameraD
96 * @ingroup math
97 */
99
100/**
101 * Definition of a vector holding AnyCameraF objects.
102 * @see AnyCameraF
103 * @ingroup math
104 */
106
107/**
108 * Definition of individual camera types.
109 * @ingroup math
110 */
111enum class AnyCameraType : uint32_t
112{
113 /// An invalid camera type.
114 INVALID = 0u,
115 /// A pinhole camera.
116 PINHOLE,
117 /// A fisheye camera.
118 FISHEYE
119};
120
121/**
122 * This class implements the abstract base class for all AnyCamera objects.
123 * A custom camera object can be implemented by
124 * - simply deriving a new class from this base class
125 * - using the helper class AnyCameraWrappingT which helps reducing the implementation effort
126 * @tparam T The data type of a scalar, 'float' or 'double'
127 * @ingroup math
128 */
129template <typename T>
130class AnyCameraT : public CameraT<T>
131{
132 public:
133
134 /// The scalar data type of this object.
135 using TScalar = T;
136
137 public:
138
139 /**
140 * Destructs the AnyCamera object.
141 */
142 virtual ~AnyCameraT() = default;
143
144 /**
145 * Returns the type of this camera.
146 * @return The camera's type
147 */
148 virtual AnyCameraType anyCameraType() const = 0;
149
150 /**
151 * Returns the name of this camera.
152 * @return The camera's name
153 */
154 virtual std::string name() const = 0;
155
156 /**
157 * Returns a copy of this camera object.
158 * The image resolution of the cloned camera must have the same aspect ratio as the current image resolution.
159 * @param width The width of the cloned camera in pixel, with range [1, infinity), 0 to use the current image resolution
160 * @param height the height of the cloned camera in pixel, with range [1, infinity), 0 to use the current image resolution
161 * @return New instance of this camera object
162 */
163 virtual std::unique_ptr<AnyCameraT<T>> clone(const unsigned int width = 0u, const unsigned int height = 0u) const = 0;
164
165 /**
166 * Returns a copy of this camera object with float precision.
167 * The image resolution of the cloned camera must have the same aspect ratio as the current image resolution.
168 * @param width The width of the cloned camera in pixel, with range [1, infinity), 0 to use the current image resolution
169 * @param height the height of the cloned camera in pixel, with range [1, infinity), 0 to use the current image resolution
170 * @return New instance of this camera object
171 */
172 virtual std::unique_ptr<AnyCameraT<float>> cloneToFloat(const unsigned int width = 0u, const unsigned int height = 0u) const = 0;
173
174 /**
175 * Returns a copy of this camera object with double precision.
176 * The image resolution of the cloned camera must have the same aspect ratio as the current image resolution.
177 * @param width The width of the cloned camera in pixel, with range [1, infinity), 0 to use the current image resolution
178 * @param height the height of the cloned camera in pixel, with range [1, infinity), 0 to use the current image resolution
179 * @return New instance of this camera object
180 */
181 virtual std::unique_ptr<AnyCameraT<double>> cloneToDouble(const unsigned int width = 0u, const unsigned int height = 0u) const = 0;
182
183 /**
184 * Returns the width of the camera image.
185 * @return Width of the camera image, in pixel, with range [0, infinity)
186 */
187 virtual unsigned int width() const = 0;
188
189 /**
190 * Returns the height of the camera image.
191 * @return Height of the camera image, in pixel, with range [0, infinity)
192 */
193 virtual unsigned int height() const = 0;
194
195 /**
196 * Returns the coordinate of the principal point of the camera image in the pixel domain.
197 * @return The 2D location of the principal point, with range (-infinity, infinity)x(-infinity, infinity)
198 */
199 virtual VectorT2<T> principalPoint() const = 0;
200
201 /**
202 * Returns the x-value of the principal point of the camera image in the pixel domain.
203 * @return x-value of the principal point, with range (-infinity, infinity)
204 */
205 virtual T principalPointX() const = 0;
206
207 /**
208 * Returns the y-value of the principal point of the camera image in the pixel domain.
209 * @return y-value of the principal point, with range (-infinity, infinity)
210 */
211 virtual T principalPointY() const = 0;
212
213 /**
214 * Returns the horizontal focal length parameter.
215 * @return Horizontal focal length parameter in pixel domain, with range (0, infinity)
216 */
217 virtual T focalLengthX() const = 0;
218
219 /**
220 * Returns the vertical focal length parameter.
221 * @return Vertical focal length parameter in pixel domain, with range (0, infinity)
222 */
223 virtual T focalLengthY() const = 0;
224
225 /**
226 * Returns the inverse horizontal focal length parameter.
227 * @return Inverse horizontal focal length parameter in pixel domain, with range (0, infinity)
228 */
229 virtual T inverseFocalLengthX() const = 0;
230
231 /**
232 * Returns the inverse vertical focal length parameter.
233 * @return Inverse vertical focal length parameter in pixel domain, with range (0, infinity)
234 */
235 virtual T inverseFocalLengthY() const = 0;
236
237 /**
238 * Returns the field of view in x direction of the camera.
239 * The fov is the sum of the left and right part of the camera.
240 * @return Field of view (in radian), with range (0, 2 * PI]
241 */
242 virtual T fovX() const = 0;
243
244 /**
245 * Returns the field of view in x direction of the camera.
246 * The fov is the sum of the top and bottom part of the camera.
247 * @return Field of view (in radian), with range (0, 2 * PI]
248 */
249 virtual T fovY() const = 0;
250
251 /**
252 * Returns whether a given 2D image point lies inside the camera frame.
253 * Optional an explicit border can be defined to allow points slightly outside the camera image, or further inside the image.<br>
254 * Defined a negative border size to allow image points outside the camera frame, or a positive border size to prevent points within the camera frame but close to the boundary.
255 * @param imagePoint Image point to be checked, must be valid
256 * @param signedBorder The optional border increasing or decreasing the rectangle in which the image point must be located, in pixels, with range (-infinity, std::min(width() / 2, height() / 2)
257 * @return True, if the image point lies in the ranges [0, width())x[0, height())
258 */
259 virtual bool isInside(const VectorT2<T>& imagePoint, const T signedBorder = T(0)) const = 0;
260
261 /**
262 * Projects a 3D object point into the camera frame.
263 * The projection is applied with a default camera pose, the camera is looking into the negative z-space with y-axis up.
264 * @param objectPoint The 3D object point to project, defined in world
265 * @return The projected 2D image point
266 */
267 virtual VectorT2<T> projectToImage(const VectorT3<T>& objectPoint) const = 0;
268
269 /**
270 * Projects a 3D object point into the camera frame.
271 * @param world_T_camera The camera pose, the default camera is looking into the negative z-space with y-axis up, transforming camera to world, must be valid
272 * @param objectPoint The 3D object point to project, defined in world
273 * @return The projected 2D image point
274 */
275 virtual VectorT2<T> projectToImage(const HomogenousMatrixT4<T>& world_T_camera, const VectorT3<T>& objectPoint) const = 0;
276
277 /**
278 * Projects several 3D object points into the camera frame at once.
279 * The projection is applied with a default camera pose, the camera is looking into the negative z-space with y-axis up.
280 * @param objectPoints The 3D object points to project, defined in world, must be valid
281 * @param size The number of object points, with range [1, infinity)
282 * @param imagePoints The resulting 2D image points, must be valid
283 */
284 virtual void projectToImage(const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const = 0;
285
286 /**
287 * Projects several 3D object points into the camera frame at once.
288 * @param world_T_camera The camera pose, the default camera is looking into the negative z-space with y-axis up, transforming camera to world, must be valid
289 * @param objectPoints The 3D object points to project, defined in world, must be valid
290 * @param size The number of object points, with range [1, infinity)
291 * @param imagePoints The resulting 2D image points, must be valid
292 */
293 virtual void projectToImage(const HomogenousMatrixT4<T>& world_T_camera, const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const = 0;
294
295 /**
296 * Projects a 3D object point into the camera frame.
297 * The projection is applied with a default (inverted) and flipped camera pose, the camera is looking into the positive z-space with y-axis down.
298 * @param objectPoint The 3D object point to project, defined in world
299 * @return The projected 2D image point
300 */
301 virtual VectorT2<T> projectToImageIF(const VectorT3<T>& objectPoint) const = 0;
302
303 /**
304 * Projects a 3D object point into the camera frame.
305 * @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
306 * @param objectPoint The 3D object point to project, defined in world
307 * @return The projected 2D image point
308 */
310
311 /**
312 * Projects several 3D object points into the camera frame at once.
313 * The projection is applied with a default (inverted) and flipped camera pose, the camera is looking into the positive z-space with y-axis down.
314 * @param objectPoints The 3D object points to project, defined in world, must be valid
315 * @param size The number of object points, with range [1, infinity)
316 * @param imagePoints The resulting 2D image points, must be valid
317 */
318 virtual void projectToImageIF(const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const = 0;
319
320 /**
321 * Projects several 3D object points into the camera frame at once.
322 * @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
323 * @param objectPoints The 3D object points to project, defined in world, must be valid
324 * @param size The number of object points, with range [1, infinity)
325 * @param imagePoints The resulting 2D image points, must be valid
326 */
327 virtual void projectToImageIF(const HomogenousMatrixT4<T>& flippedCamera_T_world, const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const = 0;
328
329 /**
330 * Returns a vector starting at the camera's center and intersecting a given 2D point in the image.
331 * The vector is determined for a default camera looking into the negative z-space with y-axis up.
332 * @param distortedImagePoint 2D (distorted) position within the image, with range [0, width())x[0, height())
333 * @param makeUnitVector True, to return a vector with length 1; False, to return a vector with any length
334 * @return Vector pointing into the negative z-space
335 * @see vectorIF(), ray().
336 */
337 virtual VectorT3<T> vector(const VectorT2<T>& distortedImagePoint, const bool makeUnitVector = true) const = 0;
338
339 /**
340 * Determines vectors starting at the camera's center and intersecting given 2D points in the image.
341 * The vectors are determined for a default camera looking into the negative z-space with y-axis up.
342 * @param distortedImagePoints 2D (distorted) positions within the image, with range [0, width())x[0, height()), must be valid
343 * @param size The number of provided points, with range [1, infinity)
344 * @param vectors The resulting vectors pointing into the negative z-space, one for each image point, must be valid
345 * @param makeUnitVector True, to return a vector with length 1; False, to return a vector with any length
346 * @see vectorIF(), ray().
347 */
348 virtual void vector(const VectorT2<T>* distortedImagePoints, const size_t size, VectorT3<T>* vectors, const bool makeUnitVector = true) const = 0;
349
350 /**
351 * Returns a vector starting at the camera's center and intersecting a given 2D point in the image.
352 * The vector is determined for a default camera looking into the positive z-space with y-axis down.
353 * @param distortedImagePoint 2D (distorted) position within the image, with range [0, width())x[0, height())
354 * @param makeUnitVector True, to return a vector with length 1; False, to return a vector with any length
355 * @return Vector pointing into the positive z-space
356 */
357 virtual VectorT3<T> vectorIF(const VectorT2<T>& distortedImagePoint, const bool makeUnitVector = true) const = 0;
358
359 /**
360 * Returns vectors starting at the camera's center and intersecting a given 2D points in the image.
361 * The vectors are determined for a default camera looking into the positive z-space with y-axis down.
362 * @param distortedImagePoints 2D (distorted) positions within the image, with range [0, width())x[0, height()), must be valid
363 * @param size The number of provided points, with range [1, infinity)
364 * @param vectors The resulting vectors pointing into the positive z-space, one for each image point, must be valid
365 * @param makeUnitVector True, to return a vector with length 1; False, to return a vector with any length
366 */
367 virtual void vectorIF(const VectorT2<T>* distortedImagePoints, const size_t size, VectorT3<T>* vectors, const bool makeUnitVector = true) const = 0;
368
369 /**
370 * Returns a ray starting at the camera's center and intersecting a given 2D point in the image.
371 * The ray is determined for a default camera looking into the negative z-space with y-axis up.
372 * @param distortedImagePoint 2D (distorted) position within the image, with range [0, width())x[0, height())
373 * @param world_T_camera The pose of the camera, the extrinsic camera matrix, must be valid
374 * @return The specified ray with direction pointing into the camera's negative z-space
375 * @see vector().
376 */
378
379 /**
380 * Returns a ray starting at the camera's center and intersecting a given 2D point in the image.
381 * The ray is determined for a default camera looking into the negative z-space with y-axis up.
382 * @param distortedImagePoint 2D (distorted) position within the image, with range [0, width())x[0, height())
383 * @return The specified ray with direction pointing into the camera's negative z-space
384 * @see vector().
385 */
386 virtual LineT3<T> ray(const VectorT2<T>& distortedImagePoint) const = 0;
387
388 /**
389 * Calculates the 2x3 jacobian matrix for the 3D object point projection into the camera frame.
390 * The resulting jacobian matrix has the following layout:
391 * <pre>
392 * | dfu / dx, dfu / dy, dfu / dz |
393 * | dfv / dx, dfv / dy, dfv / dz |
394 * with projection function
395 * q = f(p)
396 * q_u = fu(p), q_v = fv(p)
397 * with 2D image point q = (q_u, q_v) and 3D object point p = (x, y, z)
398 * </pre>
399 * @param flippedCameraObjectPoint The 3D object point defined in relation to the inverted and flipped camera pose (camera looking into the positive z-space with y-axis pointing down).
400 * @param jx The resulting first row of the Jacobian matrix, must contain three elements, must be valid
401 * @param jy The resulting second row of the Jacobian matrix, must contain three elements, must be valid
402 * @see pointJacobian2nx3IF().
403 */
404 virtual void pointJacobian2x3IF(const VectorT3<T>& flippedCameraObjectPoint, T* jx, T* jy) const = 0;
405
406 /**
407 * Calculates the 2n x 3 jacobian matrix for the 3D object point projection into the camera frame.
408 * The resulting jacobian matrix has the following layout:
409 * <pre>
410 * | dfu / dx, dfu / dy, dfu / dz | <- for object point 0
411 * | dfv / dx, dfv / dy, dfv / dz |
412 * | ... |
413 * | dfu / dx, dfu / dy, dfu / dz | <- for object point n - 1
414 * | dfv / dx, dfv / dy, dfv / dz |
415 * with projection function
416 * q = f(p)
417 * q_u = fu(p), q_v = fv(p)
418 * with 2D image point q = (q_u, q_v) and 3D object point p = (x, y, z)
419 * </pre>
420 * @param flippedCameraObjectPoints The 3D object points defined in relation to the inverted and flipped camera pose (camera looking into the positive z-space with y-axis pointing down).
421 * @param numberObjectPoints The number of given 3D object points, with range [1, infinity)
422 * @param jacobians The resulting 2n x 3 Jacobian matrix, with 2 * numberObjectPoints * 3 elements, must be valid
423 * @see pointJacobian2x3IF().
424 */
425 virtual void pointJacobian2nx3IF(const VectorT3<T>* flippedCameraObjectPoints, const size_t numberObjectPoints, T* jacobians) const = 0;
426
427 /**
428 * Returns whether two camera objects are identical up to a given epsilon.
429 * The image resolution must always be identical.
430 * @param anyCamera The second camera to be used for comparison, can be invalid
431 * @param eps The epsilon threshold to be used, with range [0, infinity)
432 * @return True, if so
433 */
434 virtual bool isEqual(const AnyCameraT<T>& anyCamera, const T eps = NumericT<T>::eps()) const = 0;
435
436 /**
437 * Returns whether this camera is valid.
438 * @return True, if so
439 */
440 virtual bool isValid() const = 0;
441
442 /**
443 * Converts an AnyCamera object with arbitrary scalar type to another AnyCamera object with arbitrary scalar type.
444 * In case both scalar types are identical, the object is simply returned.
445 * In case both scalar types are different, a clone is returned.
446 * @param anyCamera The AnyCamera object to be converted, can be nullptr
447 * @return The resulting AnyCamera object
448 * @tparam U The scalar data type of the given AnyCamera object
449 */
450 template <typename U>
451 static std::shared_ptr<AnyCameraT<T>> convert(const std::shared_ptr<AnyCameraT<U>>& anyCamera);
452
453 protected:
454
455 /**
456 * Protected default constructor.
457 */
458 AnyCameraT() = default;
459
460 /**
461 * Protected copy constructor.
462 * @param anyCamera The object to copy
463 */
465
466 /**
467 * Disabled move constructor.
468 */
470
471 /**
472 * Disabled assign operator.
473 * @return Reference to this object
474 */
475 AnyCameraT& operator=(const AnyCameraT&) = delete;
476
477 /**
478 * Disabled move operator.
479 * @return Reference to this object
480 */
482};
483
484// Forward declaration.
485template <typename T>
487
488/**
489 * Definition of an AnyCamera clipper object with Scalar precision.
490 * @see AnyCameraClipperT
491 * @ingroup math
492 */
494
495/**
496 * Definition of an AnyCamera clipper object with double precision.
497 * @see AnyCameraClipperT
498 * @ingroup math
499 */
501
502/**
503 * Definition of an AnyCamera clipper object with float precision.
504 * @see AnyCameraClipperT
505 * @ingroup math
506 */
508
509/**
510 * This class implements a helper class allowing to check whether a 3D object point projects into the camera image (i.e., clipping against the camera's field of view).
511 * The clipper uses normalized coordinates when verifying the projection behavior to avoid numerical issues when object points project far outside the image area.<br>
512 * In contrast to AnyCamera::projectToImageIF() + AnyCamera::isInside(), the clipper is more precise but also more expensive.
513 * @tparam T The data type of a scalar, 'float' or 'double'
514 * @ingroup math
515 */
516template <typename T>
518{
519 public:
520
521 /**
522 * Default constructor creating an invalid object.
523 */
524 AnyCameraClipperT() = default;
525
526 /**
527 * Creates a new clipper object for a specified camera model.
528 * @param camera The camera model defining the projection, must be valid
529 * @param segmentSteps The number of segments to be used to determine the camera boundary, with range [2, infinity)
530 */
531 explicit AnyCameraClipperT(const SharedAnyCameraT<T>& camera, const size_t segmentSteps = 10);
532
533 /**
534 * Returns whether a 3D object point is located in front of the camera and projects into the camera image.
535 * @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
536 * @param objectPoint The 3D object point to be checked, defined in world
537 * @param imagePoint Optional resulting 2D projected image point inside the camera image, nullptr if not of interest
538 * @return True, if the object point projects into the camera image; False, if the object point is behind the camera or projects outside the camera image
539 */
540 bool projectToImageIF(const HomogenousMatrixT4<T>& flippedCamera_T_world, const VectorT3<T>& objectPoint, VectorT2<T>* imagePoint = nullptr) const;
541
542 /**
543 * Returns the camera model of this clipper.
544 * @return The clipper's camera model, nullptr if no camera model has been set
545 */
546 const SharedAnyCameraT<T>& camera() const;
547
548 /**
549 * Returns the width of the camera profile.
550 * @return The camera image width in pixel, with range [0, infinity), 0 if no camera has been set
551 */
552 inline unsigned int width() const;
553
554 /**
555 * Returns the height of the camera profile.
556 * @return The camera image height in pixel, with range [0, infinity), 0 if no camera has been set
557 */
558 inline unsigned int height() const;
559
560 /**
561 * Updates the clipper with a new camera model.
562 * If the new camera is equal to the current camera, the function will return immediately without any updates.
563 * @param camera The camera model defining the projection, must be valid
564 * @param segmentSteps The number of segments to be used to determine the camera boundary, with range [1, infinity)
565 */
566 void update(const SharedAnyCameraT<T>& camera, const size_t segmentSteps = 10);
567
568 /**
569 * Returns the 2D line segments defined in the camera's normalized image plane defining the camera's boundary.
570 * @return The camera boundary segments
571 */
573
574 /**
575 * Returns whether this clipper holds a valid camera model and is ready to be used.
576 * @return True, if so
577 */
578 bool isValid() const;
579
580 protected:
581
582 /**
583 * Determines the camera boundary of a given camera model in normalized image coordinates.
584 * @param camera The camera model for which the boundary will be determined, must be valid
585 * @param cameraBoundarySegments The resulting 2D line segments defining the camera's boundary
586 * @param segmentSteps The number of segments to be used to determine the camera boundary, with range [1, infinity)
587 * @return True, if succeeded
588 */
589 static bool determineCameraBoundary(const AnyCameraT<T>& camera, FiniteLinesT2<T>& cameraBoundarySegments, const size_t segmentSteps);
590
591 /**
592 * Returns whether a given normalized image point lies inside the camera's boundary.
593 * @param cameraBoundarySegments The 2D line segments defining the camera's boundary, at least three
594 * @param normalizedImagePoint The normalized image point to be checked
595 * @return True, if if so
596 */
597 static bool isInside(const FiniteLinesT2<T>& cameraBoundarySegments, const VectorT2<T>& normalizedImagePoint);
598
599 /**
600 * Returns whether a given camera model is valid for a specified 2D image point in the camera image.
601 * The function does not only check whether the provided image point re-projects back to the same image point but also whether additional image points sampled towards the principal point have the same behavior.
602 * @param camera The camera model to be checked, must be valid
603 * @param imagePoint The 2D image point to be checked, defined in the camera image, with range [0, width()]x[0, height()]
604 * @param maximalReprojectionError The maximal allowed re-projection error in pixel, with range [0, infinity)
605 * @param additionalChecksTowardsPrincipalPoint The number of additional image points sampled towards the principal point to be checked, with range [1, infinity)
606 * @return True, if the camera model is valid for the specified image point
607 */
608 static bool isValidForPoint(const AnyCameraT<T>& camera, const VectorT2<T>& imagePoint, const T maximalReprojectionError = T(1), const unsigned int additionalChecksTowardsPrincipalPoint = 3u);
609
610 protected:
611
612 /// The actual camera model this clipper is based on.
614
615 /// The 2D line segments defined in the camera's normalized image plane defining the camera's boundary, defined in the flipped camera coordinate system with y-axis down.
617};
618
619/**
620 * This class implements a specialized AnyCamera object wrapping the actual camera model.
621 * The class is a helper class to simplify the implementation of specialized AnyCamera objects.
622 * @tparam T The data type of a scalar, 'float' or 'double'
623 * @tparam TCameraWrapper The data type of the class actually wrapping the camera object
624 * @ingroup math
625 */
626template <typename T, typename TCameraWrapper>
628 public AnyCameraT<T>,
629 public TCameraWrapper
630{
631 public:
632
633 /// The scalar data type of this object.
634 using TScalar = T;
635
636 /// The class which is actually wrapping the camera object.
638
639 /// The actual camera object wrapped by this class.
640 using ActualCamera = typename TCameraWrapper::ActualCamera;
641
642 public:
643
644 /**
645 * Creates a new AnyCamera object wrapping the actual camera model.
646 * @param actualCamera The actual camera object to be wrapped
647 */
648 explicit AnyCameraWrappingT(ActualCamera&& actualCamera);
649
650 /**
651 * Creates a new AnyCamera object wrapping the actual camera model.
652 * @param actualCamera The actual camera object to be wrapped
653 */
654 explicit AnyCameraWrappingT(const ActualCamera& actualCamera);
655
656 /**
657 * Returns the type of this camera.
658 * @return The camera's type
659 */
660 AnyCameraType anyCameraType() const override;
661
662 /**
663 * Returns the name of this camera.
664 * @return The camera's name
665 */
666 std::string name() const override;
667
668 /**
669 * Returns a copy of this camera object.
670 * The image resolution of the cloned camera must have the same aspect ratio as the current image resolution.
671 * @param width The width of the cloned camera in pixel, with range [1, infinity), 0 to use the current image resolution
672 * @param height the height of the cloned camera in pixel, with range [1, infinity), 0 to use the current image resolution
673 * @return New instance of this camera object
674 */
675 std::unique_ptr<AnyCameraT<T>> clone(const unsigned int width = 0u, const unsigned int height = 0u) const override;
676
677 /**
678 * Returns a copy of this camera object with float precision.
679 * The image resolution of the cloned camera must have the same aspect ratio as the current image resolution.
680 * @param width The width of the cloned camera in pixel, with range [1, infinity), 0 to use the current image resolution
681 * @param height the height of the cloned camera in pixel, with range [1, infinity), 0 to use the current image resolution
682 * @return New instance of this camera object
683 */
684 std::unique_ptr<AnyCameraT<float>> cloneToFloat(const unsigned int width = 0u, const unsigned int height = 0u) const override;
685
686 /**
687 * Returns a copy of this camera object with double precision.
688 * The image resolution of the cloned camera must have the same aspect ratio as the current image resolution.
689 * @param width The width of the cloned camera in pixel, with range [1, infinity), 0 to use the current image resolution
690 * @param height the height of the cloned camera in pixel, with range [1, infinity), 0 to use the current image resolution
691 * @return New instance of this camera object
692 */
693 std::unique_ptr<AnyCameraT<double>> cloneToDouble(const unsigned int width = 0u, const unsigned int height = 0u) const override;
694
695 /**
696 * Returns the width of the camera image.
697 * @return Width of the camera image, in pixel, with range [0, infinity)
698 */
699 unsigned int width() const override;
700
701 /**
702 * Returns the height of the camera image.
703 * @return Height of the camera image, in pixel, with range [0, infinity)
704 */
705 unsigned int height() const override;
706
707 /**
708 * Returns the coordinate of the principal point of the camera image in the pixel domain.
709 * @return The 2D location of the principal point, with range (-infinity, infinity)x(-infinity, infinity)
710 */
711 VectorT2<T> principalPoint() const override;
712
713 /**
714 * Returns the x-value of the principal point of the camera image in the pixel domain.
715 * @return x-value of the principal point, with range (-infinity, infinity)
716 */
717 T principalPointX() const override;
718
719 /**
720 * Returns the y-value of the principal point of the camera image in the pixel domain.
721 * @return y-value of the principal point, with range (-infinity, infinity)
722 */
723 T principalPointY() const override;
724
725 /**
726 * Returns the horizontal focal length parameter.
727 * @return Horizontal focal length parameter in pixel domain, with range (0, infinity)
728 */
729 T focalLengthX() const override;
730
731 /**
732 * Returns the vertical focal length parameter.
733 * @return Vertical focal length parameter in pixel domain, with range (0, infinity)
734 */
735 T focalLengthY() const override;
736
737 /**
738 * Returns the inverse horizontal focal length parameter.
739 * @return Inverse horizontal focal length parameter in pixel domain, with range (0, infinity)
740 */
741 T inverseFocalLengthX() const override;
742
743 /**
744 * Returns the inverse vertical focal length parameter.
745 * @return Inverse vertical focal length parameter in pixel domain, with range (0, infinity)
746 */
747 T inverseFocalLengthY() const override;
748
749 /**
750 * Returns the field of view in x direction of the camera.
751 * The fov is the sum of the left and right part of the camera.
752 * @return Field of view (in radian), with range (0, 2 * PI]
753 */
754 T fovX() const override;
755
756 /**
757 * Returns the field of view in x direction of the camera.
758 * The fov is the sum of the top and bottom part of the camera.
759 * @return Field of view (in radian), with range (0, 2 * PI]
760 */
761 T fovY() const override;
762
763 /**
764 * Returns whether a given 2D image point lies inside the camera frame.
765 * Optional an explicit border can be defined to allow points slightly outside the camera image, or further inside the image.<br>
766 * Defined a negative border size to allow image points outside the camera frame, or a positive border size to prevent points within the camera frame but close to the boundary.
767 * @param imagePoint Image point to be checked, must be valid
768 * @param signedBorder The optional border increasing or decreasing the rectangle in which the image point must be located, in pixels, with range (-infinity, std::min(width() / 2, height() / 2)
769 * @return True, if the image point lies in the ranges [0, width())x[0, height())
770 */
771 bool isInside(const VectorT2<T>& imagePoint, const T signedBorder = T(0)) const override;
772
773 /**
774 * Projects a 3D object point into the camera frame.
775 * The projection is applied with a default camera pose, the camera is looking into the negative z-space with y-axis up.
776 * @param objectPoint The 3D object point to project, defined in world
777 * @return The projected 2D image point
778 */
779 VectorT2<T> projectToImage(const VectorT3<T>& objectPoint) const override;
780
781 /**
782 * Projects a 3D object point into the camera frame.
783 * @param world_T_camera The camera pose, the default camera is looking into the negative z-space with y-axis up, transforming camera to world, must be valid
784 * @param objectPoint The 3D object point to project, defined in world
785 * @return The projected 2D image point
786 */
787 VectorT2<T> projectToImage(const HomogenousMatrixT4<T>& world_T_camera, const VectorT3<T>& objectPoint) const override;
788
789 /**
790 * Projects several 3D object points into the camera frame at once.
791 * The projection is applied with a default camera pose, the camera is looking into the negative z-space with y-axis up.
792 * @param objectPoints The 3D object points to project, defined in world, must be valid
793 * @param size The number of object points, with range [1, infinity)
794 * @param imagePoints The resulting 2D image points, must be valid
795 */
796 void projectToImage(const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const override;
797
798 /**
799 * Projects several 3D object points into the camera frame at once.
800 * @param world_T_camera The camera pose, the default camera is looking into the negative z-space with y-axis up, transforming camera to world, must be valid
801 * @param objectPoints The 3D object points to project, defined in world, must be valid
802 * @param size The number of object points, with range [1, infinity)
803 * @param imagePoints The resulting 2D image points, must be valid
804 */
805 void projectToImage(const HomogenousMatrixT4<T>& world_T_camera, const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const override;
806
807 /**
808 * Projects a 3D object point into the camera frame.
809 * The projection is applied with a default (inverted) and flipped camera pose, the camera is looking into the positive z-space with y-axis down.
810 * @param objectPoint The 3D object point to project, defined in world
811 * @return The projected 2D image point
812 */
813 VectorT2<T> projectToImageIF(const VectorT3<T>& objectPoint) const override;
814
815 /**
816 * Projects a 3D object point into the camera frame.
817 * @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
818 * @param objectPoint The 3D object point to project, defined in world
819 * @return The projected 2D image point
820 */
822
823 /**
824 * Projects several 3D object points into the camera frame at once.
825 * The projection is applied with a default (inverted) and flipped camera pose, the camera is looking into the positive z-space with y-axis down.
826 * @param objectPoints The 3D object points to project, defined in world, must be valid
827 * @param size The number of object points, with range [1, infinity)
828 * @param imagePoints The resulting 2D image points, must be valid
829 */
830 void projectToImageIF(const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const override;
831
832 /**
833 * Projects several 3D object points into the camera frame at once.
834 * @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
835 * @param objectPoints The 3D object points to project, defined in world, must be valid
836 * @param size The number of object points, with range [1, infinity)
837 * @param imagePoints The resulting 2D image points, must be valid
838 */
839 void projectToImageIF(const HomogenousMatrixT4<T>& flippedCamera_T_world, const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const override;
840
841 /**
842 * Returns a vector starting at the camera's center and intersecting a given 2D point in the image.
843 * The vector is determined for the default camera looking into the negative z-space with y-axis up.
844 * @param distortedImagePoint 2D (distorted) position within the image, with range [0, width())x[0, height())
845 * @param makeUnitVector True, to return a vector with length 1; False, to return a vector with any length
846 * @return Vector pointing into the negative z-space
847 * @see vectorIF(), ray().
848 */
849 VectorT3<T> vector(const VectorT2<T>& distortedImagePoint, const bool makeUnitVector = true) const override;
850
851 /**
852 * Determines vectors starting at the camera's center and intersecting given 2D points in the image.
853 * The vectors are determined for a default camera looking into the negative z-space with y-axis up.
854 * @param distortedImagePoints 2D (distorted) positions within the image, with range [0, width())x[0, height()), must be valid
855 * @param size The number of provided points, with range [1, infinity)
856 * @param vectors The resulting vectors pointing into the negative z-space, one for each image point, must be valid
857 * @param makeUnitVector True, to return a vector with length 1; False, to return a vector with any length
858 * @see vectorIF(), ray().
859 */
860 void vector(const VectorT2<T>* distortedImagePoints, const size_t size, VectorT3<T>* vectors, const bool makeUnitVector = true) const override;
861
862 /**
863 * Returns a vector starting at the camera's center and intersecting a given 2D point in the image.
864 * The vector is determined for the default camera looking into the positive z-space with y-axis down.
865 * @param distortedImagePoint 2D (distorted) position within the image, with range [0, width())x[0, height())
866 * @param makeUnitVector True, to return a vector with length 1; False, to return a vector with any length
867 * @return Vector pointing into the positive z-space
868 */
869 VectorT3<T> vectorIF(const VectorT2<T>& distortedImagePoint, const bool makeUnitVector = true) const override;
870
871 /**
872 * Returns vectors starting at the camera's center and intersecting a given 2D points in the image.
873 * The vectors are determined for a default camera looking into the positive z-space with y-axis down.
874 * @param distortedImagePoints 2D (distorted) positions within the image, with range [0, width())x[0, height()), must be valid
875 * @param size The number of provided points, with range [1, infinity)
876 * @param vectors The resulting vectors pointing into the positive z-space, one for each image point, must be valid
877 * @param makeUnitVector True, to return a vector with length 1; False, to return a vector with any length
878 */
879 void vectorIF(const VectorT2<T>* distortedImagePoints, const size_t size, VectorT3<T>* vectors, const bool makeUnitVector = true) const override;
880
881 /**
882 * Returns a ray starting at the camera's center and intersecting a given 2D point in the image.
883 * @param distortedImagePoint 2D (distorted) position within the image, with range [0, width())x[0, height())
884 * @param world_T_camera The pose of the camera, the extrinsic camera matrix, must be valid
885 * @return The specified ray with direction pointing into the camera's negative z-space
886 * @see vector().
887 */
889
890 /**
891 * Returns a ray starting at the camera's center and intersecting a given 2D point in the image.
892 * @param distortedImagePoint 2D (distorted) position within the image, with range [0, width())x[0, height())
893 * @return The specified ray with direction pointing into the camera's negative z-space
894 * @see vector().
895 */
896 LineT3<T> ray(const VectorT2<T>& distortedImagePoint) const override;
897
898 /**
899 * Calculates the 2x3 jacobian matrix for the 3D object point projection into the camera frame.
900 * The resulting jacobian matrix has the following layout:
901 * <pre>
902 * | dfu / dx, dfu / dy, dfu / dz |
903 * | dfv / dx, dfv / dy, dfv / dz |
904 * with projection function
905 * q = f(p)
906 * q_u = fu(p), q_v = fv(p)
907 * with 2D image point q = (q_u, q_v) and 3D object point p = (x, y, z)
908 * </pre>
909 * @param flippedCameraObjectPoint The 3D object point defined in relation to the inverted and flipped camera pose (camera looking into the positive z-space with y-axis pointing down).
910 * @param jx The resulting first row of the Jacobian matrix, must contain three elements, must be valid
911 * @param jy The resulting second row of the Jacobian matrix, must contain three elements, must be valid
912 */
913 void pointJacobian2x3IF(const VectorT3<T>& flippedCameraObjectPoint, T* jx, T* jy) const override;
914
915 /**
916 * Calculates the 2n x 3 jacobian matrix for the 3D object point projection into the camera frame.
917 * The resulting jacobian matrix has the following layout:
918 * <pre>
919 * | dfu / dx, dfu / dy, dfu / dz | <- for object point 0
920 * | dfv / dx, dfv / dy, dfv / dz |
921 * | ... |
922 * | dfu / dx, dfu / dy, dfu / dz | <- for object point n - 1
923 * | dfv / dx, dfv / dy, dfv / dz |
924 * with projection function
925 * q = f(p)
926 * q_u = fu(p), q_v = fv(p)
927 * with 2D image point q = (q_u, q_v) and 3D object point p = (x, y, z)
928 * </pre>
929 * @param flippedCameraObjectPoints The 3D object points defined in relation to the inverted and flipped camera pose (camera looking into the positive z-space with y-axis pointing down).
930 * @param numberObjectPoints The number of given 3D object points, with range [1, infinity)
931 * @param jacobians The resulting 2n x 3 Jacobian matrix, with 2 * numberObjectPoints * 3 elements, must be valid
932 */
933 void pointJacobian2nx3IF(const VectorT3<T>* flippedCameraObjectPoints, const size_t numberObjectPoints, T* jacobians) const override;
934
935 /**
936 * Returns whether two camera objects are identical up to a given epsilon.
937 * The image resolution must always be identical.
938 * @param anyCamera The second camera to be used for comparison, can be invalid
939 * @param eps The epsilon threshold to be used, with range [0, infinity)
940 * @return True, if so
941 */
942 bool isEqual(const AnyCameraT<T>& anyCamera, const T eps = NumericT<T>::eps()) const override;
943
944 /**
945 * Returns whether this camera is valid.
946 * @return True, if so
947 */
948 bool isValid() const override;
949};
950
951/**
952 * This class implements a wrapper for an actual camera object.
953 * - TCameraWrapperBase implements the wrapper functions necessary for the individual camera models.
954 * - CameraWrapperT implements some additional functions necessary to fully implement all necessary functions for AnyCameraT.
955 * @tparam T The data type of a scalar, 'float' or 'double'
956 * @tparam TCameraWrapperBase The base class implementing all functions necessary for the wrapped camera object.
957 * @ingroup math
958 */
959template <typename T, typename TCameraWrapperBase>
961{
962 public:
963
964 /**
965 * Definition of the actual camera object which is wrapped in this class.
966 */
967 using typename TCameraWrapperBase::ActualCamera;
968
969 public:
970
971 /**
972 * Creates a new CameraWrapperT object wrapping the actual camera model.
973 * @param actualCamera The actual camera object to be wrapped
974 */
975 explicit CameraWrapperT(ActualCamera&& actualCamera);
976
977 /**
978 * Creates a new CameraWrapperT object wrapping the actual camera model.
979 * @param actualCamera The actual camera object to be wrapped
980 */
981 explicit CameraWrapperT(const ActualCamera& actualCamera);
982
983 /**
984 * Returns the coordinate of the principal point of the camera image in the pixel domain.
985 * @see AnyCameraT::principalPoint().
986 */
987 inline VectorT2<T> principalPoint() const;
988
989 /**
990 * Returns the field of view in x direction of the camera.
991 * @see AnyCameraT::fovX().
992 */
993 inline T fovX() const;
994
995 /**
996 * Returns the field of view in x direction of the camera.
997 * @see AnyCameraT::fovY().
998 */
999 inline T fovY() const;
1000
1001 /**
1002 * Returns whether a given 2D image point lies inside the camera frame.
1003 * @see AnyCameraT::isInside().
1004 */
1005 inline bool isInside(const VectorT2<T>& imagePoint, const T signedBorder = T(0)) const;
1006
1007 /**
1008 * Projects a 3D object point into the camera frame.
1009 * @see projectToImage().
1010 */
1011 inline VectorT2<T> projectToImage(const VectorT3<T>& objectPoint) const;
1012
1013 /**
1014 * Projects a 3D object point into the camera frame.
1015 * @see projectToImage().
1016 */
1017 inline VectorT2<T> projectToImage(const HomogenousMatrixT4<T>& world_T_camera, const VectorT3<T>& objectPoint) const;
1018
1019 /**
1020 * Projects several 3D object points into the camera frame at once.
1021 * @see projectToImage().
1022 */
1023 inline void projectToImage(const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const;
1024
1025 /**
1026 * Projects several 3D object points into the camera frame at once.
1027 * @see projectToImage().
1028 */
1029 inline void projectToImage(const HomogenousMatrixT4<T>& world_T_camera, const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const;
1030
1031 /**
1032 * Returns a vector starting at the camera's center and intersecting a given 2D point in the image.
1033 * @see AnyCameraT::vector().
1034 */
1035 inline VectorT3<T> vector(const VectorT2<T>& distortedImagePoint, const bool makeUnitVector) const;
1036
1037 /**
1038 * Determines vectors starting at the camera's center and intersecting given 2D points in the image.
1039 * @see AnyCameraT::vector().
1040 */
1041 inline void vector(const VectorT2<T>* distortedImagePoints, const size_t size, VectorT3<T>* vectors, const bool makeUnitVector) const;
1042
1043 /**
1044 * Returns a ray starting at the camera's center and intersecting a given 2D point in the image.
1045 * @see ray().
1046 */
1048
1049 /**
1050 * Returns a ray starting at the camera's center and intersecting a given 2D point in the image.
1051 * @see ray().
1052 */
1053 inline LineT3<T> ray(const VectorT2<T>& distortedImagePoint) const;
1054
1055 /**
1056 * Calculates the 2x3 jacobian matrix for the 3D object point projection into the camera frame.
1057 * @see AnyCameraT::pointJacobian2nx3IF().
1058 */
1059 inline void pointJacobian2nx3IF(const VectorT3<T>* flippedCameraObjectPoints, const size_t numberObjectPoints, T* jacobians) const;
1060};
1061
1062/**
1063 * This class implements the base wrapper around Ocean's pinhole camera profile.
1064 * The class can be used as 'TCameraWrapperBase' in 'CameraWrapperT' to create a full wrapper class e.g., 'CameraWrapperT<T, CameraWrapperBasePinholeT<T>>'.
1065 * @tparam T The data type of a scalar, 'float' or 'double'
1066 * @ingroup math
1067 */
1068template <typename T>
1070{
1071 public:
1072
1073 /**
1074 * Definition of the actual camera object wrapped by this class.
1075 */
1077
1078 /**
1079 * Definition of the parent WrappedCamera class using this base class.
1080 */
1082
1083 public:
1084
1085 /**
1086 * Creates a new CameraWrapperBasePinholeT object wrapping the actual camera model.
1087 * @param actualCamera The actual camera object to be wrapped
1088 */
1090
1091 /**
1092 * Creates a new CameraWrapperBasePinholeT object wrapping the actual camera model.
1093 * @param actualCamera The actual camera object to be wrapped
1094 */
1096
1097 /**
1098 * Returns the actual camera object wrapped in this class.
1099 * @return The wrapped camera object
1100 */
1101 inline const ActualCamera& actualCamera() const;
1102
1103 /**
1104 * Returns the width of the camera image.
1105 * @see AnyCameraT::width().
1106 */
1107 inline unsigned int width() const;
1108
1109 /**
1110 * Returns the height of the camera image.
1111 * @see AnyCameraT::height().
1112 */
1113 inline unsigned int height() const;
1114
1115 /**
1116 * Returns the x-value of the principal point of the camera image in the pixel domain.
1117 * @see AnyCameraT::principalPointX().
1118 */
1119 inline T principalPointX() const;
1120
1121 /**
1122 * Returns the y-value of the principal point of the camera image in the pixel domain.
1123 * @see AnyCameraT::principalPointY().
1124 */
1125 inline T principalPointY() const;
1126
1127 /**
1128 * Returns the horizontal focal length parameter.
1129 * @see AnyCameraT::focalLengthX().
1130 */
1131 inline T focalLengthX() const;
1132
1133 /**
1134 * Returns the vertical focal length parameter.
1135 * @see AnyCameraT::focalLengthY().
1136 */
1137 inline T focalLengthY() const;
1138
1139 /**
1140 * Returns the inverse horizontal focal length parameter.
1141 * @see AnyCameraT::inverseFocalLengthX().
1142 */
1143 inline T inverseFocalLengthX() const;
1144
1145 /**
1146 * Returns the inverse vertical focal length parameter.
1147 * @see AnyCameraT::inverseFocalLengthY().
1148 */
1149 inline T inverseFocalLengthY() const;
1150
1151 /**
1152 * Projects a 3D object point into the camera frame.
1153 * @see AnyCameraT::projectToImageIF().
1154 */
1155 inline VectorT2<T> projectToImageIF(const VectorT3<T>& objectPoint) const;
1156
1157 /**
1158 * Projects a 3D object point into the camera frame.
1159 * @see AnyCameraT::projectToImageIF().
1160 */
1161 inline VectorT2<T> projectToImageIF(const HomogenousMatrixT4<T>& flippedCamera_T_world, const VectorT3<T>& objectPoint) const;
1162
1163 /**
1164 * Projects several 3D object points into the camera frame at once.
1165 * @see AnyCameraT::projectToImageIF().
1166 */
1167 inline void projectToImageIF(const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const;
1168
1169 /**
1170 * Projects several 3D object points into the camera frame at once.
1171 * @see AnyCameraT::projectToImageIF().
1172 */
1173 inline void projectToImageIF(const HomogenousMatrixT4<T>& flippedCamera_T_world, const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const;
1174
1175 /**
1176 * Returns a vector starting at the camera's center and intersecting a given 2D point in the image.
1177 * @see AnyCameraT::vectorIF().
1178 */
1179 inline VectorT3<T> vectorIF(const VectorT2<T>& distortedImagePoint, const bool makeUnitVector) const;
1180
1181 /**
1182 * Returns vectors starting at the camera's center and intersecting a given 2D points in the image.
1183 * @see AnyCameraT::vectorIF().
1184 */
1185 inline void vectorIF(const VectorT2<T>* distortedImagePoint, const size_t size, VectorT3<T>* vectors, const bool makeUnitVector) const;
1186
1187 /**
1188 * Calculates the 2x3 jacobian matrix for the 3D object point projection into the camera frame.
1189 * @see AnyCameraT::pointJacobian2x3IF().
1190 */
1191 inline void pointJacobian2x3IF(const VectorT3<T>& flippedCameraObjectPoint, T* jx, T* jy) const;
1192
1193 /**
1194 * Returns whether two camera objects are identical up to a given epsilon.
1195 * @see AnyCameraT::isEqual().
1196 */
1197 inline bool isEqual(const CameraWrapperBasePinholeT<T>& basePinhole, const T eps = NumericT<T>::eps()) const;
1198
1199 /**
1200 * Returns whether this camera is valid.
1201 * @see AnyCameraT::isValid().
1202 */
1203 inline bool isValid() const;
1204
1205 /**
1206 * Returns a copy of the actual camera object.
1207 * @return New instance of the actual camera object used in this wrapper.
1208 * @tparam U The scalar data type of the resulting cloned object, either 'float' or 'double'
1209 */
1210 template <typename U>
1211 inline std::unique_ptr<AnyCameraT<U>> clone(const unsigned int width = 0u, const unsigned int height = 0u) const;
1212
1213 /**
1214 * Returns the type of this camera.
1215 * @see AnyCameraT::anyCameraType().
1216 */
1217 static inline AnyCameraType anyCameraType();
1218
1219 /**
1220 * Returns the name of this camera.
1221 * @see AnyCameraT::name().
1222 */
1223 static inline std::string name();
1224
1225 protected:
1226
1227 /// The actual pinhole camera.
1229};
1230
1231/**
1232 * This class implements the base wrapper around Ocean's fisheye camera profile.
1233 * The class can be used as 'TCameraWrapperBase' in 'CameraWrapperT' to create a full wrapper class e.g., 'CameraWrapperT<T, CameraWrapperBaseFisheyeT<T>>'.
1234 * @tparam T The data type of a scalar, 'float' or 'double'
1235 * @ingroup math
1236 */
1237template <typename T>
1239{
1240 public:
1241
1242 /**
1243 * Definition of the actual camera object wrapped by this class.
1244 */
1246
1247 /**
1248 * Definition of the parent WrappedCamera class using this base class.
1249 */
1251
1252 public:
1253
1254 /**
1255 * Creates a new CameraWrapperBaseFisheyeT object wrapping the actual camera model.
1256 * @param actualCamera The actual camera object to be wrapped
1257 */
1259
1260 /**
1261 * Creates a new CameraWrapperBaseFisheyeT object wrapping the actual camera model.
1262 * @param actualCamera The actual camera object to be wrapped
1263 */
1265
1266 /**
1267 * Returns the actual camera object wrapped in this class.
1268 * @return The wrapped camera object
1269 */
1270 inline const ActualCamera& actualCamera() const;
1271
1272 /**
1273 * Returns the width of the camera image.
1274 * @see AnyCameraT::width().
1275 */
1276 inline unsigned int width() const;
1277
1278 /**
1279 * Returns the height of the camera image.
1280 * @see AnyCameraT::height().
1281 */
1282 inline unsigned int height() const;
1283
1284 /**
1285 * Returns the coordinate of the principal point of the camera image in the pixel domain.
1286 * @see AnyCameraT::principalPoint().
1287 */
1288 inline VectorT2<T> principalPoint() const;
1289
1290 /**
1291 * Returns the x-value of the principal point of the camera image in the pixel domain.
1292 * @see AnyCameraT::principalPointX().
1293 */
1294 inline T principalPointX() const;
1295
1296 /**
1297 * Returns the y-value of the principal point of the camera image in the pixel domain.
1298 * @see AnyCameraT::principalPointY().
1299 */
1300 inline T principalPointY() const;
1301
1302 /**
1303 * Returns the horizontal focal length parameter.
1304 * @see AnyCameraT::focalLengthX().
1305 */
1306 inline T focalLengthX() const;
1307
1308 /**
1309 * Returns the vertical focal length parameter.
1310 * @see AnyCameraT::focalLengthY().
1311 */
1312 inline T focalLengthY() const;
1313
1314 /**
1315 * Returns the inverse horizontal focal length parameter.
1316 * @see AnyCameraT::inverseFocalLengthX().
1317 */
1318 inline T inverseFocalLengthX() const;
1319
1320 /**
1321 * Returns the inverse vertical focal length parameter.
1322 * @see AnyCameraT::inverseFocalLengthY().
1323 */
1324 inline T inverseFocalLengthY() const;
1325
1326 /**
1327 * Projects a 3D object point into the camera frame.
1328 * @see AnyCameraT::projectToImageIF().
1329 */
1330 inline VectorT2<T> projectToImageIF(const VectorT3<T>& objectPoint) const;
1331
1332 /**
1333 * Projects a 3D object point into the camera frame.
1334 * @see AnyCameraT::projectToImageIF().
1335 */
1336 inline VectorT2<T> projectToImageIF(const HomogenousMatrixT4<T>& flippedCamera_T_world, const VectorT3<T>& objectPoint) const;
1337
1338 /**
1339 * Projects several 3D object points into the camera frame at once.
1340 * @see AnyCameraT::projectToImageIF().
1341 */
1342 inline void projectToImageIF(const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const;
1343
1344 /**
1345 * Projects several 3D object points into the camera frame at once.
1346 * @see AnyCameraT::projectToImageIF().
1347 */
1348 inline void projectToImageIF(const HomogenousMatrixT4<T>& flippedCamera_T_world, const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const;
1349
1350 /**
1351 * Returns a vector starting at the camera's center and intersecting a given 2D point in the image.
1352 * @see AnyCameraT::vectorIF().
1353 */
1354 inline VectorT3<T> vectorIF(const VectorT2<T>& distortedImagePoint, const bool makeUnitVector) const;
1355
1356 /**
1357 * Returns vectors starting at the camera's center and intersecting a given 2D points in the image.
1358 * @see AnyCameraT::vectorIF().
1359 */
1360 inline void vectorIF(const VectorT2<T>* distortedImagePoint, const size_t size, VectorT3<T>* vectors, const bool makeUnitVector) const;
1361
1362 /**
1363 * Calculates the 2x3 jacobian matrix for the 3D object point projection into the camera frame.
1364 * @see AnyCameraT::pointJacobian2x3IF().
1365 */
1366 inline void pointJacobian2x3IF(const VectorT3<T>& flippedCameraObjectPoint, T* jx, T* jy) const;
1367
1368 /**
1369 * Returns whether two camera objects are identical up to a given epsilon.
1370 * @see AnyCameraT::isEqual().
1371 */
1372 inline bool isEqual(const CameraWrapperBaseFisheyeT<T>& baseFisheye, const T eps = NumericT<T>::eps()) const;
1373
1374 /**
1375 * Returns whether this camera is valid.
1376 * @return True, if so
1377 */
1378 inline bool isValid() const;
1379
1380 /**
1381 * Returns a copy of the actual camera object.
1382 * @return New instance of the actual camera object used in this wrapper.
1383 */
1384 template <typename U>
1385 inline std::unique_ptr<AnyCameraT<U>> clone(const unsigned int width = 0u, const unsigned int height = 0u) const;
1386
1387 /**
1388 * Returns the type of this camera.
1389 * @see AnyCamera::anyCameraType().
1390 */
1391 static inline AnyCameraType anyCameraType();
1392
1393 /**
1394 * Returns the name of this camera.
1395 * @see AnyCamera::name().
1396 */
1397 static inline std::string name();
1398
1399 protected:
1400
1401 /// The actual fisheye camera object.
1403};
1404
1405/**
1406 * This class implements invalid camera profiles, e.g. when no intrinsic information is available.
1407 * @tparam T The data type of a 'Scalar', 'float' or 'double'
1408 * @ingroup math
1409 */
1410template <typename T>
1412{
1413 public:
1414
1415 /**
1416 * Creates an invalid camera
1417 * @param reason The reason why no valid camera is available, must be valid
1418 */
1419 explicit InvalidCameraT(const std::string& reason);
1420
1421 /**
1422 * Returns the reason of this invalid camera
1423 * @return The reason
1424 */
1425 const std::string& reason() const;
1426
1427 protected:
1428
1429 /// The reason why no valid camera is available.
1430 std::string reason_;
1431};
1432
1433/**
1434 * Definition of an invalid camera object based with element precision 'Scalar'.
1435 * @see AnyCameraT, AnyCameraInvalidT.
1436 * @ingroup math
1437 */
1439
1440/**
1441 * Definition of an invalid camera object based with element precision 'double'.
1442 * @see AnyCameraT, AnyCameraInvalidT.
1443 * @ingroup math
1444 */
1446
1447/**
1448 * Definition of an invalid camera object based with element precision 'float'.
1449 * @see AnyCameraT, AnyCameraInvalidT.
1450 * @ingroup math
1451 */
1453
1454/**
1455 * This class implements the base wrapper around an invalid camera profile.
1456 * The class can be used as 'TCameraWrapperBase' in 'CameraWrapperT' to create a full wrapper class e.g., 'CameraWrapperT<T, CameraWrapperBaseInvalidT<T>>'.
1457 * @tparam T The data type of a scalar, 'float' or 'double'
1458 * @ingroup math
1459 */
1460template <typename T>
1462{
1463 public:
1464
1465 /**
1466 * Definition of the actual camera object wrapped by this class.
1467 */
1469
1470 /**
1471 * Definition of the parent WrappedCamera class using this base class.
1472 */
1474
1475 public:
1476
1477 /**
1478 * Creates a new CameraWrapperBaseInvalidT object wrapping the actual camera model.
1479 * @param actualCamera The actual camera object to be wrapped
1480 */
1482
1483 /**
1484 * Creates a new CameraWrapperBaseInvalidT object wrapping the actual camera model.
1485 * @param actualCamera The actual camera object to be wrapped
1486 */
1488
1489 /**
1490 * Returns the actual camera object wrapped in this class.
1491 * @return The wrapped camera object
1492 */
1493 inline const ActualCamera& actualCamera() const;
1494
1495 /**
1496 * Returns the width of the camera image.
1497 * @see AnyCameraT::width().
1498 */
1499 inline unsigned int width() const;
1500
1501 /**
1502 * Returns the height of the camera image.
1503 * @see AnyCameraT::height().
1504 */
1505 inline unsigned int height() const;
1506
1507 /**
1508 * Returns the coordinate of the principal point of the camera image in the pixel domain.
1509 * @see AnyCameraT::principalPoint().
1510 */
1511 inline VectorT2<T> principalPoint() const;
1512
1513 /**
1514 * Returns the x-value of the principal point of the camera image in the pixel domain.
1515 * @see AnyCameraT::principalPointX().
1516 */
1517 inline T principalPointX() const;
1518
1519 /**
1520 * Returns the y-value of the principal point of the camera image in the pixel domain.
1521 * @see AnyCameraT::principalPointY().
1522 */
1523 inline T principalPointY() const;
1524
1525 /**
1526 * Returns the horizontal focal length parameter.
1527 * @see AnyCameraT::focalLengthX().
1528 */
1529 inline T focalLengthX() const;
1530
1531 /**
1532 * Returns the vertical focal length parameter.
1533 * @see AnyCameraT::focalLengthY().
1534 */
1535 inline T focalLengthY() const;
1536
1537 /**
1538 * Returns the inverse horizontal focal length parameter.
1539 * @see AnyCameraT::inverseFocalLengthX().
1540 */
1541 inline T inverseFocalLengthX() const;
1542
1543 /**
1544 * Returns the inverse vertical focal length parameter.
1545 * @see AnyCameraT::inverseFocalLengthY().
1546 */
1547 inline T inverseFocalLengthY() const;
1548
1549 /**
1550 * Projects a 3D object point into the camera frame.
1551 * @see AnyCameraT::projectToImageIF().
1552 */
1553 inline VectorT2<T> projectToImageIF(const VectorT3<T>& objectPoint) const;
1554
1555 /**
1556 * Projects a 3D object point into the camera frame.
1557 * @see AnyCameraT::projectToImageIF().
1558 */
1559 inline VectorT2<T> projectToImageIF(const HomogenousMatrixT4<T>& flippedCamera_T_world, const VectorT3<T>& objectPoint) const;
1560
1561 /**
1562 * Projects several 3D object points into the camera frame at once.
1563 * @see AnyCameraT::projectToImageIF().
1564 */
1565 inline void projectToImageIF(const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const;
1566
1567 /**
1568 * Projects several 3D object points into the camera frame at once.
1569 * @see AnyCameraT::projectToImageIF().
1570 */
1571 inline void projectToImageIF(const HomogenousMatrixT4<T>& flippedCamera_T_world, const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const;
1572
1573 /**
1574 * Returns a vector starting at the camera's center and intersecting a given 2D point in the image.
1575 * @see AnyCameraT::vectorIF().
1576 */
1577 inline VectorT3<T> vectorIF(const VectorT2<T>& distortedImagePoint, const bool makeUnitVector) const;
1578
1579 /**
1580 * Returns vectors starting at the camera's center and intersecting a given 2D points in the image.
1581 * @see AnyCameraT::vectorIF().
1582 */
1583 inline void vectorIF(const VectorT2<T>* distortedImagePoint, const size_t size, VectorT3<T>* vectors, const bool makeUnitVector) const;
1584
1585 /**
1586 * Calculates the 2x3 jacobian matrix for the 3D object point projection into the camera frame.
1587 * @see AnyCameraT::pointJacobian2x3IF().
1588 */
1589 inline void pointJacobian2x3IF(const VectorT3<T>& flippedCameraObjectPoint, T* jx, T* jy) const;
1590
1591 /**
1592 * Returns whether two camera objects are identical up to a given epsilon.
1593 * @see AnyCameraT::isEqual().
1594 */
1595 inline bool isEqual(const CameraWrapperBaseInvalidT<T>& baseInvalid, const T eps = NumericT<T>::eps()) const;
1596
1597 /**
1598 * Returns whether this camera is valid.
1599 * @return True, if so
1600 */
1601 inline bool isValid() const;
1602
1603 /**
1604 * Returns a copy of the actual camera object.
1605 * @return New instance of the actual camera object used in this wrapper.
1606 */
1607 template <typename U>
1608 inline std::unique_ptr<AnyCameraT<U>> clone(const unsigned int width = 0u, const unsigned int height = 0u) const;
1609
1610 /**
1611 * Returns the type of this camera.
1612 * @see AnyCamera::anyCameraType().
1613 */
1614 static inline AnyCameraType anyCameraType();
1615
1616 /**
1617 * Returns the name of this camera.
1618 * @see AnyCamera::name().
1619 */
1620 static inline std::string name();
1621
1622 protected:
1623
1624 /// The actual invalid camera.
1626};
1627
1628/**
1629 * Definition of an AnyCamera object based on Ocean's pinhole camera class with template parameter to define the element precision.
1630 * @tparam T The scalar data type
1631 * @see AnyCameraT, CameraWrapperBasePinholeT, AnyCameraPinhole, AnyCameraPinholeD, AnyCameraPinholeF.
1632 * @ingroup math
1633 */
1634template <typename T>
1636
1637/**
1638 * Definition of an AnyCamera object based on Ocean's pinhole camera class with element precision 'Scalar'.
1639 * @see AnyCameraT, AnyCameraPinholeT.
1640 * @ingroup math
1641 */
1643
1644/**
1645 * Definition of an AnyCamera object based on Ocean's pinhole camera class with element precision 'double'.
1646 * @see AnyCameraT, AnyCameraPinholeT.
1647 * @ingroup math
1648 */
1650
1651/**
1652 * Definition of an AnyCamera object based on Ocean's pinhole camera class with element precision 'float'.
1653 * @see AnyCameraT, AnyCameraPinholeT.
1654 * @ingroup math
1655 */
1657
1658/**
1659 * Definition of an AnyCamera object based on Ocean's fisheye camera class with template parameter to define the element precision.
1660 * @tparam T The scalar data type
1661 * @see AnyCameraT, CameraWrapperBaseFisheyeT, AnyCameraFisheye, AnyCameraFisheyeD, AnyCameraFisheyeF.
1662 * @ingroup math
1663 */
1664template <typename T>
1666
1667/**
1668 * Definition of an AnyCamera object based on Ocean's fisheye camera class with element precision 'Scalar'.
1669 * @see AnyCameraT, AnyCameraFisheyeT.
1670 * @ingroup math
1671 */
1673
1674/**
1675 * Definition of an AnyCamera object based on Ocean's fisheye camera class with element precision 'double'.
1676 * @see AnyCameraT, AnyCameraFisheyeT.
1677 * @ingroup math
1678 */
1680
1681/**
1682 * Definition of an AnyCamera object based on Ocean's fisheye camera class with element precision 'float'.
1683 * @see AnyCameraT, AnyCameraFisheyeT.
1684 * @ingroup math
1685 */
1687
1688/**
1689 * Definition of an AnyCamera object based on an invalid (by design) camera with template parameter to define the element precision.
1690 * @tparam T The scalar data type
1691 * @see AnyCameraT, CameraWrapperBaseFisheyeT, AnyCameraInvalid, AnyCameraInvalidD, AnyCameraInvalidF.
1692 * @ingroup math
1693 */
1694template <typename T>
1696
1697/**
1698 * Definition of an AnyCamera object based on an invalid (by design) camera with element precision 'Scalar'.
1699 * @see AnyCameraT, AnyCameraInvalidT.
1700 * @ingroup math
1701 */
1703
1704/**
1705 * Definition of an AnyCamera object based on an invalid (by design) camera with element precision 'double'.
1706 * @see AnyCameraT, AnyCameraInvalidT.
1707 * @ingroup math
1708 */
1710
1711/**
1712 * Definition of an AnyCamera object based on an invalid (by design) camera with element precision 'float'.
1713 * @see AnyCameraT, AnyCameraInvalidT.
1714 * @ingroup math
1715 */
1717
1718template <typename T>
1719AnyCameraClipperT<T>::AnyCameraClipperT(const SharedAnyCameraT<T>& camera, const size_t segmentSteps)
1720{
1721 update(camera, segmentSteps);
1722}
1723
1724template <typename T>
1725bool AnyCameraClipperT<T>::projectToImageIF(const HomogenousMatrixT4<T>& flippedCamera_T_world, const VectorT3<T>& objectPoint, VectorT2<T>* imagePoint) const
1726{
1727 ocean_assert(camera_ != nullptr);
1728 ocean_assert(camera_->isValid());
1729 ocean_assert(flippedCamera_T_world.isValid());
1730
1731 const VectorT3<T> cameraObjectPointIF = flippedCamera_T_world * objectPoint;
1732
1733 if (cameraObjectPointIF.z() <= NumericT<T>::eps())
1734 {
1735 return false;
1736 }
1737
1738 const T invZ = T(1) / cameraObjectPointIF.z();
1739
1740 const VectorT2<T> normalizedImagePoint(cameraObjectPointIF.x() * invZ, cameraObjectPointIF.y() * invZ);
1741
1742 if (!isInside(cameraBoundarySegments_, normalizedImagePoint))
1743 {
1744 return false;
1745 }
1746
1747 if (imagePoint != nullptr)
1748 {
1749 *imagePoint = camera_->projectToImageIF(cameraObjectPointIF);
1750
1751 ocean_assert_accuracy(camera_->isInside(*imagePoint, T(std::max(camera_->width(), camera_->height())) * T(-0.1)));
1752 }
1753
1754 return true;
1755}
1756
1757template <typename T>
1759{
1760 return camera_;
1761}
1762
1763template <typename T>
1764inline unsigned int AnyCameraClipperT<T>::width() const
1765{
1766 if (camera_)
1767 {
1768 return camera_->width();
1769 }
1770
1771 return 0u;
1772}
1773
1774template <typename T>
1775inline unsigned int AnyCameraClipperT<T>::height() const
1776{
1777 if (camera_)
1778 {
1779 return camera_->height();
1780 }
1781
1782 return 0u;
1783}
1784
1785template <typename T>
1786void AnyCameraClipperT<T>::update(const SharedAnyCameraT<T>& camera, const size_t segmentSteps)
1787{
1788 ocean_assert(camera != nullptr && camera->isValid() && segmentSteps >= 1);
1789 if (camera == nullptr || !camera->isValid() || segmentSteps == 0)
1790 {
1791 return;
1792 }
1793
1794 if (camera_ && camera_->isEqual(*camera))
1795 {
1796 ocean_assert(isValid());
1797 return;
1798 }
1799
1800 cameraBoundarySegments_.clear();
1801
1802 if (determineCameraBoundary(*camera, cameraBoundarySegments_, segmentSteps))
1803 {
1804 camera_ = camera;
1805 }
1806 else
1807 {
1808 camera_ = nullptr;
1809 cameraBoundarySegments_.clear();
1810 }
1811
1812 ocean_assert(isValid());
1813}
1814
1815template <typename T>
1817{
1818 return cameraBoundarySegments_;
1819}
1820
1821template <typename T>
1823{
1824 ocean_assert(camera_ == nullptr || !cameraBoundarySegments_.empty());
1825
1826 return camera_ != nullptr;
1827}
1828
1829template <typename T>
1830bool AnyCameraClipperT<T>::determineCameraBoundary(const AnyCameraT<T>& camera, FiniteLinesT2<T>& cameraBoundarySegments, const size_t segmentSteps)
1831{
1832 ocean_assert(camera.isValid());
1833 if (!camera.isValid())
1834 {
1835 return false;
1836 }
1837
1838 ocean_assert(segmentSteps >= 1);
1839 if (segmentSteps < 1)
1840 {
1841 return false;
1842 }
1843
1844 constexpr unsigned int border = 0u;
1845
1846 const std::array<VectorT2<T>, 4> corners =
1847 {
1848 VectorT2<T>(T(border), T(border)),
1849 VectorT2<T>(T(border), T(camera.height() - border - 1u)),
1850 VectorT2<T>(T(camera.width() - border - 1u), T(camera.height() - border - 1u)),
1851 VectorT2<T>(T(camera.width() - border - 1u), T(border))
1852 };
1853
1854 const VectorT2<T> principalPoint = camera.principalPoint();
1855
1856 constexpr T maximalSqrDistance = NumericT<T>::sqr(T(1));
1857
1858 // let's first check whether the camera model is precise enough at the principal point
1859
1860 const VectorT3<T> principalObjectPoint = camera.vectorIF(principalPoint, false /*makeUnitVector*/);
1861
1862 const T sqrProjectionErrorPrincipalPoint = camera.projectToImageIF(principalObjectPoint).sqrDistance(principalPoint);
1863
1864 if (sqrProjectionErrorPrincipalPoint > maximalSqrDistance)
1865 {
1866 ocean_assert(false && "The camera model is not precise enough");
1867 return false;
1868 }
1869
1870 VectorsT2<T> normalizedImagePoints;
1871 normalizedImagePoints.reserve(corners.size() * segmentSteps);
1872
1873 for (size_t nCorner = 0; nCorner < corners.size(); ++nCorner)
1874 {
1875 const VectorT2<T>& corner0 = corners[nCorner];
1876 const VectorT2<T>& corner1 = corners[(nCorner + 1u) % corners.size()];
1877
1878 for (size_t nStep = 0; nStep < segmentSteps; ++nStep)
1879 {
1880 const T factor = T(nStep) / T(segmentSteps);
1881
1882 const VectorT2<T> distortedImagePoint = corner0 * (T(1) - factor) + corner1 * factor;
1883
1884 const VectorT2<T> offsetTowardsPrincipalPoint = (principalPoint - distortedImagePoint).normalizedOrZero() * T(1.0); // one pixel towards the principal point
1885
1886 VectorT3<T> objectPoint = VectorT3<T>::minValue();
1887
1888 if (isValidForPoint(camera, distortedImagePoint, maximalSqrDistance, 3u))
1889 {
1890 objectPoint = camera.vectorIF(distortedImagePoint, false /*makeUnitVector*/);
1891 }
1892 else
1893 {
1894 // un-projecting and re-projecting the distorted image point did not result in a similar image point, so the camera model is not well defined in this area
1895 // so let's try to find the point closest to the image boundary which is precise enough
1896
1897 // | image boundary ideal point principal point |
1898
1899 VectorT2<T> boundaryImagePoint = distortedImagePoint;
1900 VectorT2<T> centerImagePoint = principalPoint;
1901
1902 objectPoint = principalObjectPoint;
1903
1904 constexpr unsigned int iterations = 20u;
1905
1906 for (unsigned int nIteration = 0u; nIteration < iterations; ++nIteration)
1907 {
1908 if (boundaryImagePoint.sqrDistance(centerImagePoint) <= maximalSqrDistance)
1909 {
1910 break;
1911 }
1912
1913 const VectorT2<T> middleImagePoint = (boundaryImagePoint + centerImagePoint) * T(0.5);
1914
1915 const VectorT3<T> middleObjectPoint = camera.vectorIF(middleImagePoint, false /*makeUnitVector*/);
1916 const VectorT2<T> projectedMiddleObjectPoint = camera.projectToImageIF(middleObjectPoint);
1917
1918 const T sqrMiddleDistance = middleImagePoint.sqrDistance(projectedMiddleObjectPoint);
1919
1920 if (sqrMiddleDistance <= maximalSqrDistance)
1921 {
1922 centerImagePoint = middleImagePoint;
1923
1924 objectPoint = camera.vectorIF(middleImagePoint + offsetTowardsPrincipalPoint, false /*makeUnitVector*/);
1925 }
1926 else
1927 {
1928 boundaryImagePoint = middleImagePoint;
1929 }
1930 }
1931 }
1932
1933 if (objectPoint != VectorT3<T>::minValue())
1934 {
1935 ocean_assert(objectPoint.z() >= NumericT<T>::eps());
1936 const VectorT2<T> normalizedImagePoint = objectPoint.xy() / objectPoint.z();
1937
1938 normalizedImagePoints.emplace_back(normalizedImagePoint.x(), normalizedImagePoint.y());
1939 }
1940 }
1941 }
1942
1943 ocean_assert(normalizedImagePoints.size() >= 3);
1944
1945 ocean_assert(cameraBoundarySegments.empty());
1946 cameraBoundarySegments.clear();
1947
1948 cameraBoundarySegments.reserve(normalizedImagePoints.size());
1949
1950 for (size_t n = 1; n < normalizedImagePoints.size(); ++n)
1951 {
1952 cameraBoundarySegments.emplace_back(normalizedImagePoints[n - 1], normalizedImagePoints[n]);
1953 }
1954
1955 cameraBoundarySegments.emplace_back(normalizedImagePoints.back(), normalizedImagePoints.front());
1956
1957 return true;
1958}
1959
1960template <typename T>
1961bool AnyCameraClipperT<T>::isInside(const FiniteLinesT2<T>& cameraBoundarySegments, const VectorT2<T>& normalizedImagePoint)
1962{
1963 ocean_assert(cameraBoundarySegments.size() >= 3);
1964
1965 size_t counter = 0;
1966
1967 for (const FiniteLineT2<T>& cameraBoundarySegment : cameraBoundarySegments)
1968 {
1969 // let's check whether the point is above or below the line segment
1970
1971 const bool segmentTopDown = cameraBoundarySegment.point0().y() < cameraBoundarySegment.point1().y();
1972
1973 if (segmentTopDown)
1974 {
1975 if (cameraBoundarySegment.point1().y() < normalizedImagePoint.y() || normalizedImagePoint.y() < cameraBoundarySegment.point0().y())
1976 {
1977 continue;
1978 }
1979 }
1980 else
1981 {
1982 if (cameraBoundarySegment.point0().y() < normalizedImagePoint.y() || normalizedImagePoint.y() < cameraBoundarySegment.point1().y())
1983 {
1984 continue;
1985 }
1986 }
1987
1988 if (cameraBoundarySegment.isOnLine(normalizedImagePoint))
1989 {
1990 // the point is on the line segment, so we know the point is inside the camera boundary
1991
1992 return true;
1993 }
1994
1995 if (cameraBoundarySegment.isLeftOfLine(normalizedImagePoint) == segmentTopDown)
1996 {
1997 // the point is on the left side of the line segment, we only count points on the right side
1998 continue;
1999 }
2000
2001 ++counter;
2002 }
2003
2004 return counter % 2 == 1;
2005}
2006
2007template <typename T>
2008bool AnyCameraClipperT<T>::isValidForPoint(const AnyCameraT<T>& camera, const VectorT2<T>& imagePoint, const T maximalReprojectionError, const unsigned int additionalChecksTowardsPrincipalPoint)
2009{
2010 ocean_assert(camera.isValid());
2011 ocean_assert(camera.isInside(imagePoint, T(-1)));
2012 ocean_assert(maximalReprojectionError >= T(0));
2013 ocean_assert(additionalChecksTowardsPrincipalPoint >= 1u);
2014
2015 const VectorT3<T> objectPoint = camera.vectorIF(imagePoint, false /*makeUnitVector*/);
2016 const VectorT2<T> projectedObjectPoint = camera.projectToImageIF(objectPoint);
2017
2018 if (imagePoint.sqrDistance(projectedObjectPoint) > NumericT<T>::sqr(maximalReprojectionError))
2019 {
2020 // simple case, the point does not re-project back to the same image point
2021 return false;
2022 }
2023
2024 const VectorT2<T> principalPoint = camera.principalPoint();
2025
2026 const VectorT2<T> direction = (principalPoint - imagePoint).normalizedOrZero();
2027
2028 if (direction.isNull())
2029 {
2030 // we check the principal point
2031 return true;
2032 }
2033
2034 for (unsigned int n = 0u; n < std::min(additionalChecksTowardsPrincipalPoint, 10u); ++n)
2035 {
2036 const VectorT2<T> additionalImagePoint = imagePoint + direction * T(n + 1u);
2037
2038 const VectorT3<T> additionalObjectPoint = camera.vectorIF(additionalImagePoint, false /*makeUnitVector*/);
2039 const VectorT2<T> additionalProjectedObjectPoint = camera.projectToImageIF(additionalObjectPoint);
2040
2041 if (additionalImagePoint.sqrDistance(additionalProjectedObjectPoint) > NumericT<T>::sqr(maximalReprojectionError))
2042 {
2043 return false;
2044 }
2045 }
2046
2047 return true;
2048}
2049
2050template <>
2051template <>
2052inline std::shared_ptr<AnyCameraT<float>> AnyCameraT<float>::convert(const std::shared_ptr<AnyCameraT<double>>& anyCamera)
2053{
2054 if (anyCamera)
2055 {
2056 return anyCamera->cloneToFloat();
2057 }
2058
2059 return nullptr;
2060}
2061
2062template <>
2063template <>
2064inline std::shared_ptr<AnyCameraT<double>> AnyCameraT<double>::convert(const std::shared_ptr<AnyCameraT<float>>& anyCamera)
2065{
2066 if (anyCamera)
2067 {
2068 return anyCamera->cloneToDouble();
2069 }
2070
2071 return nullptr;
2072}
2073
2074template <typename T>
2075template <typename U>
2076std::shared_ptr<AnyCameraT<T>> AnyCameraT<T>::convert(const std::shared_ptr<AnyCameraT<U>>& anyCamera)
2077{
2078 static_assert(std::is_same<T, U>::value, "Invalid data types!");
2079
2080 return anyCamera;
2081}
2082
2083template <typename T, typename TCameraWrapper>
2085 TCameraWrapper(std::move(actualCamera))
2086{
2087 // nothing to do here
2088}
2089
2090template <typename T, typename TCameraWrapper>
2092 TCameraWrapper(actualCamera)
2093{
2094 // nothing to do here
2095}
2096
2097template <typename T, typename TCameraWrapper>
2099{
2100 return TCameraWrapper::anyCameraType();
2101}
2102
2103template <typename T, typename TCameraWrapper>
2105{
2106 return TCameraWrapper::name();
2107}
2108
2109template <typename T, typename TCameraWrapper>
2110std::unique_ptr<AnyCameraT<T>> AnyCameraWrappingT<T, TCameraWrapper>::clone(const unsigned int width, const unsigned int height) const
2111{
2112 return TCameraWrapper::template clone<T>(width, height);
2113}
2114
2115template <typename T, typename TCameraWrapper>
2116std::unique_ptr<AnyCameraT<float>> AnyCameraWrappingT<T, TCameraWrapper>::cloneToFloat(const unsigned int width, const unsigned int height) const
2117{
2118 return TCameraWrapper::template clone<float>(width, height);
2119}
2120
2121template <typename T, typename TCameraWrapper>
2122std::unique_ptr<AnyCameraT<double>> AnyCameraWrappingT<T, TCameraWrapper>::cloneToDouble(const unsigned int width, const unsigned int height) const
2123{
2124 return TCameraWrapper::template clone<double>(width, height);
2125}
2126
2127template <typename T, typename TCameraWrapper>
2129{
2130 return TCameraWrapper::width();
2131}
2132
2133template <typename T, typename TCameraWrapper>
2135{
2136 return TCameraWrapper::height();
2137}
2138
2139template <typename T, typename TCameraWrapper>
2141{
2142 return TCameraWrapper::principalPoint();
2143}
2144
2145template <typename T, typename TCameraWrapper>
2147{
2148 return TCameraWrapper::principalPointX();
2149}
2150
2151template <typename T, typename TCameraWrapper>
2153{
2154 return TCameraWrapper::principalPointY();
2155}
2156
2157template <typename T, typename TCameraWrapper>
2159{
2160 return TCameraWrapper::focalLengthX();
2161}
2162
2163template <typename T, typename TCameraWrapper>
2165{
2166 return TCameraWrapper::focalLengthY();
2167}
2168
2169template <typename T, typename TCameraWrapper>
2171{
2172 return TCameraWrapper::inverseFocalLengthX();
2173}
2174
2175template <typename T, typename TCameraWrapper>
2177{
2178 return TCameraWrapper::inverseFocalLengthY();
2179}
2180
2181template <typename T, typename TCameraWrapper>
2183{
2184 return TCameraWrapper::fovX();
2185}
2186
2187template <typename T, typename TCameraWrapper>
2189{
2190 return TCameraWrapper::fovY();
2191}
2192
2193template <typename T, typename TCameraWrapper>
2194bool AnyCameraWrappingT<T, TCameraWrapper>::isInside(const VectorT2<T>& imagePoint, const T signedBorder) const
2195{
2196 return TCameraWrapper::isInside(imagePoint, signedBorder);
2197}
2198
2199template <typename T, typename TCameraWrapper>
2201{
2202 return TCameraWrapper::projectToImage(objectPoint);
2203}
2204
2205template <typename T, typename TCameraWrapper>
2207{
2208 return TCameraWrapper::projectToImage(world_T_camera, objectPoint);
2209}
2210
2211template <typename T, typename TCameraWrapper>
2213{
2214 return TCameraWrapper::projectToImageIF(objectPoint);
2215}
2216
2217template <typename T, typename TCameraWrapper>
2219{
2220 return TCameraWrapper::projectToImageIF(flippedCamera_T_world, objectPoint);
2221}
2222
2223template <typename T, typename TCameraWrapper>
2224void AnyCameraWrappingT<T, TCameraWrapper>::projectToImage(const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const
2225{
2226 return TCameraWrapper::projectToImage(objectPoints, size, imagePoints);
2227}
2228
2229template <typename T, typename TCameraWrapper>
2230void AnyCameraWrappingT<T, TCameraWrapper>::projectToImage(const HomogenousMatrixT4<T>& world_T_camera, const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const
2231{
2232 return TCameraWrapper::projectToImage(world_T_camera, objectPoints, size, imagePoints);
2233}
2234
2235template <typename T, typename TCameraWrapper>
2236void AnyCameraWrappingT<T, TCameraWrapper>::projectToImageIF(const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const
2237{
2238 return TCameraWrapper::projectToImageIF(objectPoints, size, imagePoints);
2239}
2240
2241template <typename T, typename TCameraWrapper>
2242void AnyCameraWrappingT<T, TCameraWrapper>::projectToImageIF(const HomogenousMatrixT4<T>& flippedCamera_T_world, const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const
2243{
2244 return TCameraWrapper::projectToImageIF(flippedCamera_T_world, objectPoints, size, imagePoints);
2245}
2246
2247template <typename T, typename TCameraWrapper>
2248VectorT3<T> AnyCameraWrappingT<T, TCameraWrapper>::vector(const VectorT2<T>& distortedImagePoint, const bool makeUnitVector) const
2249{
2250 return TCameraWrapper::vector(distortedImagePoint, makeUnitVector);
2251}
2252
2253template <typename T, typename TCameraWrapper>
2254void AnyCameraWrappingT<T, TCameraWrapper>::vector(const VectorT2<T>* distortedImagePoints, const size_t size, VectorT3<T>* vectors, const bool makeUnitVector) const
2255{
2256 return TCameraWrapper::vector(distortedImagePoints, size, vectors, makeUnitVector);
2257}
2258
2259template <typename T, typename TCameraWrapper>
2260VectorT3<T> AnyCameraWrappingT<T, TCameraWrapper>::vectorIF(const VectorT2<T>& distortedImagePoint, const bool makeUnitVector) const
2261{
2262 return TCameraWrapper::vectorIF(distortedImagePoint, makeUnitVector);
2263}
2264
2265template <typename T, typename TCameraWrapper>
2266void AnyCameraWrappingT<T, TCameraWrapper>::vectorIF(const VectorT2<T>* distortedImagePoints, const size_t size, VectorT3<T>* vectors, const bool makeUnitVector) const
2267{
2268 return TCameraWrapper::vectorIF(distortedImagePoints, size, vectors, makeUnitVector);
2269}
2270
2271template <typename T, typename TCameraWrapper>
2272LineT3<T> AnyCameraWrappingT<T, TCameraWrapper>::ray(const VectorT2<T>& distortedImagePoint, const HomogenousMatrixT4<T>& world_T_camera) const
2273{
2274 return TCameraWrapper::ray(distortedImagePoint, world_T_camera);
2275}
2276
2277template <typename T, typename TCameraWrapper>
2279{
2280 return TCameraWrapper::ray(distortedImagePoint);
2281}
2282
2283template <typename T, typename TCameraWrapper>
2284void AnyCameraWrappingT<T, TCameraWrapper>::pointJacobian2x3IF(const VectorT3<T>& flippedCameraObjectPoint, T* jx, T* jy) const
2285{
2286 return TCameraWrapper::pointJacobian2x3IF(flippedCameraObjectPoint, jx, jy);
2287}
2288
2289template <typename T, typename TCameraWrapper>
2290void AnyCameraWrappingT<T, TCameraWrapper>::pointJacobian2nx3IF(const VectorT3<T>* flippedCameraObjectPoints, const size_t numberObjectPoints, T* jacobians) const
2291{
2292 return TCameraWrapper::pointJacobian2nx3IF(flippedCameraObjectPoints, numberObjectPoints, jacobians);
2293}
2294
2295template <typename T, typename TCameraWrapper>
2296bool AnyCameraWrappingT<T, TCameraWrapper>::isEqual(const AnyCameraT<T>& anyCamera, const T eps) const
2297{
2298 ocean_assert(eps >= T(0));
2299
2300 if (isValid() != anyCamera.isValid())
2301 {
2302 // one camera is value, one is not valid
2303 return false;
2304 }
2305
2306 if (!isValid())
2307 {
2308 // both cameras are invalid
2309 return true;
2310 }
2311
2312 if (name() != anyCamera.name())
2313 {
2314 return false;
2315 }
2316
2317 return TCameraWrapper::isEqual((const AnyCameraWrappingT<T, TCameraWrapper>&)(anyCamera), eps);
2318}
2319
2320template <typename T, typename TCameraWrapper>
2322{
2323 return TCameraWrapper::isValid();
2324}
2325
2326template <typename T, typename TCameraWrapperBase>
2328 TCameraWrapperBase(std::move(actualCamera))
2329{
2330 // nothing to do here
2331}
2332
2333template <typename T, typename TCameraWrapperBase>
2335 TCameraWrapperBase(actualCamera)
2336{
2337 // nothing to do here
2338}
2339
2340template <typename T, typename TCameraWrapperBase>
2342{
2343 return VectorT2<T>(TCameraWrapperBase::principalPointX(), TCameraWrapperBase::principalPointY());
2344}
2345
2346template <typename T, typename TCameraWrapperBase>
2348{
2349 ocean_assert(TCameraWrapperBase::isValid());
2350
2351 /**
2352 * x = Fx * X / Z + mx
2353 *
2354 * (x - mx) / Fx = X / Z
2355 */
2356
2357 if (NumericT<T>::isEqualEps(TCameraWrapperBase::focalLengthX()))
2358 {
2359 return T(0);
2360 }
2361
2362 const T leftAngle = NumericT<T>::abs(NumericT<T>::atan(-TCameraWrapperBase::principalPointX() * TCameraWrapperBase::inverseFocalLengthX()));
2363
2364 if (T(TCameraWrapperBase::width()) <= TCameraWrapperBase::principalPointX())
2365 {
2366 ocean_assert(false && "Invalid principal point");
2367 return T(2) * leftAngle;
2368 }
2369
2370 const T rightAngle = NumericT<T>::atan((T(TCameraWrapperBase::width()) - TCameraWrapperBase::principalPointX()) * TCameraWrapperBase::inverseFocalLengthX());
2371
2372 return leftAngle + rightAngle;
2373}
2374
2375template <typename T, typename TCameraWrapperBase>
2377{
2378 ocean_assert(TCameraWrapperBase::isValid());
2379
2380 /**
2381 * y = Fy * Y / Z + my
2382 *
2383 * (y - my) / Fy = Y / Z
2384 */
2385
2386 if (NumericT<T>::isEqualEps(TCameraWrapperBase::focalLengthY()))
2387 {
2388 return T(0);
2389 }
2390
2391 const T topAngle = NumericT<T>::abs(NumericT<T>::atan(-TCameraWrapperBase::principalPointY() * TCameraWrapperBase::inverseFocalLengthY()));
2392
2393 if (T(TCameraWrapperBase::height()) <= TCameraWrapperBase::principalPointY())
2394 {
2395 ocean_assert(false && "Invalid principal point");
2396 return T(2) * topAngle;
2397 }
2398
2399 const T bottomAngle = NumericT<T>::atan((T(TCameraWrapperBase::height()) - TCameraWrapperBase::principalPointY()) * TCameraWrapperBase::inverseFocalLengthY());
2400
2401 return topAngle + bottomAngle;
2402}
2403
2404template <typename T, typename TCameraWrapperBase>
2405inline bool CameraWrapperT<T, TCameraWrapperBase>::isInside(const VectorT2<T>& imagePoint, const T signedBorder) const
2406{
2407 ocean_assert(TCameraWrapperBase::isValid());
2408
2409 const unsigned int cameraWidth = TCameraWrapperBase::width();
2410 const unsigned int cameraHeight = TCameraWrapperBase::height();
2411
2412 ocean_assert(signedBorder < T(std::min(cameraWidth / 2u, cameraHeight / 2u)));
2413
2414 return imagePoint.x() >= signedBorder && imagePoint.y() >= signedBorder
2415 && imagePoint.x() < T(cameraWidth) - signedBorder && imagePoint.y() < T(cameraHeight) - signedBorder;
2416}
2417
2418template <typename T, typename TCameraWrapperBase>
2420{
2421 return TCameraWrapperBase::projectToImageIF(VectorT3<T>(objectPoint.x(), -objectPoint.y(), -objectPoint.z()));
2422}
2423
2424template <typename T, typename TCameraWrapperBase>
2426{
2427 return TCameraWrapperBase::projectToImageIF(CameraT<T>::standard2InvertedFlipped(world_T_camera), objectPoint);
2428}
2429
2430template <typename T, typename TCameraWrapperBase>
2431inline void CameraWrapperT<T, TCameraWrapperBase>::projectToImage(const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const
2432{
2433 ocean_assert(size == 0 || objectPoints != nullptr);
2434 ocean_assert(size == 0 || imagePoints != nullptr);
2435
2436 for (size_t n = 0; n < size; ++n)
2437 {
2438 const VectorT3<T>& objectPoint = objectPoints[n];
2439 imagePoints[n] = TCameraWrapperBase::projectToImageIF(VectorT3<T>(objectPoint.x(), -objectPoint.y(), -objectPoint.z()));
2440 }
2441}
2442
2443template <typename T, typename TCameraWrapperBase>
2444inline void CameraWrapperT<T, TCameraWrapperBase>::projectToImage(const HomogenousMatrixT4<T>& world_T_camera, const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const
2445{
2446 return TCameraWrapperBase::projectToImageIF(CameraT<T>::standard2InvertedFlipped(world_T_camera), objectPoints, size, imagePoints);
2447}
2448
2449template <typename T, typename TCameraWrapperBase>
2450inline VectorT3<T> CameraWrapperT<T, TCameraWrapperBase>::vector(const VectorT2<T>& distortedImagePoint, const bool makeUnitVector) const
2451{
2452 const VectorT3<T> localVectorIF(TCameraWrapperBase::vectorIF(distortedImagePoint, makeUnitVector));
2453
2454 return VectorT3<T>(localVectorIF.x(), -localVectorIF.y(), -localVectorIF.z());
2455}
2456
2457template <typename T, typename TCameraWrapperBase>
2458inline void CameraWrapperT<T, TCameraWrapperBase>::vector(const VectorT2<T>* distortedImagePoints, const size_t size, VectorT3<T>* vectors, const bool makeUnitVector) const
2459{
2460 TCameraWrapperBase::vectorIF(distortedImagePoints, size, vectors, makeUnitVector);
2461
2462 for (size_t n = 0; n < size; ++n)
2463 {
2464 const VectorT3<T>& localVectorIF = vectors[n];
2465
2466 vectors[n] = VectorT3<T>(localVectorIF.x(), -localVectorIF.y(), -localVectorIF.z());
2467 }
2468}
2469
2470template <typename T, typename TCameraWrapperBase>
2471inline LineT3<T> CameraWrapperT<T, TCameraWrapperBase>::ray(const VectorT2<T>& distortedImagePoint, const HomogenousMatrixT4<T>& world_T_camera) const
2472{
2473 ocean_assert(TCameraWrapperBase::isValid() && world_T_camera.isValid());
2474
2475 return LineT3<T>(world_T_camera.translation(), world_T_camera.rotationMatrix(vector(distortedImagePoint, true /*makeUnitVector*/)));
2476}
2477
2478template <typename T, typename TCameraWrapperBase>
2480{
2481 ocean_assert(TCameraWrapperBase::isValid());
2482
2483 return LineT3<T>(VectorT3<T>(0, 0, 0), vector(distortedImagePoint, true /*makeUnitVector*/));
2484}
2485
2486template <typename T, typename TCameraWrapperBase>
2487inline void CameraWrapperT<T, TCameraWrapperBase>::pointJacobian2nx3IF(const VectorT3<T>* flippedCameraObjectPoints, const size_t numberObjectPoints, T* jacobians) const
2488{
2489 ocean_assert(flippedCameraObjectPoints != nullptr);
2490 ocean_assert(numberObjectPoints >= 1);
2491 ocean_assert(jacobians != nullptr);
2492
2493 for (size_t n = 0; n < numberObjectPoints; ++n)
2494 {
2495 TCameraWrapperBase::pointJacobian2x3IF(flippedCameraObjectPoints[n], jacobians + 0, jacobians + 3);
2496 jacobians += 6;
2497 }
2498}
2499
2500template <typename T>
2502 actualCamera_(std::move(actualCamera))
2503{
2504 // nothing to do here
2505}
2506
2507template <typename T>
2509 actualCamera_(actualCamera)
2510{
2511 // nothing to do here
2512}
2513
2514template <typename T>
2516{
2517 return actualCamera_;
2518}
2519
2520template <typename T>
2521inline unsigned int CameraWrapperBasePinholeT<T>::width() const
2522{
2523 return actualCamera_.width();
2524}
2525
2526template <typename T>
2527inline unsigned int CameraWrapperBasePinholeT<T>::height() const
2528{
2529 return actualCamera_.height();
2530}
2531
2532template <typename T>
2534{
2535 return T(actualCamera_.principalPointX());
2536}
2537
2538template <typename T>
2540{
2541 return T(actualCamera_.principalPointY());
2542}
2543
2544template <typename T>
2546{
2547 return T(actualCamera_.focalLengthX());
2548}
2549
2550template <typename T>
2552{
2553 return T(actualCamera_.focalLengthY());
2554}
2555
2556template <typename T>
2558{
2559 return T(actualCamera_.inverseFocalLengthX());
2560}
2561
2562template <typename T>
2564{
2565 return T(actualCamera_.inverseFocalLengthY());
2566}
2567
2568template <typename T>
2570{
2571 return VectorT2<T>(actualCamera_.template projectToImageIF<true>(HomogenousMatrixT4<T>(true), objectPoint, true));
2572}
2573
2574template <typename T>
2575inline VectorT2<T> CameraWrapperBasePinholeT<T>::projectToImageIF(const HomogenousMatrixT4<T>& flippedCamera_T_world, const VectorT3<T>& objectPoint) const
2576{
2577 return VectorT2<T>(actualCamera_.template projectToImageIF<true>(flippedCamera_T_world, objectPoint, true));
2578}
2579
2580template <typename T>
2581inline void CameraWrapperBasePinholeT<T>::projectToImageIF(const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const
2582{
2583 ocean_assert(size == 0 || objectPoints != nullptr);
2584 ocean_assert(size == 0 || imagePoints != nullptr);
2585
2586 for (size_t n = 0; n < size; ++n)
2587 {
2588 imagePoints[n] = projectToImageIF(objectPoints[n]);
2589 }
2590}
2591
2592template <typename T>
2593inline void CameraWrapperBasePinholeT<T>::projectToImageIF(const HomogenousMatrixT4<T>& flippedCamera_T_world, const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const
2594{
2595 ocean_assert(size == 0 || objectPoints != nullptr);
2596 ocean_assert(size == 0 || imagePoints != nullptr);
2597
2598 for (size_t n = 0; n < size; ++n)
2599 {
2600 imagePoints[n] = projectToImageIF(flippedCamera_T_world, objectPoints[n]);
2601 }
2602}
2603
2604template <typename T>
2605inline VectorT3<T> CameraWrapperBasePinholeT<T>::vectorIF(const VectorT2<T>& distortedImagePoint, const bool makeUnitVector) const
2606{
2607 const VectorT2<T> undistortedImagePoint(actualCamera_.template undistort<true>(distortedImagePoint));
2608
2609 return VectorT3<T>(actualCamera_.vectorIF(undistortedImagePoint, makeUnitVector));
2610}
2611
2612template <typename T>
2613inline void CameraWrapperBasePinholeT<T>::vectorIF(const VectorT2<T>* distortedImagePoints, const size_t size, VectorT3<T>* vectors, const bool makeUnitVector) const
2614{
2615 ocean_assert(distortedImagePoints != nullptr && size > 0);
2616 ocean_assert(vectors != nullptr);
2617
2618 for (size_t n = 0; n < size; ++n)
2619 {
2620 vectors[n] = vectorIF(distortedImagePoints[n], makeUnitVector);
2621 }
2622}
2623
2624template <typename T>
2625inline void CameraWrapperBasePinholeT<T>::pointJacobian2x3IF(const VectorT3<T>& flippedCameraObjectPoint, T* jx, T* jy) const
2626{
2627 ocean_assert(jx != nullptr && jy != nullptr);
2628 actualCamera_.template pointJacobian2x3IF<T, true>(flippedCameraObjectPoint, jx, jy);
2629}
2630
2631template <typename T>
2632inline bool CameraWrapperBasePinholeT<T>::isEqual(const CameraWrapperBasePinholeT<T>& basePinhole, const T eps) const
2633{
2634 ocean_assert(eps >= T(0));
2635
2636 return actualCamera_.isEqual(basePinhole.actualCamera_, eps);
2637}
2638
2639template <typename T>
2641{
2642 return actualCamera_.isValid();
2643}
2644
2645template <typename T>
2646template <typename U>
2647inline std::unique_ptr<AnyCameraT<U>> CameraWrapperBasePinholeT<T>::clone(const unsigned int width, const unsigned int height) const
2648{
2649 ocean_assert(actualCamera_.isValid());
2650
2651 if constexpr (std::is_same<T, U>::value)
2652 {
2653 if ((width == 0u && height == 0u) || (width == actualCamera_.width() && height == actualCamera_.height()))
2654 {
2655 return std::make_unique<AnyCameraWrappingT<U, CameraWrapperT<U, CameraWrapperBasePinholeT<U>>>>(actualCamera_);
2656 }
2657
2658 const unsigned int validWidth = (height * actualCamera_.width() + actualCamera_.height() / 2u) / actualCamera_.height();
2659 const unsigned int validHeight = (width * actualCamera_.height() + actualCamera_.width() / 2u) / actualCamera_.width();
2660
2661 if (!NumericT<unsigned int>::isEqual(width, validWidth, 1u) && !NumericT<unsigned int>::isEqual(height, validHeight, 1u)) // either of the valid width/height needs to be close by 1 pixel
2662 {
2663 ocean_assert(false && "Wrong aspect ratio!");
2664 return nullptr;
2665 }
2666
2667 return std::make_unique<AnyCameraWrappingT<U, CameraWrapperT<U, CameraWrapperBasePinholeT<U>>>>(PinholeCameraT<U>(width, height, actualCamera_));
2668 }
2669 else
2670 {
2671 const PinholeCameraT<U> convertedPinholeCamera(actualCamera_);
2672
2673 if ((width == 0u && height == 0u) || (width == actualCamera_.width() && height == actualCamera_.height()))
2674 {
2675 return std::make_unique<AnyCameraWrappingT<U, CameraWrapperT<U, CameraWrapperBasePinholeT<U>>>>(convertedPinholeCamera);
2676 }
2677
2678 const unsigned int validWidth = (height * actualCamera_.width() + actualCamera_.height() / 2u) / actualCamera_.height();
2679 const unsigned int validHeight = (width * actualCamera_.height() + actualCamera_.width() / 2u) / actualCamera_.width();
2680
2681 if (!NumericT<unsigned int>::isEqual(width, validWidth, 1u) && !NumericT<unsigned int>::isEqual(height, validHeight, 1u)) // either of the valid width/height needs to be close by 1 pixel
2682 {
2683 ocean_assert(false && "Wrong aspect ratio!");
2684 return nullptr;
2685 }
2686
2687 return std::make_unique<AnyCameraWrappingT<U, CameraWrapperT<U, CameraWrapperBasePinholeT<U>>>>(PinholeCameraT<U>(width, height, convertedPinholeCamera));
2688 }
2689}
2690
2691template <typename T>
2696
2697template <typename T>
2699{
2700 return std::string("Ocean Pinhole");
2701}
2702
2703template <typename T>
2705 actualCamera_(std::move(camera))
2706{
2707 // nothing to do here
2708}
2709
2710template <typename T>
2712 actualCamera_(camera)
2713{
2714 // nothing to do here
2715}
2716
2717template <typename T>
2719{
2720 return actualCamera_;
2721}
2722
2723template <typename T>
2724inline unsigned int CameraWrapperBaseFisheyeT<T>::width() const
2725{
2726 return actualCamera_.width();
2727}
2728
2729template <typename T>
2730inline unsigned int CameraWrapperBaseFisheyeT<T>::height() const
2731{
2732 return actualCamera_.height();
2733}
2734
2735template <typename T>
2737{
2738 return actualCamera_.principalPoint();
2739}
2740
2741template <typename T>
2743{
2744 return actualCamera_.principalPointX();
2745}
2746
2747template <typename T>
2749{
2750 return actualCamera_.principalPointY();
2751}
2752
2753template <typename T>
2755{
2756 return actualCamera_.focalLengthX();
2757}
2758
2759template <typename T>
2761{
2762 return actualCamera_.focalLengthY();
2763}
2764
2765template <typename T>
2767{
2768 return actualCamera_.inverseFocalLengthX();
2769}
2770
2771template <typename T>
2773{
2774 return actualCamera_.inverseFocalLengthY();
2775}
2776
2777template <typename T>
2779{
2780 return actualCamera_.projectToImageIF(objectPoint);
2781}
2782
2783template <typename T>
2784inline VectorT2<T> CameraWrapperBaseFisheyeT<T>::projectToImageIF(const HomogenousMatrixT4<T>& flippedCamera_T_world, const VectorT3<T>& objectPoint) const
2785{
2786 return actualCamera_.projectToImageIF(flippedCamera_T_world, objectPoint);
2787}
2788
2789template <typename T>
2790inline void CameraWrapperBaseFisheyeT<T>::projectToImageIF(const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const
2791{
2792 ocean_assert(size == 0 || objectPoints != nullptr);
2793 ocean_assert(size == 0 || imagePoints != nullptr);
2794
2795 for (size_t n = 0; n < size; ++n)
2796 {
2797 imagePoints[n] = projectToImageIF(objectPoints[n]);
2798 }
2799}
2800
2801template <typename T>
2802inline void CameraWrapperBaseFisheyeT<T>::projectToImageIF(const HomogenousMatrixT4<T>& flippedCamera_T_world, const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const
2803{
2804 ocean_assert(size == 0 || objectPoints != nullptr);
2805 ocean_assert(size == 0 || imagePoints != nullptr);
2806
2807 for (size_t n = 0; n < size; ++n)
2808 {
2809 imagePoints[n] = projectToImageIF(flippedCamera_T_world, objectPoints[n]);
2810 }
2811}
2812
2813template <typename T>
2814inline VectorT3<T> CameraWrapperBaseFisheyeT<T>::vectorIF(const VectorT2<T>& distortedImagePoint, const bool makeUnitVector) const
2815{
2816 return actualCamera_.vectorIF(distortedImagePoint, makeUnitVector);
2817}
2818
2819template <typename T>
2820inline void CameraWrapperBaseFisheyeT<T>::vectorIF(const VectorT2<T>* distortedImagePoints, const size_t size, VectorT3<T>* vectors, const bool makeUnitVector) const
2821{
2822 ocean_assert(distortedImagePoints != nullptr && size > 0);
2823 ocean_assert(vectors != nullptr);
2824
2825 for (size_t n = 0; n < size; ++n)
2826 {
2827 vectors[n] = vectorIF(distortedImagePoints[n], makeUnitVector);
2828 }
2829}
2830
2831template <typename T>
2832inline void CameraWrapperBaseFisheyeT<T>::pointJacobian2x3IF(const VectorT3<T>& flippedCameraObjectPoint, T* jx, T* jy) const
2833{
2834 actualCamera_.pointJacobian2x3IF(flippedCameraObjectPoint, jx, jy);
2835}
2836
2837template <typename T>
2838inline bool CameraWrapperBaseFisheyeT<T>::isEqual(const CameraWrapperBaseFisheyeT& baseFisheye, const T eps) const
2839{
2840 ocean_assert(eps >= T(0));
2841
2842 return actualCamera_.isEqual(baseFisheye.actualCamera_, eps);
2843}
2844
2845template <typename T>
2847{
2848 return actualCamera_.isValid();
2849}
2850
2851template <typename T>
2852template <typename U>
2853inline std::unique_ptr<AnyCameraT<U>> CameraWrapperBaseFisheyeT<T>::clone(const unsigned int width, const unsigned int height) const
2854{
2855 ocean_assert(actualCamera_.isValid());
2856
2857 if ((width == 0u && height == 0u) || (width == actualCamera_.width() && height == actualCamera_.height()))
2858 {
2859 return std::make_unique<AnyCameraWrappingT<U, CameraWrapperT<U, CameraWrapperBaseFisheyeT<U>>>>(FisheyeCameraT<U>(actualCamera_));
2860 }
2861
2862 const unsigned int validWidth = (height * actualCamera_.width() + actualCamera_.height() / 2u) / actualCamera_.height();
2863 const unsigned int validHeight = (width * actualCamera_.height() + actualCamera_.width() / 2u) / actualCamera_.width();
2864
2865 if (!NumericT<unsigned int>::isEqual(width, validWidth, 1u) && !NumericT<unsigned int>::isEqual(height, validHeight, 1u))
2866 {
2867 ocean_assert(false && "Wrong aspect ratio!");
2868 return nullptr;
2869 }
2870
2871 const T xFactor = T(width) / T(actualCamera_.width());
2872 const T yFactor = T(height) / T(actualCamera_.height());
2873
2874 const U newPrincipalX = U(actualCamera_.principalPointX() * xFactor);
2875 const U newPrincipalY = U(actualCamera_.principalPointY() * yFactor);
2876
2877 const U newFocalLengthX = U(actualCamera_.focalLengthX() * xFactor);
2878 const U newFocalLengthY = U(actualCamera_.focalLengthY() * yFactor);
2879
2880 U radialDistortion[6];
2881 for (unsigned int n = 0u; n < 6u; ++n)
2882 {
2883 radialDistortion[n] = U(actualCamera_.radialDistortion()[n]);
2884 }
2885
2886 const U tangentialDistortion[2] =
2887 {
2888 U(actualCamera_.tangentialDistortion()[0]),
2889 U(actualCamera_.tangentialDistortion()[1])
2890 };
2891
2892 return std::make_unique<AnyCameraWrappingT<U, CameraWrapperT<U, CameraWrapperBaseFisheyeT<U>>>>(FisheyeCameraT<U>(width, height, newFocalLengthX, newFocalLengthY, newPrincipalX, newPrincipalY, radialDistortion, tangentialDistortion));
2893}
2894
2895template <typename T>
2900
2901template <typename T>
2903{
2904 return std::string("Ocean Fisheye");
2905}
2906
2907template <typename T>
2909 actualCamera_(std::move(camera))
2910{
2911 // nothing to do here
2912}
2913
2914template <typename T>
2916 actualCamera_(camera)
2917{
2918 // nothing to do here
2919}
2920
2921template <typename T>
2923{
2924 Log::error() << "Invalid camera: " << actualCamera_.reason();
2925
2926 ocean_assert(false && "This function must never be called.");
2927
2928 return actualCamera_;
2929}
2930
2931template <typename T>
2932inline unsigned int CameraWrapperBaseInvalidT<T>::width() const
2933{
2934 Log::error() << "Invalid camera: " << actualCamera_.reason();
2935
2936 ocean_assert(false && "This function must never be called.");
2937
2938 return (unsigned int)(-1);
2939}
2940
2941template <typename T>
2942inline unsigned int CameraWrapperBaseInvalidT<T>::height() const
2943{
2944 Log::error() << "Invalid camera: " << actualCamera_.reason();
2945
2946 ocean_assert(false && "This function must never be called.");
2947
2948 return (unsigned int)(-1);
2949}
2950
2951template <typename T>
2953{
2954 Log::error() << "Invalid camera: " << actualCamera_.reason();
2955
2956 ocean_assert(false && "This function must never be called.");
2957
2959}
2960
2961template <typename T>
2963{
2964 Log::error() << "Invalid camera: " << actualCamera_.reason();
2965
2966 ocean_assert(false && "This function must never be called.");
2967
2968 return NumericT<T>::minValue();
2969}
2970
2971template <typename T>
2973{
2974 Log::error() << "Invalid camera: " << actualCamera_.reason();
2975
2976 ocean_assert(false && "This function must never be called.");
2977
2978 return NumericT<T>::minValue();
2979}
2980
2981template <typename T>
2983{
2984 Log::error() << "Invalid camera: " << actualCamera_.reason();
2985
2986 ocean_assert(false && "This function must never be called.");
2987
2988 return NumericT<T>::minValue();
2989}
2990
2991template <typename T>
2993{
2994 Log::error() << "Invalid camera: " << actualCamera_.reason();
2995
2996 ocean_assert(false && "This function must never be called.");
2997
2998 return NumericT<T>::minValue();
2999}
3000
3001template <typename T>
3003{
3004 Log::error() << "Invalid camera: " << actualCamera_.reason();
3005
3006 ocean_assert(false && "This function must never be called.");
3007
3008 return NumericT<T>::minValue();
3009}
3010
3011template <typename T>
3013{
3014 Log::error() << "Invalid camera: " << actualCamera_.reason();
3015
3016 ocean_assert(false && "This function must never be called.");
3017
3018 return NumericT<T>::minValue();
3019}
3020
3021template <typename T>
3023{
3024 Log::error() << "Invalid camera: " << actualCamera_.reason();
3025
3026 ocean_assert(false && "This function must never be called.");
3027
3029}
3030
3031template <typename T>
3032inline VectorT2<T> CameraWrapperBaseInvalidT<T>::projectToImageIF(const HomogenousMatrixT4<T>& /*flippedCamera_T_world*/, const VectorT3<T>& /*objectPoint*/) const
3033{
3034 Log::error() << "Invalid camera: " << actualCamera_.reason();
3035
3036 ocean_assert(false && "This function must never be called.");
3037
3039}
3040
3041template <typename T>
3042inline void CameraWrapperBaseInvalidT<T>::projectToImageIF(const VectorT3<T>* /*objectPoints*/, const size_t /*size*/, VectorT2<T>* /*imagePoints*/) const
3043{
3044 Log::error() << "Invalid camera: " << actualCamera_.reason();
3045
3046 ocean_assert(false && "This function must never be called.");
3047
3048}
3049
3050template <typename T>
3051inline void CameraWrapperBaseInvalidT<T>::projectToImageIF(const HomogenousMatrixT4<T>& /*flippedCamera_T_world*/, const VectorT3<T>* /*objectPoints*/, const size_t /*size*/, VectorT2<T>* /*imagePoints*/) const
3052{
3053 Log::error() << "Invalid camera: " << actualCamera_.reason();
3054
3055 ocean_assert(false && "This function must never be called.");
3056}
3057
3058template <typename T>
3059inline VectorT3<T> CameraWrapperBaseInvalidT<T>::vectorIF(const VectorT2<T>& /*distortedImagePoint*/, const bool /*makeUnitVector*/) const
3060{
3061 Log::error() << "Invalid camera: " << actualCamera_.reason();
3062
3063 ocean_assert(false && "This function must never be called.");
3064
3066}
3067
3068template <typename T>
3069inline void CameraWrapperBaseInvalidT<T>::vectorIF(const VectorT2<T>* /*distortedImagePoints*/, const size_t /*size*/, VectorT3<T>* /*vectors*/, const bool /*makeUnitVector*/) const
3070{
3071 Log::error() << "Invalid camera: " << actualCamera_.reason();
3072
3073 ocean_assert(false && "This function must never be called.");
3074}
3075
3076template <typename T>
3077inline void CameraWrapperBaseInvalidT<T>::pointJacobian2x3IF(const VectorT3<T>& /*flippedCameraObjectPoint*/, T* /*jx*/, T* /*jy*/) const
3078{
3079 Log::error() << "Invalid camera: " << actualCamera_.reason();
3080
3081 ocean_assert(false && "This function must never be called.");
3082}
3083
3084template <typename T>
3085inline bool CameraWrapperBaseInvalidT<T>::isEqual(const CameraWrapperBaseInvalidT& /*baseFisheye*/, const T /*eps*/) const
3086{
3087 Log::error() << "Invalid camera: " << actualCamera_.reason();
3088
3089 ocean_assert(false && "This function must never be called.");
3090
3091 return false;
3092}
3093
3094template <typename T>
3096{
3097 return false;
3098}
3099
3100template <typename T>
3101template <typename U>
3102inline std::unique_ptr<AnyCameraT<U>> CameraWrapperBaseInvalidT<T>::clone(const unsigned int /*width*/, const unsigned int /*height*/) const
3103{
3104 Log::error() << "Invalid camera: " << actualCamera_.reason();
3105
3106 ocean_assert(false && "This function must never be called.");
3107
3108 return nullptr;
3109}
3110
3111template <typename T>
3116
3117template <typename T>
3119{
3120 return std::string("Invalid camera");
3121}
3122
3123template <typename T>
3124InvalidCameraT<T>::InvalidCameraT(const std::string& reason) :
3125 reason_(reason)
3126{
3127 // nothing to do here
3128}
3129
3130template <typename T>
3131const std::string& InvalidCameraT<T>::reason() const
3132{
3133 return reason_;
3134}
3135
3136}
3137
3138#endif // META_OCEAN_MATH_ANY_CAMERA_H
This class implements a helper class allowing to check whether a 3D object point projects into the ca...
Definition AnyCamera.h:518
bool projectToImageIF(const HomogenousMatrixT4< T > &flippedCamera_T_world, const VectorT3< T > &objectPoint, VectorT2< T > *imagePoint=nullptr) const
Returns whether a 3D object point is located in front of the camera and projects into the camera imag...
Definition AnyCamera.h:1725
bool isValid() const
Returns whether this clipper holds a valid camera model and is ready to be used.
Definition AnyCamera.h:1822
static bool isInside(const FiniteLinesT2< T > &cameraBoundarySegments, const VectorT2< T > &normalizedImagePoint)
Returns whether a given normalized image point lies inside the camera's boundary.
Definition AnyCamera.h:1961
AnyCameraClipperT()=default
Default constructor creating an invalid object.
unsigned int height() const
Returns the height of the camera profile.
Definition AnyCamera.h:1775
const FiniteLinesT2< T > & cameraBoundarySegments() const
Returns the 2D line segments defined in the camera's normalized image plane defining the camera's bou...
Definition AnyCamera.h:1816
FiniteLinesT2< T > cameraBoundarySegments_
The 2D line segments defined in the camera's normalized image plane defining the camera's boundary,...
Definition AnyCamera.h:616
const SharedAnyCameraT< T > & camera() const
Returns the camera model of this clipper.
Definition AnyCamera.h:1758
unsigned int width() const
Returns the width of the camera profile.
Definition AnyCamera.h:1764
SharedAnyCameraT< T > camera_
The actual camera model this clipper is based on.
Definition AnyCamera.h:613
void update(const SharedAnyCameraT< T > &camera, const size_t segmentSteps=10)
Updates the clipper with a new camera model.
Definition AnyCamera.h:1786
static bool determineCameraBoundary(const AnyCameraT< T > &camera, FiniteLinesT2< T > &cameraBoundarySegments, const size_t segmentSteps)
Determines the camera boundary of a given camera model in normalized image coordinates.
Definition AnyCamera.h:1830
static bool isValidForPoint(const AnyCameraT< T > &camera, const VectorT2< T > &imagePoint, const T maximalReprojectionError=T(1), const unsigned int additionalChecksTowardsPrincipalPoint=3u)
Returns whether a given camera model is valid for a specified 2D image point in the camera image.
Definition AnyCamera.h:2008
This class implements the abstract base class for all AnyCamera objects.
Definition AnyCamera.h:131
virtual ~AnyCameraT()=default
Destructs the AnyCamera object.
virtual VectorT3< T > vector(const VectorT2< T > &distortedImagePoint, const bool makeUnitVector=true) const =0
Returns a vector starting at the camera's center and intersecting a given 2D point in the image.
AnyCameraT(AnyCameraT< T > &&)=delete
Disabled move constructor.
virtual LineT3< T > ray(const VectorT2< T > &distortedImagePoint) const =0
Returns a ray starting at the camera's center and intersecting a given 2D point in the image.
virtual unsigned int width() const =0
Returns the width of the camera image.
virtual T focalLengthX() const =0
Returns the horizontal focal length parameter.
virtual VectorT2< T > projectToImage(const HomogenousMatrixT4< T > &world_T_camera, const VectorT3< T > &objectPoint) const =0
Projects a 3D object point into the camera frame.
virtual void vectorIF(const VectorT2< T > *distortedImagePoints, const size_t size, VectorT3< T > *vectors, const bool makeUnitVector=true) const =0
Returns vectors starting at the camera's center and intersecting a given 2D points in the image.
virtual void projectToImage(const VectorT3< T > *objectPoints, const size_t size, VectorT2< T > *imagePoints) const =0
Projects several 3D object points into the camera frame at once.
virtual VectorT2< T > principalPoint() const =0
Returns the coordinate of the principal point of the camera image in the pixel domain.
virtual std::unique_ptr< AnyCameraT< double > > cloneToDouble(const unsigned int width=0u, const unsigned int height=0u) const =0
Returns a copy of this camera object with double precision.
virtual T inverseFocalLengthY() const =0
Returns the inverse vertical focal length parameter.
AnyCameraT & operator=(AnyCameraT &&)=delete
Disabled move operator.
virtual void projectToImageIF(const VectorT3< T > *objectPoints, const size_t size, VectorT2< T > *imagePoints) const =0
Projects several 3D object points into the camera frame at once.
virtual std::unique_ptr< AnyCameraT< T > > clone(const unsigned int width=0u, const unsigned int height=0u) const =0
Returns a copy of this camera object.
virtual T fovX() const =0
Returns the field of view in x direction of the camera.
virtual VectorT2< T > projectToImage(const VectorT3< T > &objectPoint) const =0
Projects a 3D object point into the camera frame.
virtual T inverseFocalLengthX() const =0
Returns the inverse horizontal focal length parameter.
virtual T focalLengthY() const =0
Returns the vertical focal length parameter.
virtual void pointJacobian2x3IF(const VectorT3< T > &flippedCameraObjectPoint, T *jx, T *jy) const =0
Calculates the 2x3 jacobian matrix for the 3D object point projection into the camera frame.
AnyCameraT & operator=(const AnyCameraT &)=delete
Disabled assign operator.
T TScalar
The scalar data type of this object.
Definition AnyCamera.h:135
virtual unsigned int height() const =0
Returns the height of the camera image.
virtual VectorT2< T > projectToImageIF(const VectorT3< T > &objectPoint) const =0
Projects a 3D object point into the camera frame.
virtual T fovY() const =0
Returns the field of view in x direction of the camera.
virtual T principalPointY() const =0
Returns the y-value of the principal point of the camera image in the pixel domain.
virtual void projectToImage(const HomogenousMatrixT4< T > &world_T_camera, const VectorT3< T > *objectPoints, const size_t size, VectorT2< T > *imagePoints) const =0
Projects several 3D object points into the camera frame at once.
virtual bool isEqual(const AnyCameraT< T > &anyCamera, const T eps=NumericT< T >::eps()) const =0
Returns whether two camera objects are identical up to a given epsilon.
virtual VectorT3< T > vectorIF(const VectorT2< T > &distortedImagePoint, const bool makeUnitVector=true) const =0
Returns a vector starting at the camera's center and intersecting a given 2D point in the image.
virtual bool isValid() const =0
Returns whether this camera is valid.
virtual LineT3< T > ray(const VectorT2< T > &distortedImagePoint, const HomogenousMatrixT4< T > &world_T_camera) const =0
Returns a ray starting at the camera's center and intersecting a given 2D point in the image.
virtual VectorT2< T > projectToImageIF(const HomogenousMatrixT4< T > &flippedCamera_T_world, const VectorT3< T > &objectPoint) const =0
Projects a 3D object point into the camera frame.
virtual AnyCameraType anyCameraType() const =0
Returns the type of this camera.
AnyCameraT()=default
Protected default constructor.
virtual void vector(const VectorT2< T > *distortedImagePoints, const size_t size, VectorT3< T > *vectors, const bool makeUnitVector=true) const =0
Determines vectors starting at the camera's center and intersecting given 2D points in the image.
virtual void pointJacobian2nx3IF(const VectorT3< T > *flippedCameraObjectPoints, const size_t numberObjectPoints, T *jacobians) const =0
Calculates the 2n x 3 jacobian matrix for the 3D object point projection into the camera frame.
virtual std::string name() const =0
Returns the name of this camera.
AnyCameraT(const AnyCameraT< T > &anyCamera)=default
Protected copy constructor.
static std::shared_ptr< AnyCameraT< T > > convert(const std::shared_ptr< AnyCameraT< U > > &anyCamera)
Converts an AnyCamera object with arbitrary scalar type to another AnyCamera object with arbitrary sc...
Definition AnyCamera.h:2076
virtual std::unique_ptr< AnyCameraT< float > > cloneToFloat(const unsigned int width=0u, const unsigned int height=0u) const =0
Returns a copy of this camera object with float precision.
virtual void projectToImageIF(const HomogenousMatrixT4< T > &flippedCamera_T_world, const VectorT3< T > *objectPoints, const size_t size, VectorT2< T > *imagePoints) const =0
Projects several 3D object points into the camera frame at once.
virtual bool isInside(const VectorT2< T > &imagePoint, const T signedBorder=T(0)) const =0
Returns whether a given 2D image point lies inside the camera frame.
virtual T principalPointX() const =0
Returns the x-value of the principal point of the camera image in the pixel domain.
This class implements a specialized AnyCamera object wrapping the actual camera model.
Definition AnyCamera.h:630
VectorT2< T > principalPoint() const override
Returns the coordinate of the principal point of the camera image in the pixel domain.
Definition AnyCamera.h:2140
void pointJacobian2nx3IF(const VectorT3< T > *flippedCameraObjectPoints, const size_t numberObjectPoints, T *jacobians) const override
Calculates the 2n x 3 jacobian matrix for the 3D object point projection into the camera frame.
Definition AnyCamera.h:2290
VectorT2< T > projectToImage(const VectorT3< T > &objectPoint) const override
Projects a 3D object point into the camera frame.
Definition AnyCamera.h:2200
bool isEqual(const AnyCameraT< T > &anyCamera, const T eps=NumericT< T >::eps()) const override
Returns whether two camera objects are identical up to a given epsilon.
Definition AnyCamera.h:2296
unsigned int width() const override
Returns the width of the camera image.
Definition AnyCamera.h:2128
unsigned int height() const override
Returns the height of the camera image.
Definition AnyCamera.h:2134
std::unique_ptr< AnyCameraT< float > > cloneToFloat(const unsigned int width=0u, const unsigned int height=0u) const override
Returns a copy of this camera object with float precision.
Definition AnyCamera.h:2116
std::unique_ptr< AnyCameraT< T > > clone(const unsigned int width=0u, const unsigned int height=0u) const override
Returns a copy of this camera object.
Definition AnyCamera.h:2110
T focalLengthY() const override
Returns the vertical focal length parameter.
Definition AnyCamera.h:2164
bool isValid() const override
Returns whether this camera is valid.
Definition AnyCamera.h:2321
AnyCameraType anyCameraType() const override
Returns the type of this camera.
Definition AnyCamera.h:2098
T inverseFocalLengthX() const override
Returns the inverse horizontal focal length parameter.
Definition AnyCamera.h:2170
T principalPointY() const override
Returns the y-value of the principal point of the camera image in the pixel domain.
Definition AnyCamera.h:2152
AnyCameraWrappingT(ActualCamera &&actualCamera)
Creates a new AnyCamera object wrapping the actual camera model.
Definition AnyCamera.h:2084
VectorT3< T > vector(const VectorT2< T > &distortedImagePoint, const bool makeUnitVector=true) const override
Returns a vector starting at the camera's center and intersecting a given 2D point in the image.
Definition AnyCamera.h:2248
VectorT2< T > projectToImageIF(const VectorT3< T > &objectPoint) const override
Projects a 3D object point into the camera frame.
Definition AnyCamera.h:2212
T TScalar
The scalar data type of this object.
Definition AnyCamera.h:634
T focalLengthX() const override
Returns the horizontal focal length parameter.
Definition AnyCamera.h:2158
T fovX() const override
Returns the field of view in x direction of the camera.
Definition AnyCamera.h:2182
bool isInside(const VectorT2< T > &imagePoint, const T signedBorder=T(0)) const override
Returns whether a given 2D image point lies inside the camera frame.
Definition AnyCamera.h:2194
std::string name() const override
Returns the name of this camera.
Definition AnyCamera.h:2104
LineT3< T > ray(const VectorT2< T > &distortedImagePoint, const HomogenousMatrixT4< T > &world_T_camera) const override
Returns a ray starting at the camera's center and intersecting a given 2D point in the image.
Definition AnyCamera.h:2272
VectorT3< T > vectorIF(const VectorT2< T > &distortedImagePoint, const bool makeUnitVector=true) const override
Returns a vector starting at the camera's center and intersecting a given 2D point in the image.
Definition AnyCamera.h:2260
typename TCameraWrapper::ActualCamera ActualCamera
The actual camera object wrapped by this class.
Definition AnyCamera.h:640
T principalPointX() const override
Returns the x-value of the principal point of the camera image in the pixel domain.
Definition AnyCamera.h:2146
std::unique_ptr< AnyCameraT< double > > cloneToDouble(const unsigned int width=0u, const unsigned int height=0u) const override
Returns a copy of this camera object with double precision.
Definition AnyCamera.h:2122
void pointJacobian2x3IF(const VectorT3< T > &flippedCameraObjectPoint, T *jx, T *jy) const override
Calculates the 2x3 jacobian matrix for the 3D object point projection into the camera frame.
Definition AnyCamera.h:2284
T fovY() const override
Returns the field of view in x direction of the camera.
Definition AnyCamera.h:2188
T inverseFocalLengthY() const override
Returns the inverse vertical focal length parameter.
Definition AnyCamera.h:2176
This class implements the base class for all cameras.
Definition Camera.h:98
This class implements the base wrapper around Ocean's fisheye camera profile.
Definition AnyCamera.h:1239
T principalPointX() const
Returns the x-value of the principal point of the camera image in the pixel domain.
Definition AnyCamera.h:2742
T inverseFocalLengthX() const
Returns the inverse horizontal focal length parameter.
Definition AnyCamera.h:2766
ActualCamera actualCamera_
The actual fisheye camera object.
Definition AnyCamera.h:1402
unsigned int height() const
Returns the height of the camera image.
Definition AnyCamera.h:2730
void pointJacobian2x3IF(const VectorT3< T > &flippedCameraObjectPoint, T *jx, T *jy) const
Calculates the 2x3 jacobian matrix for the 3D object point projection into the camera frame.
Definition AnyCamera.h:2832
unsigned int width() const
Returns the width of the camera image.
Definition AnyCamera.h:2724
bool isValid() const
Returns whether this camera is valid.
Definition AnyCamera.h:2846
FisheyeCameraT< T > ActualCamera
Definition of the actual camera object wrapped by this class.
Definition AnyCamera.h:1245
T inverseFocalLengthY() const
Returns the inverse vertical focal length parameter.
Definition AnyCamera.h:2772
static AnyCameraType anyCameraType()
Returns the type of this camera.
Definition AnyCamera.h:2896
VectorT3< T > vectorIF(const VectorT2< T > &distortedImagePoint, const bool makeUnitVector) const
Returns a vector starting at the camera's center and intersecting a given 2D point in the image.
Definition AnyCamera.h:2814
const ActualCamera & actualCamera() const
Returns the actual camera object wrapped in this class.
Definition AnyCamera.h:2718
VectorT2< T > principalPoint() const
Returns the coordinate of the principal point of the camera image in the pixel domain.
Definition AnyCamera.h:2736
T principalPointY() const
Returns the y-value of the principal point of the camera image in the pixel domain.
Definition AnyCamera.h:2748
static std::string name()
Returns the name of this camera.
Definition AnyCamera.h:2902
T focalLengthX() const
Returns the horizontal focal length parameter.
Definition AnyCamera.h:2754
T focalLengthY() const
Returns the vertical focal length parameter.
Definition AnyCamera.h:2760
VectorT2< T > projectToImageIF(const VectorT3< T > &objectPoint) const
Projects a 3D object point into the camera frame.
Definition AnyCamera.h:2778
CameraWrapperBaseFisheyeT(ActualCamera &&actualCamera)
Creates a new CameraWrapperBaseFisheyeT object wrapping the actual camera model.
Definition AnyCamera.h:2704
std::unique_ptr< AnyCameraT< U > > clone(const unsigned int width=0u, const unsigned int height=0u) const
Returns a copy of the actual camera object.
Definition AnyCamera.h:2853
bool isEqual(const CameraWrapperBaseFisheyeT< T > &baseFisheye, const T eps=NumericT< T >::eps()) const
Returns whether two camera objects are identical up to a given epsilon.
Definition AnyCamera.h:2838
This class implements the base wrapper around an invalid camera profile.
Definition AnyCamera.h:1462
bool isEqual(const CameraWrapperBaseInvalidT< T > &baseInvalid, const T eps=NumericT< T >::eps()) const
Returns whether two camera objects are identical up to a given epsilon.
Definition AnyCamera.h:3085
InvalidCameraT< T > ActualCamera
Definition of the actual camera object wrapped by this class.
Definition AnyCamera.h:1468
VectorT2< T > projectToImageIF(const VectorT3< T > &objectPoint) const
Projects a 3D object point into the camera frame.
Definition AnyCamera.h:3022
CameraWrapperBaseInvalidT(ActualCamera &&actualCamera)
Creates a new CameraWrapperBaseInvalidT object wrapping the actual camera model.
Definition AnyCamera.h:2908
unsigned int height() const
Returns the height of the camera image.
Definition AnyCamera.h:2942
const ActualCamera & actualCamera() const
Returns the actual camera object wrapped in this class.
Definition AnyCamera.h:2922
static std::string name()
Returns the name of this camera.
Definition AnyCamera.h:3118
ActualCamera actualCamera_
The actual invalid camera.
Definition AnyCamera.h:1625
T principalPointX() const
Returns the x-value of the principal point of the camera image in the pixel domain.
Definition AnyCamera.h:2962
VectorT2< T > principalPoint() const
Returns the coordinate of the principal point of the camera image in the pixel domain.
Definition AnyCamera.h:2952
T inverseFocalLengthX() const
Returns the inverse horizontal focal length parameter.
Definition AnyCamera.h:3002
bool isValid() const
Returns whether this camera is valid.
Definition AnyCamera.h:3095
static AnyCameraType anyCameraType()
Returns the type of this camera.
Definition AnyCamera.h:3112
std::unique_ptr< AnyCameraT< U > > clone(const unsigned int width=0u, const unsigned int height=0u) const
Returns a copy of the actual camera object.
Definition AnyCamera.h:3102
T inverseFocalLengthY() const
Returns the inverse vertical focal length parameter.
Definition AnyCamera.h:3012
void pointJacobian2x3IF(const VectorT3< T > &flippedCameraObjectPoint, T *jx, T *jy) const
Calculates the 2x3 jacobian matrix for the 3D object point projection into the camera frame.
Definition AnyCamera.h:3077
VectorT3< T > vectorIF(const VectorT2< T > &distortedImagePoint, const bool makeUnitVector) const
Returns a vector starting at the camera's center and intersecting a given 2D point in the image.
Definition AnyCamera.h:3059
T focalLengthY() const
Returns the vertical focal length parameter.
Definition AnyCamera.h:2992
T principalPointY() const
Returns the y-value of the principal point of the camera image in the pixel domain.
Definition AnyCamera.h:2972
T focalLengthX() const
Returns the horizontal focal length parameter.
Definition AnyCamera.h:2982
unsigned int width() const
Returns the width of the camera image.
Definition AnyCamera.h:2932
This class implements the base wrapper around Ocean's pinhole camera profile.
Definition AnyCamera.h:1070
T inverseFocalLengthX() const
Returns the inverse horizontal focal length parameter.
Definition AnyCamera.h:2557
void pointJacobian2x3IF(const VectorT3< T > &flippedCameraObjectPoint, T *jx, T *jy) const
Calculates the 2x3 jacobian matrix for the 3D object point projection into the camera frame.
Definition AnyCamera.h:2625
PinholeCameraT< T > ActualCamera
Definition of the actual camera object wrapped by this class.
Definition AnyCamera.h:1076
unsigned int height() const
Returns the height of the camera image.
Definition AnyCamera.h:2527
bool isValid() const
Returns whether this camera is valid.
Definition AnyCamera.h:2640
T principalPointY() const
Returns the y-value of the principal point of the camera image in the pixel domain.
Definition AnyCamera.h:2539
T inverseFocalLengthY() const
Returns the inverse vertical focal length parameter.
Definition AnyCamera.h:2563
static std::string name()
Returns the name of this camera.
Definition AnyCamera.h:2698
ActualCamera actualCamera_
The actual pinhole camera.
Definition AnyCamera.h:1228
const ActualCamera & actualCamera() const
Returns the actual camera object wrapped in this class.
Definition AnyCamera.h:2515
unsigned int width() const
Returns the width of the camera image.
Definition AnyCamera.h:2521
CameraWrapperBasePinholeT(ActualCamera &&actualCamera)
Creates a new CameraWrapperBasePinholeT object wrapping the actual camera model.
Definition AnyCamera.h:2501
VectorT3< T > vectorIF(const VectorT2< T > &distortedImagePoint, const bool makeUnitVector) const
Returns a vector starting at the camera's center and intersecting a given 2D point in the image.
Definition AnyCamera.h:2605
VectorT2< T > projectToImageIF(const VectorT3< T > &objectPoint) const
Projects a 3D object point into the camera frame.
Definition AnyCamera.h:2569
static AnyCameraType anyCameraType()
Returns the type of this camera.
Definition AnyCamera.h:2692
T principalPointX() const
Returns the x-value of the principal point of the camera image in the pixel domain.
Definition AnyCamera.h:2533
bool isEqual(const CameraWrapperBasePinholeT< T > &basePinhole, const T eps=NumericT< T >::eps()) const
Returns whether two camera objects are identical up to a given epsilon.
Definition AnyCamera.h:2632
std::unique_ptr< AnyCameraT< U > > clone(const unsigned int width=0u, const unsigned int height=0u) const
Returns a copy of the actual camera object.
Definition AnyCamera.h:2647
T focalLengthY() const
Returns the vertical focal length parameter.
Definition AnyCamera.h:2551
T focalLengthX() const
Returns the horizontal focal length parameter.
Definition AnyCamera.h:2545
This class implements a wrapper for an actual camera object.
Definition AnyCamera.h:961
LineT3< T > ray(const VectorT2< T > &distortedImagePoint, const HomogenousMatrixT4< T > &world_T_camera) const
Returns a ray starting at the camera's center and intersecting a given 2D point in the image.
Definition AnyCamera.h:2471
T fovY() const
Returns the field of view in x direction of the camera.
Definition AnyCamera.h:2376
T fovX() const
Returns the field of view in x direction of the camera.
Definition AnyCamera.h:2347
CameraWrapperT(ActualCamera &&actualCamera)
Creates a new CameraWrapperT object wrapping the actual camera model.
Definition AnyCamera.h:2327
VectorT3< T > vector(const VectorT2< T > &distortedImagePoint, const bool makeUnitVector) const
Returns a vector starting at the camera's center and intersecting a given 2D point in the image.
Definition AnyCamera.h:2450
void pointJacobian2nx3IF(const VectorT3< T > *flippedCameraObjectPoints, const size_t numberObjectPoints, T *jacobians) const
Calculates the 2x3 jacobian matrix for the 3D object point projection into the camera frame.
Definition AnyCamera.h:2487
bool isInside(const VectorT2< T > &imagePoint, const T signedBorder=T(0)) const
Returns whether a given 2D image point lies inside the camera frame.
Definition AnyCamera.h:2405
VectorT2< T > principalPoint() const
Returns the coordinate of the principal point of the camera image in the pixel domain.
Definition AnyCamera.h:2341
VectorT2< T > projectToImage(const VectorT3< T > &objectPoint) const
Projects a 3D object point into the camera frame.
Definition AnyCamera.h:2419
This class implements an finite line in 2D space.
Definition FiniteLine2.h:82
Class representing a fisheye camera.
Definition FisheyeCamera.h:106
This class implements a 4x4 homogeneous transformation matrix using floating point values with the pr...
Definition HomogenousMatrix4.h:110
SquareMatrixT3< T > rotationMatrix() const
Returns the rotation matrix of the transformation.
Definition HomogenousMatrix4.h:1493
VectorT3< T > translation() const
Returns the translation of the transformation.
Definition HomogenousMatrix4.h:1381
bool isValid() const
Returns whether this matrix is a valid homogeneous transformation.
Definition HomogenousMatrix4.h:1806
This class implements invalid camera profiles, e.g.
Definition AnyCamera.h:1412
const std::string & reason() const
Returns the reason of this invalid camera.
Definition AnyCamera.h:3131
std::string reason_
The reason why no valid camera is available.
Definition AnyCamera.h:1430
InvalidCameraT(const std::string &reason)
Creates an invalid camera.
Definition AnyCamera.h:3124
This class implements an infinite line in 3D space.
Definition Line3.h:68
static MessageObject error()
Returns the message for error messages.
Definition Messenger.h:1095
This class provides basic numeric functionalities.
Definition Numeric.h:57
static constexpr T minValue()
Returns the min scalar value.
Definition Numeric.h:3259
static T atan(const T value)
Returns the arctangent of a given value.
Definition Numeric.h:1620
static T abs(const T value)
Returns the absolute value of a given value.
Definition Numeric.h:1220
static bool isEqual(const T first, const T second)
Returns whether two values are equal up to a small epsilon.
Definition Numeric.h:2395
static constexpr T sqr(const T value)
Returns the square of a given value.
Definition Numeric.h:1499
Definition of a pinhole camera model.
Definition PinholeCamera.h:114
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
bool isNull() const
Returns whether this vector is a null vector up to a small epsilon.
Definition Vector2.h:746
T sqrDistance(const VectorT2< T > &right) const
Returns the square distance between this 2D position and a second 2D position.
Definition Vector2.h:645
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
VectorT2< T > xy() const noexcept
Returns the x and y component of the vector as new 2D vector.
Definition Vector3.h:848
static VectorT3< T > minValue()
Returns a 3D vector with all elements set to NumericT::minValue().
Definition Vector3.h:1059
const T & z() const noexcept
Returns the z value.
Definition Vector3.h:836
std::shared_ptr< AnyCameraD > SharedAnyCameraD
Definition of a shared pointer holding an AnyCamera object with double precision.
Definition AnyCamera.h:68
std::shared_ptr< AnyCamera > SharedAnyCamera
Definition of a shared pointer holding an AnyCamera object with Scalar precision.
Definition AnyCamera.h:61
std::vector< FiniteLineT2< T > > FiniteLinesT2
Definition of a typename alias for vectors with FiniteLineT2 objects.
Definition FiniteLine2.h:50
std::vector< VectorT2< T > > VectorsT2
Definition of a typename alias for vectors with VectorT2 objects.
Definition Vector2.h:57
SharedAnyCamerasT< float > SharedAnyCamerasF
Definition of a vector holding AnyCameraF objects.
Definition AnyCamera.h:105
SharedAnyCamerasT< double > SharedAnyCamerasD
Definition of a vector holding AnyCameraD objects.
Definition AnyCamera.h:98
AnyCameraType
Definition of individual camera types.
Definition AnyCamera.h:112
std::shared_ptr< AnyCameraF > SharedAnyCameraF
Definition of a shared pointer holding an AnyCamera object with float precision.
Definition AnyCamera.h:75
std::vector< std::shared_ptr< AnyCameraT< T > > > SharedAnyCamerasT
Definition of a typename alias for vectors with shared AnyCameraT objects.
Definition AnyCamera.h:84
SharedAnyCamerasT< Scalar > SharedAnyCameras
Definition of a vector holding AnyCamera objects.
Definition AnyCamera.h:91
std::shared_ptr< AnyCameraT< T > > SharedAnyCameraT
Definition of a shared pointer holding an AnyCamera object with Scalar precision.
Definition AnyCamera.h:54
@ FISHEYE
A fisheye camera.
@ PINHOLE
A pinhole camera.
@ INVALID
An invalid camera type.
The namespace covering the entire Ocean framework.
Definition Accessor.h:15