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 */
309 virtual VectorT2<T> projectToImageIF(const HomogenousMatrixT4<T>& flippedCamera_T_world, const VectorT3<T>& objectPoint) const = 0;
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 */
377 virtual LineT3<T> ray(const VectorT2<T>& distortedImagePoint, const HomogenousMatrixT4<T>& world_T_camera) const = 0;
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 * Updates the clipper with a new camera model based on a cloned copy of the provided camera.
570 * If the new camera is equal to the current camera, the function will return immediately without any updates.
571 * @param camera The camera model defining the projection, must be valid
572 * @param segmentSteps The number of segments to be used to determine the camera boundary, with range [1, infinity)
573 */
574 void update(const AnyCameraT<T>& camera, const size_t segmentSteps = 10);
575
576 /**
577 * Returns the 2D line segments defined in the camera's normalized image plane defining the camera's boundary.
578 * @return The camera boundary segments
579 */
581
582 /**
583 * Returns whether this clipper holds a valid camera model and is ready to be used.
584 * @return True, if so
585 */
586 bool isValid() const;
587
588 protected:
589
590 /**
591 * Determines the camera boundary of a given camera model in normalized image coordinates.
592 * @param camera The camera model for which the boundary will be determined, must be valid
593 * @param cameraBoundarySegments The resulting 2D line segments defining the camera's boundary
594 * @param segmentSteps The number of segments to be used to determine the camera boundary, with range [1, infinity)
595 * @return True, if succeeded
596 */
597 static bool determineCameraBoundary(const AnyCameraT<T>& camera, FiniteLinesT2<T>& cameraBoundarySegments, const size_t segmentSteps);
598
599 /**
600 * Returns whether a given normalized image point lies inside the camera's boundary.
601 * @param cameraBoundarySegments The 2D line segments defining the camera's boundary, at least three
602 * @param normalizedImagePoint The normalized image point to be checked
603 * @return True, if if so
604 */
605 static bool isInside(const FiniteLinesT2<T>& cameraBoundarySegments, const VectorT2<T>& normalizedImagePoint);
606
607 /**
608 * Returns whether a given camera model is valid for a specified 2D image point in the camera image.
609 * 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.
610 * @param camera The camera model to be checked, must be valid
611 * @param imagePoint The 2D image point to be checked, defined in the camera image, with range [0, width()]x[0, height()]
612 * @param maximalReprojectionError The maximal allowed re-projection error in pixel, with range [0, infinity)
613 * @param additionalChecksTowardsPrincipalPoint The number of additional image points sampled towards the principal point to be checked, with range [1, infinity)
614 * @return True, if the camera model is valid for the specified image point
615 */
616 static bool isValidForPoint(const AnyCameraT<T>& camera, const VectorT2<T>& imagePoint, const T maximalReprojectionError = T(1), const unsigned int additionalChecksTowardsPrincipalPoint = 3u);
617
618 protected:
619
620 /// The actual camera model this clipper is based on.
622
623 /// 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.
625};
626
627/**
628 * This class implements a specialized AnyCamera object wrapping the actual camera model.
629 * The class is a helper class to simplify the implementation of specialized AnyCamera objects.
630 * @tparam T The data type of a scalar, 'float' or 'double'
631 * @tparam TCameraWrapper The data type of the class actually wrapping the camera object
632 * @ingroup math
633 */
634template <typename T, typename TCameraWrapper>
636 public AnyCameraT<T>,
637 public TCameraWrapper
638{
639 public:
640
641 /// The scalar data type of this object.
642 using TScalar = T;
643
644 /// The class which is actually wrapping the camera object.
646
647 /// The actual camera object wrapped by this class.
648 using ActualCamera = typename TCameraWrapper::ActualCamera;
649
650 public:
651
652 /**
653 * Creates a new AnyCamera object wrapping the actual camera model.
654 * @param actualCamera The actual camera object to be wrapped
655 */
656 explicit AnyCameraWrappingT(ActualCamera&& actualCamera);
657
658 /**
659 * Creates a new AnyCamera object wrapping the actual camera model.
660 * @param actualCamera The actual camera object to be wrapped
661 */
662 explicit AnyCameraWrappingT(const ActualCamera& actualCamera);
663
664 /**
665 * Returns the type of this camera.
666 * @return The camera's type
667 */
668 AnyCameraType anyCameraType() const override;
669
670 /**
671 * Returns the name of this camera.
672 * @return The camera's name
673 */
674 std::string name() const override;
675
676 /**
677 * Returns a copy of this camera object.
678 * The image resolution of the cloned camera must have the same aspect ratio as the current image resolution.
679 * @param width The width of the cloned camera in pixel, with range [1, infinity), 0 to use the current image resolution
680 * @param height the height of the cloned camera in pixel, with range [1, infinity), 0 to use the current image resolution
681 * @return New instance of this camera object
682 */
683 std::unique_ptr<AnyCameraT<T>> clone(const unsigned int width = 0u, const unsigned int height = 0u) const override;
684
685 /**
686 * Returns a copy of this camera object with float precision.
687 * The image resolution of the cloned camera must have the same aspect ratio as the current image resolution.
688 * @param width The width of the cloned camera in pixel, with range [1, infinity), 0 to use the current image resolution
689 * @param height the height of the cloned camera in pixel, with range [1, infinity), 0 to use the current image resolution
690 * @return New instance of this camera object
691 */
692 std::unique_ptr<AnyCameraT<float>> cloneToFloat(const unsigned int width = 0u, const unsigned int height = 0u) const override;
693
694 /**
695 * Returns a copy of this camera object with double precision.
696 * The image resolution of the cloned camera must have the same aspect ratio as the current image resolution.
697 * @param width The width of the cloned camera in pixel, with range [1, infinity), 0 to use the current image resolution
698 * @param height the height of the cloned camera in pixel, with range [1, infinity), 0 to use the current image resolution
699 * @return New instance of this camera object
700 */
701 std::unique_ptr<AnyCameraT<double>> cloneToDouble(const unsigned int width = 0u, const unsigned int height = 0u) const override;
702
703 /**
704 * Returns the width of the camera image.
705 * @return Width of the camera image, in pixel, with range [0, infinity)
706 */
707 unsigned int width() const override;
708
709 /**
710 * Returns the height of the camera image.
711 * @return Height of the camera image, in pixel, with range [0, infinity)
712 */
713 unsigned int height() const override;
714
715 /**
716 * Returns the coordinate of the principal point of the camera image in the pixel domain.
717 * @return The 2D location of the principal point, with range (-infinity, infinity)x(-infinity, infinity)
718 */
719 VectorT2<T> principalPoint() const override;
720
721 /**
722 * Returns the x-value of the principal point of the camera image in the pixel domain.
723 * @return x-value of the principal point, with range (-infinity, infinity)
724 */
725 T principalPointX() const override;
726
727 /**
728 * Returns the y-value of the principal point of the camera image in the pixel domain.
729 * @return y-value of the principal point, with range (-infinity, infinity)
730 */
731 T principalPointY() const override;
732
733 /**
734 * Returns the horizontal focal length parameter.
735 * @return Horizontal focal length parameter in pixel domain, with range (0, infinity)
736 */
737 T focalLengthX() const override;
738
739 /**
740 * Returns the vertical focal length parameter.
741 * @return Vertical focal length parameter in pixel domain, with range (0, infinity)
742 */
743 T focalLengthY() const override;
744
745 /**
746 * Returns the inverse horizontal focal length parameter.
747 * @return Inverse horizontal focal length parameter in pixel domain, with range (0, infinity)
748 */
749 T inverseFocalLengthX() const override;
750
751 /**
752 * Returns the inverse vertical focal length parameter.
753 * @return Inverse vertical focal length parameter in pixel domain, with range (0, infinity)
754 */
755 T inverseFocalLengthY() const override;
756
757 /**
758 * Returns the field of view in x direction of the camera.
759 * The fov is the sum of the left and right part of the camera.
760 * @return Field of view (in radian), with range (0, 2 * PI]
761 */
762 T fovX() const override;
763
764 /**
765 * Returns the field of view in x direction of the camera.
766 * The fov is the sum of the top and bottom part of the camera.
767 * @return Field of view (in radian), with range (0, 2 * PI]
768 */
769 T fovY() const override;
770
771 /**
772 * Returns whether a given 2D image point lies inside the camera frame.
773 * Optional an explicit border can be defined to allow points slightly outside the camera image, or further inside the image.<br>
774 * 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.
775 * @param imagePoint Image point to be checked, must be valid
776 * @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)
777 * @return True, if the image point lies in the ranges [0, width())x[0, height())
778 */
779 bool isInside(const VectorT2<T>& imagePoint, const T signedBorder = T(0)) const override;
780
781 /**
782 * Projects a 3D object point into the camera frame.
783 * The projection is applied with a default camera pose, the camera is looking into the negative z-space with y-axis up.
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 VectorT3<T>& objectPoint) const override;
788
789 /**
790 * Projects a 3D object point into the camera frame.
791 * @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
792 * @param objectPoint The 3D object point to project, defined in world
793 * @return The projected 2D image point
794 */
795 VectorT2<T> projectToImage(const HomogenousMatrixT4<T>& world_T_camera, const VectorT3<T>& objectPoint) const override;
796
797 /**
798 * Projects several 3D object points into the camera frame at once.
799 * The projection is applied with a default camera pose, the camera is looking into the negative z-space with y-axis up.
800 * @param objectPoints The 3D object points to project, defined in world, must be valid
801 * @param size The number of object points, with range [1, infinity)
802 * @param imagePoints The resulting 2D image points, must be valid
803 */
804 void projectToImage(const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const override;
805
806 /**
807 * Projects several 3D object points into the camera frame at once.
808 * @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
809 * @param objectPoints The 3D object points to project, defined in world, must be valid
810 * @param size The number of object points, with range [1, infinity)
811 * @param imagePoints The resulting 2D image points, must be valid
812 */
813 void projectToImage(const HomogenousMatrixT4<T>& world_T_camera, const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const override;
814
815 /**
816 * Projects a 3D object point into the camera frame.
817 * 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.
818 * @param objectPoint The 3D object point to project, defined in world
819 * @return The projected 2D image point
820 */
821 VectorT2<T> projectToImageIF(const VectorT3<T>& objectPoint) const override;
822
823 /**
824 * Projects a 3D object point into the camera frame.
825 * @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
826 * @param objectPoint The 3D object point to project, defined in world
827 * @return The projected 2D image point
828 */
829 VectorT2<T> projectToImageIF(const HomogenousMatrixT4<T>& flippedCamera_T_world, const VectorT3<T>& objectPoint) const override;
830
831 /**
832 * Projects several 3D object points into the camera frame at once.
833 * 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.
834 * @param objectPoints The 3D object points to project, defined in world, must be valid
835 * @param size The number of object points, with range [1, infinity)
836 * @param imagePoints The resulting 2D image points, must be valid
837 */
838 void projectToImageIF(const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const override;
839
840 /**
841 * Projects several 3D object points into the camera frame at once.
842 * @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
843 * @param objectPoints The 3D object points to project, defined in world, must be valid
844 * @param size The number of object points, with range [1, infinity)
845 * @param imagePoints The resulting 2D image points, must be valid
846 */
847 void projectToImageIF(const HomogenousMatrixT4<T>& flippedCamera_T_world, const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const override;
848
849 /**
850 * Returns a vector starting at the camera's center and intersecting a given 2D point in the image.
851 * The vector is determined for the default camera looking into the negative z-space with y-axis up.
852 * @param distortedImagePoint 2D (distorted) position within the image, with range [0, width())x[0, height())
853 * @param makeUnitVector True, to return a vector with length 1; False, to return a vector with any length
854 * @return Vector pointing into the negative z-space
855 * @see vectorIF(), ray().
856 */
857 VectorT3<T> vector(const VectorT2<T>& distortedImagePoint, const bool makeUnitVector = true) const override;
858
859 /**
860 * Determines vectors starting at the camera's center and intersecting given 2D points in the image.
861 * The vectors are determined for a default camera looking into the negative z-space with y-axis up.
862 * @param distortedImagePoints 2D (distorted) positions within the image, with range [0, width())x[0, height()), must be valid
863 * @param size The number of provided points, with range [1, infinity)
864 * @param vectors The resulting vectors pointing into the negative z-space, one for each image point, must be valid
865 * @param makeUnitVector True, to return a vector with length 1; False, to return a vector with any length
866 * @see vectorIF(), ray().
867 */
868 void vector(const VectorT2<T>* distortedImagePoints, const size_t size, VectorT3<T>* vectors, const bool makeUnitVector = true) const override;
869
870 /**
871 * Returns a vector starting at the camera's center and intersecting a given 2D point in the image.
872 * The vector is determined for the default camera looking into the positive z-space with y-axis down.
873 * @param distortedImagePoint 2D (distorted) position within the image, with range [0, width())x[0, height())
874 * @param makeUnitVector True, to return a vector with length 1; False, to return a vector with any length
875 * @return Vector pointing into the positive z-space
876 */
877 VectorT3<T> vectorIF(const VectorT2<T>& distortedImagePoint, const bool makeUnitVector = true) const override;
878
879 /**
880 * Returns vectors starting at the camera's center and intersecting a given 2D points in the image.
881 * The vectors are determined for a default camera looking into the positive z-space with y-axis down.
882 * @param distortedImagePoints 2D (distorted) positions within the image, with range [0, width())x[0, height()), must be valid
883 * @param size The number of provided points, with range [1, infinity)
884 * @param vectors The resulting vectors pointing into the positive z-space, one for each image point, must be valid
885 * @param makeUnitVector True, to return a vector with length 1; False, to return a vector with any length
886 */
887 void vectorIF(const VectorT2<T>* distortedImagePoints, const size_t size, VectorT3<T>* vectors, const bool makeUnitVector = true) const override;
888
889 /**
890 * Returns a ray starting at the camera's center and intersecting a given 2D point in the image.
891 * @param distortedImagePoint 2D (distorted) position within the image, with range [0, width())x[0, height())
892 * @param world_T_camera The pose of the camera, the extrinsic camera matrix, must be valid
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 HomogenousMatrixT4<T>& world_T_camera) const override;
897
898 /**
899 * Returns a ray starting at the camera's center and intersecting a given 2D point in the image.
900 * @param distortedImagePoint 2D (distorted) position within the image, with range [0, width())x[0, height())
901 * @return The specified ray with direction pointing into the camera's negative z-space
902 * @see vector().
903 */
904 LineT3<T> ray(const VectorT2<T>& distortedImagePoint) const override;
905
906 /**
907 * Calculates the 2x3 jacobian matrix for the 3D object point projection into the camera frame.
908 * The resulting jacobian matrix has the following layout:
909 * <pre>
910 * | dfu / dx, dfu / dy, dfu / dz |
911 * | dfv / dx, dfv / dy, dfv / dz |
912 * with projection function
913 * q = f(p)
914 * q_u = fu(p), q_v = fv(p)
915 * with 2D image point q = (q_u, q_v) and 3D object point p = (x, y, z)
916 * </pre>
917 * @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).
918 * @param jx The resulting first row of the Jacobian matrix, must contain three elements, must be valid
919 * @param jy The resulting second row of the Jacobian matrix, must contain three elements, must be valid
920 */
921 void pointJacobian2x3IF(const VectorT3<T>& flippedCameraObjectPoint, T* jx, T* jy) const override;
922
923 /**
924 * Calculates the 2n x 3 jacobian matrix for the 3D object point projection into the camera frame.
925 * The resulting jacobian matrix has the following layout:
926 * <pre>
927 * | dfu / dx, dfu / dy, dfu / dz | <- for object point 0
928 * | dfv / dx, dfv / dy, dfv / dz |
929 * | ... |
930 * | dfu / dx, dfu / dy, dfu / dz | <- for object point n - 1
931 * | dfv / dx, dfv / dy, dfv / dz |
932 * with projection function
933 * q = f(p)
934 * q_u = fu(p), q_v = fv(p)
935 * with 2D image point q = (q_u, q_v) and 3D object point p = (x, y, z)
936 * </pre>
937 * @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).
938 * @param numberObjectPoints The number of given 3D object points, with range [1, infinity)
939 * @param jacobians The resulting 2n x 3 Jacobian matrix, with 2 * numberObjectPoints * 3 elements, must be valid
940 */
941 void pointJacobian2nx3IF(const VectorT3<T>* flippedCameraObjectPoints, const size_t numberObjectPoints, T* jacobians) const override;
942
943 /**
944 * Returns whether two camera objects are identical up to a given epsilon.
945 * The image resolution must always be identical.
946 * @param anyCamera The second camera to be used for comparison, can be invalid
947 * @param eps The epsilon threshold to be used, with range [0, infinity)
948 * @return True, if so
949 */
950 bool isEqual(const AnyCameraT<T>& anyCamera, const T eps = NumericT<T>::eps()) const override;
951
952 /**
953 * Returns whether this camera is valid.
954 * @return True, if so
955 */
956 bool isValid() const override;
957};
958
959/**
960 * This class implements a wrapper for an actual camera object.
961 * - TCameraWrapperBase implements the wrapper functions necessary for the individual camera models.
962 * - CameraWrapperT implements some additional functions necessary to fully implement all necessary functions for AnyCameraT.
963 * @tparam T The data type of a scalar, 'float' or 'double'
964 * @tparam TCameraWrapperBase The base class implementing all functions necessary for the wrapped camera object.
965 * @ingroup math
966 */
967template <typename T, typename TCameraWrapperBase>
969{
970 public:
971
972 /**
973 * Definition of the actual camera object which is wrapped in this class.
974 */
975 using typename TCameraWrapperBase::ActualCamera;
976
977 public:
978
979 /**
980 * Creates a new CameraWrapperT object wrapping the actual camera model.
981 * @param actualCamera The actual camera object to be wrapped
982 */
983 explicit CameraWrapperT(ActualCamera&& actualCamera);
984
985 /**
986 * Creates a new CameraWrapperT object wrapping the actual camera model.
987 * @param actualCamera The actual camera object to be wrapped
988 */
989 explicit CameraWrapperT(const ActualCamera& actualCamera);
990
991 /**
992 * Returns the coordinate of the principal point of the camera image in the pixel domain.
993 * @see AnyCameraT::principalPoint().
994 */
995 inline VectorT2<T> principalPoint() const;
996
997 /**
998 * Returns the field of view in x direction of the camera.
999 * @see AnyCameraT::fovX().
1000 */
1001 inline T fovX() const;
1002
1003 /**
1004 * Returns the field of view in x direction of the camera.
1005 * @see AnyCameraT::fovY().
1006 */
1007 inline T fovY() const;
1008
1009 /**
1010 * Returns whether a given 2D image point lies inside the camera frame.
1011 * @see AnyCameraT::isInside().
1012 */
1013 inline bool isInside(const VectorT2<T>& imagePoint, const T signedBorder = T(0)) const;
1014
1015 /**
1016 * Projects a 3D object point into the camera frame.
1017 * @see projectToImage().
1018 */
1019 inline VectorT2<T> projectToImage(const VectorT3<T>& objectPoint) const;
1020
1021 /**
1022 * Projects a 3D object point into the camera frame.
1023 * @see projectToImage().
1024 */
1025 inline VectorT2<T> projectToImage(const HomogenousMatrixT4<T>& world_T_camera, const VectorT3<T>& objectPoint) const;
1026
1027 /**
1028 * Projects several 3D object points into the camera frame at once.
1029 * @see projectToImage().
1030 */
1031 inline void projectToImage(const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const;
1032
1033 /**
1034 * Projects several 3D object points into the camera frame at once.
1035 * @see projectToImage().
1036 */
1037 inline void projectToImage(const HomogenousMatrixT4<T>& world_T_camera, const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const;
1038
1039 /**
1040 * Returns a vector starting at the camera's center and intersecting a given 2D point in the image.
1041 * @see AnyCameraT::vector().
1042 */
1043 inline VectorT3<T> vector(const VectorT2<T>& distortedImagePoint, const bool makeUnitVector) const;
1044
1045 /**
1046 * Determines vectors starting at the camera's center and intersecting given 2D points in the image.
1047 * @see AnyCameraT::vector().
1048 */
1049 inline void vector(const VectorT2<T>* distortedImagePoints, const size_t size, VectorT3<T>* vectors, const bool makeUnitVector) const;
1050
1051 /**
1052 * Returns a ray starting at the camera's center and intersecting a given 2D point in the image.
1053 * @see ray().
1054 */
1055 inline LineT3<T> ray(const VectorT2<T>& distortedImagePoint, const HomogenousMatrixT4<T>& world_T_camera) const;
1056
1057 /**
1058 * Returns a ray starting at the camera's center and intersecting a given 2D point in the image.
1059 * @see ray().
1060 */
1061 inline LineT3<T> ray(const VectorT2<T>& distortedImagePoint) const;
1062
1063 /**
1064 * Calculates the 2x3 jacobian matrix for the 3D object point projection into the camera frame.
1065 * @see AnyCameraT::pointJacobian2nx3IF().
1066 */
1067 inline void pointJacobian2nx3IF(const VectorT3<T>* flippedCameraObjectPoints, const size_t numberObjectPoints, T* jacobians) const;
1068};
1069
1070/**
1071 * This class implements the base wrapper around Ocean's pinhole camera profile.
1072 * The class can be used as 'TCameraWrapperBase' in 'CameraWrapperT' to create a full wrapper class e.g., 'CameraWrapperT<T, CameraWrapperBasePinholeT<T>>'.
1073 * @tparam T The data type of a scalar, 'float' or 'double'
1074 * @ingroup math
1075 */
1076template <typename T>
1078{
1079 public:
1080
1081 /**
1082 * Definition of the actual camera object wrapped by this class.
1083 */
1085
1086 /**
1087 * Definition of the parent WrappedCamera class using this base class.
1088 */
1090
1091 public:
1092
1093 /**
1094 * Creates a new CameraWrapperBasePinholeT object wrapping the actual camera model.
1095 * @param actualCamera The actual camera object to be wrapped
1096 */
1098
1099 /**
1100 * Creates a new CameraWrapperBasePinholeT object wrapping the actual camera model.
1101 * @param actualCamera The actual camera object to be wrapped
1102 */
1104
1105 /**
1106 * Returns the actual camera object wrapped in this class.
1107 * @return The wrapped camera object
1108 */
1109 inline const ActualCamera& actualCamera() const;
1110
1111 /**
1112 * Returns the width of the camera image.
1113 * @see AnyCameraT::width().
1114 */
1115 inline unsigned int width() const;
1116
1117 /**
1118 * Returns the height of the camera image.
1119 * @see AnyCameraT::height().
1120 */
1121 inline unsigned int height() const;
1122
1123 /**
1124 * Returns the x-value of the principal point of the camera image in the pixel domain.
1125 * @see AnyCameraT::principalPointX().
1126 */
1127 inline T principalPointX() const;
1128
1129 /**
1130 * Returns the y-value of the principal point of the camera image in the pixel domain.
1131 * @see AnyCameraT::principalPointY().
1132 */
1133 inline T principalPointY() const;
1134
1135 /**
1136 * Returns the horizontal focal length parameter.
1137 * @see AnyCameraT::focalLengthX().
1138 */
1139 inline T focalLengthX() const;
1140
1141 /**
1142 * Returns the vertical focal length parameter.
1143 * @see AnyCameraT::focalLengthY().
1144 */
1145 inline T focalLengthY() const;
1146
1147 /**
1148 * Returns the inverse horizontal focal length parameter.
1149 * @see AnyCameraT::inverseFocalLengthX().
1150 */
1151 inline T inverseFocalLengthX() const;
1152
1153 /**
1154 * Returns the inverse vertical focal length parameter.
1155 * @see AnyCameraT::inverseFocalLengthY().
1156 */
1157 inline T inverseFocalLengthY() const;
1158
1159 /**
1160 * Projects a 3D object point into the camera frame.
1161 * @see AnyCameraT::projectToImageIF().
1162 */
1163 inline VectorT2<T> projectToImageIF(const VectorT3<T>& objectPoint) const;
1164
1165 /**
1166 * Projects a 3D object point into the camera frame.
1167 * @see AnyCameraT::projectToImageIF().
1168 */
1169 inline VectorT2<T> projectToImageIF(const HomogenousMatrixT4<T>& flippedCamera_T_world, const VectorT3<T>& objectPoint) const;
1170
1171 /**
1172 * Projects several 3D object points into the camera frame at once.
1173 * @see AnyCameraT::projectToImageIF().
1174 */
1175 inline void projectToImageIF(const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const;
1176
1177 /**
1178 * Projects several 3D object points into the camera frame at once.
1179 * @see AnyCameraT::projectToImageIF().
1180 */
1181 inline void projectToImageIF(const HomogenousMatrixT4<T>& flippedCamera_T_world, const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const;
1182
1183 /**
1184 * Returns a vector starting at the camera's center and intersecting a given 2D point in the image.
1185 * @see AnyCameraT::vectorIF().
1186 */
1187 inline VectorT3<T> vectorIF(const VectorT2<T>& distortedImagePoint, const bool makeUnitVector) const;
1188
1189 /**
1190 * Returns vectors starting at the camera's center and intersecting a given 2D points in the image.
1191 * @see AnyCameraT::vectorIF().
1192 */
1193 inline void vectorIF(const VectorT2<T>* distortedImagePoint, const size_t size, VectorT3<T>* vectors, const bool makeUnitVector) const;
1194
1195 /**
1196 * Calculates the 2x3 jacobian matrix for the 3D object point projection into the camera frame.
1197 * @see AnyCameraT::pointJacobian2x3IF().
1198 */
1199 inline void pointJacobian2x3IF(const VectorT3<T>& flippedCameraObjectPoint, T* jx, T* jy) const;
1200
1201 /**
1202 * Returns whether two camera objects are identical up to a given epsilon.
1203 * @see AnyCameraT::isEqual().
1204 */
1205 inline bool isEqual(const CameraWrapperBasePinholeT<T>& basePinhole, const T eps = NumericT<T>::eps()) const;
1206
1207 /**
1208 * Returns whether this camera is valid.
1209 * @see AnyCameraT::isValid().
1210 */
1211 inline bool isValid() const;
1212
1213 /**
1214 * Returns a copy of the actual camera object.
1215 * @return New instance of the actual camera object used in this wrapper.
1216 * @tparam U The scalar data type of the resulting cloned object, either 'float' or 'double'
1217 */
1218 template <typename U>
1219 inline std::unique_ptr<AnyCameraT<U>> clone(const unsigned int width = 0u, const unsigned int height = 0u) const;
1220
1221 /**
1222 * Returns the type of this camera.
1223 * @see AnyCameraT::anyCameraType().
1224 */
1225 static inline AnyCameraType anyCameraType();
1226
1227 /**
1228 * Returns the name of this camera.
1229 * @see AnyCameraT::name().
1230 */
1231 static inline std::string name();
1232
1233 protected:
1234
1235 /// The actual pinhole camera.
1237};
1238
1239/**
1240 * This class implements the base wrapper around Ocean's fisheye camera profile.
1241 * The class can be used as 'TCameraWrapperBase' in 'CameraWrapperT' to create a full wrapper class e.g., 'CameraWrapperT<T, CameraWrapperBaseFisheyeT<T>>'.
1242 * @tparam T The data type of a scalar, 'float' or 'double'
1243 * @ingroup math
1244 */
1245template <typename T>
1247{
1248 public:
1249
1250 /**
1251 * Definition of the actual camera object wrapped by this class.
1252 */
1254
1255 /**
1256 * Definition of the parent WrappedCamera class using this base class.
1257 */
1259
1260 public:
1261
1262 /**
1263 * Creates a new CameraWrapperBaseFisheyeT object wrapping the actual camera model.
1264 * @param actualCamera The actual camera object to be wrapped
1265 */
1267
1268 /**
1269 * Creates a new CameraWrapperBaseFisheyeT object wrapping the actual camera model.
1270 * @param actualCamera The actual camera object to be wrapped
1271 */
1273
1274 /**
1275 * Returns the actual camera object wrapped in this class.
1276 * @return The wrapped camera object
1277 */
1278 inline const ActualCamera& actualCamera() const;
1279
1280 /**
1281 * Returns the width of the camera image.
1282 * @see AnyCameraT::width().
1283 */
1284 inline unsigned int width() const;
1285
1286 /**
1287 * Returns the height of the camera image.
1288 * @see AnyCameraT::height().
1289 */
1290 inline unsigned int height() const;
1291
1292 /**
1293 * Returns the coordinate of the principal point of the camera image in the pixel domain.
1294 * @see AnyCameraT::principalPoint().
1295 */
1296 inline VectorT2<T> principalPoint() const;
1297
1298 /**
1299 * Returns the x-value of the principal point of the camera image in the pixel domain.
1300 * @see AnyCameraT::principalPointX().
1301 */
1302 inline T principalPointX() const;
1303
1304 /**
1305 * Returns the y-value of the principal point of the camera image in the pixel domain.
1306 * @see AnyCameraT::principalPointY().
1307 */
1308 inline T principalPointY() const;
1309
1310 /**
1311 * Returns the horizontal focal length parameter.
1312 * @see AnyCameraT::focalLengthX().
1313 */
1314 inline T focalLengthX() const;
1315
1316 /**
1317 * Returns the vertical focal length parameter.
1318 * @see AnyCameraT::focalLengthY().
1319 */
1320 inline T focalLengthY() const;
1321
1322 /**
1323 * Returns the inverse horizontal focal length parameter.
1324 * @see AnyCameraT::inverseFocalLengthX().
1325 */
1326 inline T inverseFocalLengthX() const;
1327
1328 /**
1329 * Returns the inverse vertical focal length parameter.
1330 * @see AnyCameraT::inverseFocalLengthY().
1331 */
1332 inline T inverseFocalLengthY() const;
1333
1334 /**
1335 * Projects a 3D object point into the camera frame.
1336 * @see AnyCameraT::projectToImageIF().
1337 */
1338 inline VectorT2<T> projectToImageIF(const VectorT3<T>& objectPoint) const;
1339
1340 /**
1341 * Projects a 3D object point into the camera frame.
1342 * @see AnyCameraT::projectToImageIF().
1343 */
1344 inline VectorT2<T> projectToImageIF(const HomogenousMatrixT4<T>& flippedCamera_T_world, const VectorT3<T>& objectPoint) const;
1345
1346 /**
1347 * Projects several 3D object points into the camera frame at once.
1348 * @see AnyCameraT::projectToImageIF().
1349 */
1350 inline void projectToImageIF(const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const;
1351
1352 /**
1353 * Projects several 3D object points into the camera frame at once.
1354 * @see AnyCameraT::projectToImageIF().
1355 */
1356 inline void projectToImageIF(const HomogenousMatrixT4<T>& flippedCamera_T_world, const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const;
1357
1358 /**
1359 * Returns a vector starting at the camera's center and intersecting a given 2D point in the image.
1360 * @see AnyCameraT::vectorIF().
1361 */
1362 inline VectorT3<T> vectorIF(const VectorT2<T>& distortedImagePoint, const bool makeUnitVector) const;
1363
1364 /**
1365 * Returns vectors starting at the camera's center and intersecting a given 2D points in the image.
1366 * @see AnyCameraT::vectorIF().
1367 */
1368 inline void vectorIF(const VectorT2<T>* distortedImagePoint, const size_t size, VectorT3<T>* vectors, const bool makeUnitVector) const;
1369
1370 /**
1371 * Calculates the 2x3 jacobian matrix for the 3D object point projection into the camera frame.
1372 * @see AnyCameraT::pointJacobian2x3IF().
1373 */
1374 inline void pointJacobian2x3IF(const VectorT3<T>& flippedCameraObjectPoint, T* jx, T* jy) const;
1375
1376 /**
1377 * Returns whether two camera objects are identical up to a given epsilon.
1378 * @see AnyCameraT::isEqual().
1379 */
1380 inline bool isEqual(const CameraWrapperBaseFisheyeT<T>& baseFisheye, const T eps = NumericT<T>::eps()) const;
1381
1382 /**
1383 * Returns whether this camera is valid.
1384 * @return True, if so
1385 */
1386 inline bool isValid() const;
1387
1388 /**
1389 * Returns a copy of the actual camera object.
1390 * @return New instance of the actual camera object used in this wrapper.
1391 */
1392 template <typename U>
1393 inline std::unique_ptr<AnyCameraT<U>> clone(const unsigned int width = 0u, const unsigned int height = 0u) const;
1394
1395 /**
1396 * Returns the type of this camera.
1397 * @see AnyCamera::anyCameraType().
1398 */
1399 static inline AnyCameraType anyCameraType();
1400
1401 /**
1402 * Returns the name of this camera.
1403 * @see AnyCamera::name().
1404 */
1405 static inline std::string name();
1406
1407 protected:
1408
1409 /// The actual fisheye camera object.
1411};
1412
1413/**
1414 * This class implements invalid camera profiles, e.g. when no intrinsic information is available.
1415 * @tparam T The data type of a 'Scalar', 'float' or 'double'
1416 * @ingroup math
1417 */
1418template <typename T>
1420{
1421 public:
1422
1423 /**
1424 * Creates an invalid camera
1425 * @param reason The reason why no valid camera is available, must be valid
1426 */
1427 explicit InvalidCameraT(const std::string& reason);
1428
1429 /**
1430 * Returns the reason of this invalid camera
1431 * @return The reason
1432 */
1433 const std::string& reason() const;
1434
1435 protected:
1436
1437 /// The reason why no valid camera is available.
1438 std::string reason_;
1439};
1440
1441/**
1442 * Definition of an invalid camera object based with element precision 'Scalar'.
1443 * @see AnyCameraT, AnyCameraInvalidT.
1444 * @ingroup math
1445 */
1447
1448/**
1449 * Definition of an invalid camera object based with element precision 'double'.
1450 * @see AnyCameraT, AnyCameraInvalidT.
1451 * @ingroup math
1452 */
1454
1455/**
1456 * Definition of an invalid camera object based with element precision 'float'.
1457 * @see AnyCameraT, AnyCameraInvalidT.
1458 * @ingroup math
1459 */
1461
1462/**
1463 * This class implements the base wrapper around an invalid camera profile.
1464 * The class can be used as 'TCameraWrapperBase' in 'CameraWrapperT' to create a full wrapper class e.g., 'CameraWrapperT<T, CameraWrapperBaseInvalidT<T>>'.
1465 * @tparam T The data type of a scalar, 'float' or 'double'
1466 * @ingroup math
1467 */
1468template <typename T>
1470{
1471 public:
1472
1473 /**
1474 * Definition of the actual camera object wrapped by this class.
1475 */
1477
1478 /**
1479 * Definition of the parent WrappedCamera class using this base class.
1480 */
1482
1483 public:
1484
1485 /**
1486 * Creates a new CameraWrapperBaseInvalidT object wrapping the actual camera model.
1487 * @param actualCamera The actual camera object to be wrapped
1488 */
1490
1491 /**
1492 * Creates a new CameraWrapperBaseInvalidT object wrapping the actual camera model.
1493 * @param actualCamera The actual camera object to be wrapped
1494 */
1496
1497 /**
1498 * Returns the actual camera object wrapped in this class.
1499 * @return The wrapped camera object
1500 */
1501 inline const ActualCamera& actualCamera() const;
1502
1503 /**
1504 * Returns the width of the camera image.
1505 * @see AnyCameraT::width().
1506 */
1507 inline unsigned int width() const;
1508
1509 /**
1510 * Returns the height of the camera image.
1511 * @see AnyCameraT::height().
1512 */
1513 inline unsigned int height() const;
1514
1515 /**
1516 * Returns the coordinate of the principal point of the camera image in the pixel domain.
1517 * @see AnyCameraT::principalPoint().
1518 */
1519 inline VectorT2<T> principalPoint() const;
1520
1521 /**
1522 * Returns the x-value of the principal point of the camera image in the pixel domain.
1523 * @see AnyCameraT::principalPointX().
1524 */
1525 inline T principalPointX() const;
1526
1527 /**
1528 * Returns the y-value of the principal point of the camera image in the pixel domain.
1529 * @see AnyCameraT::principalPointY().
1530 */
1531 inline T principalPointY() const;
1532
1533 /**
1534 * Returns the horizontal focal length parameter.
1535 * @see AnyCameraT::focalLengthX().
1536 */
1537 inline T focalLengthX() const;
1538
1539 /**
1540 * Returns the vertical focal length parameter.
1541 * @see AnyCameraT::focalLengthY().
1542 */
1543 inline T focalLengthY() const;
1544
1545 /**
1546 * Returns the inverse horizontal focal length parameter.
1547 * @see AnyCameraT::inverseFocalLengthX().
1548 */
1549 inline T inverseFocalLengthX() const;
1550
1551 /**
1552 * Returns the inverse vertical focal length parameter.
1553 * @see AnyCameraT::inverseFocalLengthY().
1554 */
1555 inline T inverseFocalLengthY() const;
1556
1557 /**
1558 * Projects a 3D object point into the camera frame.
1559 * @see AnyCameraT::projectToImageIF().
1560 */
1561 inline VectorT2<T> projectToImageIF(const VectorT3<T>& objectPoint) const;
1562
1563 /**
1564 * Projects a 3D object point into the camera frame.
1565 * @see AnyCameraT::projectToImageIF().
1566 */
1567 inline VectorT2<T> projectToImageIF(const HomogenousMatrixT4<T>& flippedCamera_T_world, const VectorT3<T>& objectPoint) const;
1568
1569 /**
1570 * Projects several 3D object points into the camera frame at once.
1571 * @see AnyCameraT::projectToImageIF().
1572 */
1573 inline void projectToImageIF(const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const;
1574
1575 /**
1576 * Projects several 3D object points into the camera frame at once.
1577 * @see AnyCameraT::projectToImageIF().
1578 */
1579 inline void projectToImageIF(const HomogenousMatrixT4<T>& flippedCamera_T_world, const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const;
1580
1581 /**
1582 * Returns a vector starting at the camera's center and intersecting a given 2D point in the image.
1583 * @see AnyCameraT::vectorIF().
1584 */
1585 inline VectorT3<T> vectorIF(const VectorT2<T>& distortedImagePoint, const bool makeUnitVector) const;
1586
1587 /**
1588 * Returns vectors starting at the camera's center and intersecting a given 2D points in the image.
1589 * @see AnyCameraT::vectorIF().
1590 */
1591 inline void vectorIF(const VectorT2<T>* distortedImagePoint, const size_t size, VectorT3<T>* vectors, const bool makeUnitVector) const;
1592
1593 /**
1594 * Calculates the 2x3 jacobian matrix for the 3D object point projection into the camera frame.
1595 * @see AnyCameraT::pointJacobian2x3IF().
1596 */
1597 inline void pointJacobian2x3IF(const VectorT3<T>& flippedCameraObjectPoint, T* jx, T* jy) const;
1598
1599 /**
1600 * Returns whether two camera objects are identical up to a given epsilon.
1601 * @see AnyCameraT::isEqual().
1602 */
1603 inline bool isEqual(const CameraWrapperBaseInvalidT<T>& baseInvalid, const T eps = NumericT<T>::eps()) const;
1604
1605 /**
1606 * Returns whether this camera is valid.
1607 * @return True, if so
1608 */
1609 inline bool isValid() const;
1610
1611 /**
1612 * Returns a copy of the actual camera object.
1613 * @return New instance of the actual camera object used in this wrapper.
1614 */
1615 template <typename U>
1616 inline std::unique_ptr<AnyCameraT<U>> clone(const unsigned int width = 0u, const unsigned int height = 0u) const;
1617
1618 /**
1619 * Returns the type of this camera.
1620 * @see AnyCamera::anyCameraType().
1621 */
1622 static inline AnyCameraType anyCameraType();
1623
1624 /**
1625 * Returns the name of this camera.
1626 * @see AnyCamera::name().
1627 */
1628 static inline std::string name();
1629
1630 protected:
1631
1632 /// The actual invalid camera.
1634};
1635
1636/**
1637 * Definition of an AnyCamera object based on Ocean's pinhole camera class with template parameter to define the element precision.
1638 * @tparam T The scalar data type
1639 * @see AnyCameraT, CameraWrapperBasePinholeT, AnyCameraPinhole, AnyCameraPinholeD, AnyCameraPinholeF.
1640 * @ingroup math
1641 */
1642template <typename T>
1644
1645/**
1646 * Definition of an AnyCamera object based on Ocean's pinhole camera class with element precision 'Scalar'.
1647 * @see AnyCameraT, AnyCameraPinholeT.
1648 * @ingroup math
1649 */
1651
1652/**
1653 * Definition of an AnyCamera object based on Ocean's pinhole camera class with element precision 'double'.
1654 * @see AnyCameraT, AnyCameraPinholeT.
1655 * @ingroup math
1656 */
1658
1659/**
1660 * Definition of an AnyCamera object based on Ocean's pinhole camera class with element precision 'float'.
1661 * @see AnyCameraT, AnyCameraPinholeT.
1662 * @ingroup math
1663 */
1665
1666/**
1667 * Definition of an AnyCamera object based on Ocean's fisheye camera class with template parameter to define the element precision.
1668 * @tparam T The scalar data type
1669 * @see AnyCameraT, CameraWrapperBaseFisheyeT, AnyCameraFisheye, AnyCameraFisheyeD, AnyCameraFisheyeF.
1670 * @ingroup math
1671 */
1672template <typename T>
1674
1675/**
1676 * Definition of an AnyCamera object based on Ocean's fisheye camera class with element precision 'Scalar'.
1677 * @see AnyCameraT, AnyCameraFisheyeT.
1678 * @ingroup math
1679 */
1681
1682/**
1683 * Definition of an AnyCamera object based on Ocean's fisheye camera class with element precision 'double'.
1684 * @see AnyCameraT, AnyCameraFisheyeT.
1685 * @ingroup math
1686 */
1688
1689/**
1690 * Definition of an AnyCamera object based on Ocean's fisheye camera class with element precision 'float'.
1691 * @see AnyCameraT, AnyCameraFisheyeT.
1692 * @ingroup math
1693 */
1695
1696/**
1697 * Definition of an AnyCamera object based on an invalid (by design) camera with template parameter to define the element precision.
1698 * @tparam T The scalar data type
1699 * @see AnyCameraT, CameraWrapperBaseFisheyeT, AnyCameraInvalid, AnyCameraInvalidD, AnyCameraInvalidF.
1700 * @ingroup math
1701 */
1702template <typename T>
1704
1705/**
1706 * Definition of an AnyCamera object based on an invalid (by design) camera with element precision 'Scalar'.
1707 * @see AnyCameraT, AnyCameraInvalidT.
1708 * @ingroup math
1709 */
1711
1712/**
1713 * Definition of an AnyCamera object based on an invalid (by design) camera with element precision 'double'.
1714 * @see AnyCameraT, AnyCameraInvalidT.
1715 * @ingroup math
1716 */
1718
1719/**
1720 * Definition of an AnyCamera object based on an invalid (by design) camera with element precision 'float'.
1721 * @see AnyCameraT, AnyCameraInvalidT.
1722 * @ingroup math
1723 */
1725
1726template <typename T>
1727AnyCameraClipperT<T>::AnyCameraClipperT(const SharedAnyCameraT<T>& camera, const size_t segmentSteps)
1728{
1729 update(camera, segmentSteps);
1730}
1731
1732template <typename T>
1733bool AnyCameraClipperT<T>::projectToImageIF(const HomogenousMatrixT4<T>& flippedCamera_T_world, const VectorT3<T>& objectPoint, VectorT2<T>* imagePoint) const
1734{
1735 ocean_assert(camera_ != nullptr);
1736 ocean_assert(camera_->isValid());
1737 ocean_assert(flippedCamera_T_world.isValid());
1738
1739 const VectorT3<T> cameraObjectPointIF = flippedCamera_T_world * objectPoint;
1740
1741 if (cameraObjectPointIF.z() <= NumericT<T>::eps())
1742 {
1743 return false;
1744 }
1745
1746 const T invZ = T(1) / cameraObjectPointIF.z();
1747
1748 const VectorT2<T> normalizedImagePoint(cameraObjectPointIF.x() * invZ, cameraObjectPointIF.y() * invZ);
1749
1750 if (!isInside(cameraBoundarySegments_, normalizedImagePoint))
1751 {
1752 return false;
1753 }
1754
1755 if (imagePoint != nullptr)
1756 {
1757 *imagePoint = camera_->projectToImageIF(cameraObjectPointIF);
1758
1759 ocean_assert_accuracy(camera_->isInside(*imagePoint, T(std::max(camera_->width(), camera_->height())) * T(-0.1)));
1760 }
1761
1762 return true;
1763}
1764
1765template <typename T>
1767{
1768 return camera_;
1769}
1770
1771template <typename T>
1772inline unsigned int AnyCameraClipperT<T>::width() const
1773{
1774 if (camera_)
1775 {
1776 return camera_->width();
1777 }
1778
1779 return 0u;
1780}
1781
1782template <typename T>
1783inline unsigned int AnyCameraClipperT<T>::height() const
1784{
1785 if (camera_)
1786 {
1787 return camera_->height();
1788 }
1789
1790 return 0u;
1791}
1792
1793template <typename T>
1794void AnyCameraClipperT<T>::update(const SharedAnyCameraT<T>& camera, const size_t segmentSteps)
1795{
1796 ocean_assert(camera != nullptr && camera->isValid() && segmentSteps >= 1);
1797 if (camera == nullptr || !camera->isValid() || segmentSteps == 0)
1798 {
1799 return;
1800 }
1801
1802 if (camera_ && camera_->isEqual(*camera))
1803 {
1804 ocean_assert(isValid());
1805 return;
1806 }
1807
1808 cameraBoundarySegments_.clear();
1809
1810 if (determineCameraBoundary(*camera, cameraBoundarySegments_, segmentSteps))
1811 {
1812 camera_ = camera;
1813 }
1814 else
1815 {
1816 camera_ = nullptr;
1817 cameraBoundarySegments_.clear();
1818 }
1819
1820 ocean_assert(isValid());
1821}
1822
1823template <typename T>
1824void AnyCameraClipperT<T>::update(const AnyCameraT<T>& camera, const size_t segmentSteps)
1825{
1826 ocean_assert(camera.isValid() && segmentSteps >= 1);
1827 if (!camera.isValid() || segmentSteps == 0)
1828 {
1829 return;
1830 }
1831
1832 if (camera_ && camera_->isEqual(camera))
1833 {
1834 ocean_assert(isValid());
1835 return;
1836 }
1837
1838 cameraBoundarySegments_.clear();
1839
1840 if (determineCameraBoundary(camera, cameraBoundarySegments_, segmentSteps))
1841 {
1842 camera_ = camera.clone();
1843 }
1844 else
1845 {
1846 camera_ = nullptr;
1847 cameraBoundarySegments_.clear();
1848 }
1849
1850 ocean_assert(isValid());
1851}
1852
1853template <typename T>
1855{
1856 return cameraBoundarySegments_;
1857}
1858
1859template <typename T>
1861{
1862 ocean_assert(camera_ == nullptr || !cameraBoundarySegments_.empty());
1863
1864 return camera_ != nullptr;
1865}
1866
1867template <typename T>
1868bool AnyCameraClipperT<T>::determineCameraBoundary(const AnyCameraT<T>& camera, FiniteLinesT2<T>& cameraBoundarySegments, const size_t segmentSteps)
1869{
1870 ocean_assert(camera.isValid());
1871 if (!camera.isValid())
1872 {
1873 return false;
1874 }
1875
1876 ocean_assert(segmentSteps >= 1);
1877 if (segmentSteps < 1)
1878 {
1879 return false;
1880 }
1881
1882 constexpr unsigned int border = 0u;
1883
1884 const std::array<VectorT2<T>, 4> corners =
1885 {
1886 VectorT2<T>(T(border), T(border)),
1887 VectorT2<T>(T(border), T(camera.height() - border - 1u)),
1888 VectorT2<T>(T(camera.width() - border - 1u), T(camera.height() - border - 1u)),
1889 VectorT2<T>(T(camera.width() - border - 1u), T(border))
1890 };
1891
1892 const VectorT2<T> principalPoint = camera.principalPoint();
1893
1894 constexpr T maximalSqrDistance = NumericT<T>::sqr(T(1));
1895
1896 // let's first check whether the camera model is precise enough at the principal point
1897
1898 const VectorT3<T> principalObjectPoint = camera.vectorIF(principalPoint, false /*makeUnitVector*/);
1899
1900 const T sqrProjectionErrorPrincipalPoint = camera.projectToImageIF(principalObjectPoint).sqrDistance(principalPoint);
1901
1902 if (sqrProjectionErrorPrincipalPoint > maximalSqrDistance)
1903 {
1904 ocean_assert(false && "The camera model is not precise enough");
1905 return false;
1906 }
1907
1908 VectorsT2<T> normalizedImagePoints;
1909 normalizedImagePoints.reserve(corners.size() * segmentSteps);
1910
1911 for (size_t nCorner = 0; nCorner < corners.size(); ++nCorner)
1912 {
1913 const VectorT2<T>& corner0 = corners[nCorner];
1914 const VectorT2<T>& corner1 = corners[(nCorner + 1u) % corners.size()];
1915
1916 for (size_t nStep = 0; nStep < segmentSteps; ++nStep)
1917 {
1918 const T factor = T(nStep) / T(segmentSteps);
1919
1920 const VectorT2<T> distortedImagePoint = corner0 * (T(1) - factor) + corner1 * factor;
1921
1922 const VectorT2<T> offsetTowardsPrincipalPoint = (principalPoint - distortedImagePoint).normalizedOrZero() * T(1.0); // one pixel towards the principal point
1923
1924 VectorT3<T> objectPoint = VectorT3<T>::minValue();
1925
1926 if (isValidForPoint(camera, distortedImagePoint, maximalSqrDistance, 3u))
1927 {
1928 objectPoint = camera.vectorIF(distortedImagePoint, false /*makeUnitVector*/);
1929 }
1930 else
1931 {
1932 // 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
1933 // so let's try to find the point closest to the image boundary which is precise enough
1934
1935 // | image boundary ideal point principal point |
1936
1937 VectorT2<T> boundaryImagePoint = distortedImagePoint;
1938 VectorT2<T> centerImagePoint = principalPoint;
1939
1940 objectPoint = principalObjectPoint;
1941
1942 constexpr unsigned int iterations = 20u;
1943
1944 for (unsigned int nIteration = 0u; nIteration < iterations; ++nIteration)
1945 {
1946 if (boundaryImagePoint.sqrDistance(centerImagePoint) <= maximalSqrDistance)
1947 {
1948 break;
1949 }
1950
1951 const VectorT2<T> middleImagePoint = (boundaryImagePoint + centerImagePoint) * T(0.5);
1952
1953 const VectorT3<T> middleObjectPoint = camera.vectorIF(middleImagePoint, false /*makeUnitVector*/);
1954 const VectorT2<T> projectedMiddleObjectPoint = camera.projectToImageIF(middleObjectPoint);
1955
1956 const T sqrMiddleDistance = middleImagePoint.sqrDistance(projectedMiddleObjectPoint);
1957
1958 if (sqrMiddleDistance <= maximalSqrDistance)
1959 {
1960 centerImagePoint = middleImagePoint;
1961
1962 objectPoint = camera.vectorIF(middleImagePoint + offsetTowardsPrincipalPoint, false /*makeUnitVector*/);
1963 }
1964 else
1965 {
1966 boundaryImagePoint = middleImagePoint;
1967 }
1968 }
1969 }
1970
1971 if (objectPoint != VectorT3<T>::minValue())
1972 {
1973 ocean_assert(objectPoint.z() >= NumericT<T>::eps());
1974 const VectorT2<T> normalizedImagePoint = objectPoint.xy() / objectPoint.z();
1975
1976 normalizedImagePoints.emplace_back(normalizedImagePoint.x(), normalizedImagePoint.y());
1977 }
1978 }
1979 }
1980
1981 ocean_assert(normalizedImagePoints.size() >= 3);
1982
1983 ocean_assert(cameraBoundarySegments.empty());
1984 cameraBoundarySegments.clear();
1985
1986 cameraBoundarySegments.reserve(normalizedImagePoints.size());
1987
1988 for (size_t n = 1; n < normalizedImagePoints.size(); ++n)
1989 {
1990 cameraBoundarySegments.emplace_back(normalizedImagePoints[n - 1], normalizedImagePoints[n]);
1991 }
1992
1993 cameraBoundarySegments.emplace_back(normalizedImagePoints.back(), normalizedImagePoints.front());
1994
1995 return true;
1996}
1997
1998template <typename T>
1999bool AnyCameraClipperT<T>::isInside(const FiniteLinesT2<T>& cameraBoundarySegments, const VectorT2<T>& normalizedImagePoint)
2000{
2001 ocean_assert(cameraBoundarySegments.size() >= 3);
2002
2003 size_t counter = 0;
2004
2005 for (const FiniteLineT2<T>& cameraBoundarySegment : cameraBoundarySegments)
2006 {
2007 // let's check whether the point is above or below the line segment
2008
2009 const bool segmentTopDown = cameraBoundarySegment.point0().y() < cameraBoundarySegment.point1().y();
2010
2011 if (segmentTopDown)
2012 {
2013 if (cameraBoundarySegment.point1().y() < normalizedImagePoint.y() || normalizedImagePoint.y() < cameraBoundarySegment.point0().y())
2014 {
2015 continue;
2016 }
2017 }
2018 else
2019 {
2020 if (cameraBoundarySegment.point0().y() < normalizedImagePoint.y() || normalizedImagePoint.y() < cameraBoundarySegment.point1().y())
2021 {
2022 continue;
2023 }
2024 }
2025
2026 if (cameraBoundarySegment.isOnLine(normalizedImagePoint))
2027 {
2028 // the point is on the line segment, so we know the point is inside the camera boundary
2029
2030 return true;
2031 }
2032
2033 if (cameraBoundarySegment.isLeftOfLine(normalizedImagePoint) == segmentTopDown)
2034 {
2035 // the point is on the left side of the line segment, we only count points on the right side
2036 continue;
2037 }
2038
2039 ++counter;
2040 }
2041
2042 return counter % 2 == 1;
2043}
2044
2045template <typename T>
2046bool AnyCameraClipperT<T>::isValidForPoint(const AnyCameraT<T>& camera, const VectorT2<T>& imagePoint, const T maximalReprojectionError, const unsigned int additionalChecksTowardsPrincipalPoint)
2047{
2048 ocean_assert(camera.isValid());
2049 ocean_assert(camera.isInside(imagePoint, T(-1)));
2050 ocean_assert(maximalReprojectionError >= T(0));
2051 ocean_assert(additionalChecksTowardsPrincipalPoint >= 1u);
2052
2053 const VectorT3<T> objectPoint = camera.vectorIF(imagePoint, false /*makeUnitVector*/);
2054 const VectorT2<T> projectedObjectPoint = camera.projectToImageIF(objectPoint);
2055
2056 if (imagePoint.sqrDistance(projectedObjectPoint) > NumericT<T>::sqr(maximalReprojectionError))
2057 {
2058 // simple case, the point does not re-project back to the same image point
2059 return false;
2060 }
2061
2062 const VectorT2<T> principalPoint = camera.principalPoint();
2063
2064 const VectorT2<T> direction = (principalPoint - imagePoint).normalizedOrZero();
2065
2066 if (direction.isNull())
2067 {
2068 // we check the principal point
2069 return true;
2070 }
2071
2072 for (unsigned int n = 0u; n < std::min(additionalChecksTowardsPrincipalPoint, 10u); ++n)
2073 {
2074 const VectorT2<T> additionalImagePoint = imagePoint + direction * T(n + 1u);
2075
2076 const VectorT3<T> additionalObjectPoint = camera.vectorIF(additionalImagePoint, false /*makeUnitVector*/);
2077 const VectorT2<T> additionalProjectedObjectPoint = camera.projectToImageIF(additionalObjectPoint);
2078
2079 if (additionalImagePoint.sqrDistance(additionalProjectedObjectPoint) > NumericT<T>::sqr(maximalReprojectionError))
2080 {
2081 return false;
2082 }
2083 }
2084
2085 return true;
2086}
2087
2088template <>
2089template <>
2090inline std::shared_ptr<AnyCameraT<float>> AnyCameraT<float>::convert(const std::shared_ptr<AnyCameraT<double>>& anyCamera)
2091{
2092 if (anyCamera)
2093 {
2094 return anyCamera->cloneToFloat();
2095 }
2096
2097 return nullptr;
2098}
2099
2100template <>
2101template <>
2102inline std::shared_ptr<AnyCameraT<double>> AnyCameraT<double>::convert(const std::shared_ptr<AnyCameraT<float>>& anyCamera)
2103{
2104 if (anyCamera)
2105 {
2106 return anyCamera->cloneToDouble();
2107 }
2108
2109 return nullptr;
2110}
2111
2112template <typename T>
2113template <typename U>
2114std::shared_ptr<AnyCameraT<T>> AnyCameraT<T>::convert(const std::shared_ptr<AnyCameraT<U>>& anyCamera)
2115{
2116 static_assert(std::is_same<T, U>::value, "Invalid data types!");
2117
2118 return anyCamera;
2119}
2120
2121template <typename T, typename TCameraWrapper>
2123 TCameraWrapper(std::move(actualCamera))
2124{
2125 // nothing to do here
2126}
2127
2128template <typename T, typename TCameraWrapper>
2130 TCameraWrapper(actualCamera)
2131{
2132 // nothing to do here
2133}
2134
2135template <typename T, typename TCameraWrapper>
2137{
2138 return TCameraWrapper::anyCameraType();
2139}
2140
2141template <typename T, typename TCameraWrapper>
2143{
2144 return TCameraWrapper::name();
2145}
2146
2147template <typename T, typename TCameraWrapper>
2148std::unique_ptr<AnyCameraT<T>> AnyCameraWrappingT<T, TCameraWrapper>::clone(const unsigned int width, const unsigned int height) const
2149{
2150 return TCameraWrapper::template clone<T>(width, height);
2151}
2152
2153template <typename T, typename TCameraWrapper>
2154std::unique_ptr<AnyCameraT<float>> AnyCameraWrappingT<T, TCameraWrapper>::cloneToFloat(const unsigned int width, const unsigned int height) const
2155{
2156 return TCameraWrapper::template clone<float>(width, height);
2157}
2158
2159template <typename T, typename TCameraWrapper>
2160std::unique_ptr<AnyCameraT<double>> AnyCameraWrappingT<T, TCameraWrapper>::cloneToDouble(const unsigned int width, const unsigned int height) const
2161{
2162 return TCameraWrapper::template clone<double>(width, height);
2163}
2164
2165template <typename T, typename TCameraWrapper>
2167{
2168 return TCameraWrapper::width();
2169}
2170
2171template <typename T, typename TCameraWrapper>
2173{
2174 return TCameraWrapper::height();
2175}
2176
2177template <typename T, typename TCameraWrapper>
2179{
2180 return TCameraWrapper::principalPoint();
2181}
2182
2183template <typename T, typename TCameraWrapper>
2185{
2186 return TCameraWrapper::principalPointX();
2187}
2188
2189template <typename T, typename TCameraWrapper>
2191{
2192 return TCameraWrapper::principalPointY();
2193}
2194
2195template <typename T, typename TCameraWrapper>
2197{
2198 return TCameraWrapper::focalLengthX();
2199}
2200
2201template <typename T, typename TCameraWrapper>
2203{
2204 return TCameraWrapper::focalLengthY();
2205}
2206
2207template <typename T, typename TCameraWrapper>
2209{
2210 return TCameraWrapper::inverseFocalLengthX();
2211}
2212
2213template <typename T, typename TCameraWrapper>
2215{
2216 return TCameraWrapper::inverseFocalLengthY();
2217}
2218
2219template <typename T, typename TCameraWrapper>
2221{
2222 return TCameraWrapper::fovX();
2223}
2224
2225template <typename T, typename TCameraWrapper>
2227{
2228 return TCameraWrapper::fovY();
2229}
2230
2231template <typename T, typename TCameraWrapper>
2232bool AnyCameraWrappingT<T, TCameraWrapper>::isInside(const VectorT2<T>& imagePoint, const T signedBorder) const
2233{
2234 return TCameraWrapper::isInside(imagePoint, signedBorder);
2235}
2236
2237template <typename T, typename TCameraWrapper>
2239{
2240 return TCameraWrapper::projectToImage(objectPoint);
2241}
2242
2243template <typename T, typename TCameraWrapper>
2245{
2246 return TCameraWrapper::projectToImage(world_T_camera, objectPoint);
2247}
2248
2249template <typename T, typename TCameraWrapper>
2251{
2252 return TCameraWrapper::projectToImageIF(objectPoint);
2253}
2254
2255template <typename T, typename TCameraWrapper>
2257{
2258 return TCameraWrapper::projectToImageIF(flippedCamera_T_world, objectPoint);
2259}
2260
2261template <typename T, typename TCameraWrapper>
2262void AnyCameraWrappingT<T, TCameraWrapper>::projectToImage(const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const
2263{
2264 return TCameraWrapper::projectToImage(objectPoints, size, imagePoints);
2265}
2266
2267template <typename T, typename TCameraWrapper>
2268void AnyCameraWrappingT<T, TCameraWrapper>::projectToImage(const HomogenousMatrixT4<T>& world_T_camera, const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const
2269{
2270 return TCameraWrapper::projectToImage(world_T_camera, objectPoints, size, imagePoints);
2271}
2272
2273template <typename T, typename TCameraWrapper>
2274void AnyCameraWrappingT<T, TCameraWrapper>::projectToImageIF(const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const
2275{
2276 return TCameraWrapper::projectToImageIF(objectPoints, size, imagePoints);
2277}
2278
2279template <typename T, typename TCameraWrapper>
2280void AnyCameraWrappingT<T, TCameraWrapper>::projectToImageIF(const HomogenousMatrixT4<T>& flippedCamera_T_world, const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const
2281{
2282 return TCameraWrapper::projectToImageIF(flippedCamera_T_world, objectPoints, size, imagePoints);
2283}
2284
2285template <typename T, typename TCameraWrapper>
2286VectorT3<T> AnyCameraWrappingT<T, TCameraWrapper>::vector(const VectorT2<T>& distortedImagePoint, const bool makeUnitVector) const
2287{
2288 return TCameraWrapper::vector(distortedImagePoint, makeUnitVector);
2289}
2290
2291template <typename T, typename TCameraWrapper>
2292void AnyCameraWrappingT<T, TCameraWrapper>::vector(const VectorT2<T>* distortedImagePoints, const size_t size, VectorT3<T>* vectors, const bool makeUnitVector) const
2293{
2294 return TCameraWrapper::vector(distortedImagePoints, size, vectors, makeUnitVector);
2295}
2296
2297template <typename T, typename TCameraWrapper>
2298VectorT3<T> AnyCameraWrappingT<T, TCameraWrapper>::vectorIF(const VectorT2<T>& distortedImagePoint, const bool makeUnitVector) const
2299{
2300 return TCameraWrapper::vectorIF(distortedImagePoint, makeUnitVector);
2301}
2302
2303template <typename T, typename TCameraWrapper>
2304void AnyCameraWrappingT<T, TCameraWrapper>::vectorIF(const VectorT2<T>* distortedImagePoints, const size_t size, VectorT3<T>* vectors, const bool makeUnitVector) const
2305{
2306 return TCameraWrapper::vectorIF(distortedImagePoints, size, vectors, makeUnitVector);
2307}
2308
2309template <typename T, typename TCameraWrapper>
2310LineT3<T> AnyCameraWrappingT<T, TCameraWrapper>::ray(const VectorT2<T>& distortedImagePoint, const HomogenousMatrixT4<T>& world_T_camera) const
2311{
2312 return TCameraWrapper::ray(distortedImagePoint, world_T_camera);
2313}
2314
2315template <typename T, typename TCameraWrapper>
2317{
2318 return TCameraWrapper::ray(distortedImagePoint);
2319}
2320
2321template <typename T, typename TCameraWrapper>
2322void AnyCameraWrappingT<T, TCameraWrapper>::pointJacobian2x3IF(const VectorT3<T>& flippedCameraObjectPoint, T* jx, T* jy) const
2323{
2324 return TCameraWrapper::pointJacobian2x3IF(flippedCameraObjectPoint, jx, jy);
2325}
2326
2327template <typename T, typename TCameraWrapper>
2328void AnyCameraWrappingT<T, TCameraWrapper>::pointJacobian2nx3IF(const VectorT3<T>* flippedCameraObjectPoints, const size_t numberObjectPoints, T* jacobians) const
2329{
2330 return TCameraWrapper::pointJacobian2nx3IF(flippedCameraObjectPoints, numberObjectPoints, jacobians);
2331}
2332
2333template <typename T, typename TCameraWrapper>
2334bool AnyCameraWrappingT<T, TCameraWrapper>::isEqual(const AnyCameraT<T>& anyCamera, const T eps) const
2335{
2336 ocean_assert(eps >= T(0));
2337
2338 if (isValid() != anyCamera.isValid())
2339 {
2340 // one camera is value, one is not valid
2341 return false;
2342 }
2343
2344 if (!isValid())
2345 {
2346 // both cameras are invalid
2347 return true;
2348 }
2349
2350 if (name() != anyCamera.name())
2351 {
2352 return false;
2353 }
2354
2355 return TCameraWrapper::isEqual((const AnyCameraWrappingT<T, TCameraWrapper>&)(anyCamera), eps);
2356}
2357
2358template <typename T, typename TCameraWrapper>
2360{
2361 return TCameraWrapper::isValid();
2362}
2363
2364template <typename T, typename TCameraWrapperBase>
2366 TCameraWrapperBase(std::move(actualCamera))
2367{
2368 // nothing to do here
2369}
2370
2371template <typename T, typename TCameraWrapperBase>
2373 TCameraWrapperBase(actualCamera)
2374{
2375 // nothing to do here
2376}
2377
2378template <typename T, typename TCameraWrapperBase>
2380{
2381 return VectorT2<T>(TCameraWrapperBase::principalPointX(), TCameraWrapperBase::principalPointY());
2382}
2383
2384template <typename T, typename TCameraWrapperBase>
2386{
2387 ocean_assert(TCameraWrapperBase::isValid());
2388
2389 /**
2390 * x = Fx * X / Z + mx
2391 *
2392 * (x - mx) / Fx = X / Z
2393 */
2394
2395 if (NumericT<T>::isEqualEps(TCameraWrapperBase::focalLengthX()))
2396 {
2397 return T(0);
2398 }
2399
2400 // the left angle is negative in case the principal point lies left of the image, so that the field of view is the difference of both angles
2401 const T leftAngle = NumericT<T>::atan(TCameraWrapperBase::principalPointX() * TCameraWrapperBase::inverseFocalLengthX());
2402
2403 if (T(TCameraWrapperBase::width()) <= TCameraWrapperBase::principalPointX())
2404 {
2405 ocean_assert(false && "Invalid principal point");
2406 return T(2) * leftAngle;
2407 }
2408
2409 const T rightAngle = NumericT<T>::atan((T(TCameraWrapperBase::width()) - TCameraWrapperBase::principalPointX()) * TCameraWrapperBase::inverseFocalLengthX());
2410
2411 return leftAngle + rightAngle;
2412}
2413
2414template <typename T, typename TCameraWrapperBase>
2416{
2417 ocean_assert(TCameraWrapperBase::isValid());
2418
2419 /**
2420 * y = Fy * Y / Z + my
2421 *
2422 * (y - my) / Fy = Y / Z
2423 */
2424
2425 if (NumericT<T>::isEqualEps(TCameraWrapperBase::focalLengthY()))
2426 {
2427 return T(0);
2428 }
2429
2430 // the top angle is negative in case the principal point lies above the image, so that the field of view is the difference of both angles
2431 const T topAngle = NumericT<T>::atan(TCameraWrapperBase::principalPointY() * TCameraWrapperBase::inverseFocalLengthY());
2432
2433 if (T(TCameraWrapperBase::height()) <= TCameraWrapperBase::principalPointY())
2434 {
2435 ocean_assert(false && "Invalid principal point");
2436 return T(2) * topAngle;
2437 }
2438
2439 const T bottomAngle = NumericT<T>::atan((T(TCameraWrapperBase::height()) - TCameraWrapperBase::principalPointY()) * TCameraWrapperBase::inverseFocalLengthY());
2440
2441 return topAngle + bottomAngle;
2442}
2443
2444template <typename T, typename TCameraWrapperBase>
2445inline bool CameraWrapperT<T, TCameraWrapperBase>::isInside(const VectorT2<T>& imagePoint, const T signedBorder) const
2446{
2447 ocean_assert(TCameraWrapperBase::isValid());
2448
2449 const unsigned int cameraWidth = TCameraWrapperBase::width();
2450 const unsigned int cameraHeight = TCameraWrapperBase::height();
2451
2452 ocean_assert(signedBorder < T(std::min(cameraWidth / 2u, cameraHeight / 2u)));
2453
2454 return imagePoint.x() >= signedBorder && imagePoint.y() >= signedBorder
2455 && imagePoint.x() < T(cameraWidth) - signedBorder && imagePoint.y() < T(cameraHeight) - signedBorder;
2456}
2457
2458template <typename T, typename TCameraWrapperBase>
2460{
2461 return TCameraWrapperBase::projectToImageIF(VectorT3<T>(objectPoint.x(), -objectPoint.y(), -objectPoint.z()));
2462}
2463
2464template <typename T, typename TCameraWrapperBase>
2466{
2467 return TCameraWrapperBase::projectToImageIF(CameraT<T>::standard2InvertedFlipped(world_T_camera), objectPoint);
2468}
2469
2470template <typename T, typename TCameraWrapperBase>
2471inline void CameraWrapperT<T, TCameraWrapperBase>::projectToImage(const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const
2472{
2473 ocean_assert(size == 0 || objectPoints != nullptr);
2474 ocean_assert(size == 0 || imagePoints != nullptr);
2475
2476 for (size_t n = 0; n < size; ++n)
2477 {
2478 const VectorT3<T>& objectPoint = objectPoints[n];
2479 imagePoints[n] = TCameraWrapperBase::projectToImageIF(VectorT3<T>(objectPoint.x(), -objectPoint.y(), -objectPoint.z()));
2480 }
2481}
2482
2483template <typename T, typename TCameraWrapperBase>
2484inline void CameraWrapperT<T, TCameraWrapperBase>::projectToImage(const HomogenousMatrixT4<T>& world_T_camera, const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const
2485{
2486 return TCameraWrapperBase::projectToImageIF(CameraT<T>::standard2InvertedFlipped(world_T_camera), objectPoints, size, imagePoints);
2487}
2488
2489template <typename T, typename TCameraWrapperBase>
2490inline VectorT3<T> CameraWrapperT<T, TCameraWrapperBase>::vector(const VectorT2<T>& distortedImagePoint, const bool makeUnitVector) const
2491{
2492 const VectorT3<T> localVectorIF(TCameraWrapperBase::vectorIF(distortedImagePoint, makeUnitVector));
2493
2494 return VectorT3<T>(localVectorIF.x(), -localVectorIF.y(), -localVectorIF.z());
2495}
2496
2497template <typename T, typename TCameraWrapperBase>
2498inline void CameraWrapperT<T, TCameraWrapperBase>::vector(const VectorT2<T>* distortedImagePoints, const size_t size, VectorT3<T>* vectors, const bool makeUnitVector) const
2499{
2500 TCameraWrapperBase::vectorIF(distortedImagePoints, size, vectors, makeUnitVector);
2501
2502 for (size_t n = 0; n < size; ++n)
2503 {
2504 const VectorT3<T>& localVectorIF = vectors[n];
2505
2506 vectors[n] = VectorT3<T>(localVectorIF.x(), -localVectorIF.y(), -localVectorIF.z());
2507 }
2508}
2509
2510template <typename T, typename TCameraWrapperBase>
2511inline LineT3<T> CameraWrapperT<T, TCameraWrapperBase>::ray(const VectorT2<T>& distortedImagePoint, const HomogenousMatrixT4<T>& world_T_camera) const
2512{
2513 ocean_assert(TCameraWrapperBase::isValid() && world_T_camera.isValid());
2514
2515 return LineT3<T>(world_T_camera.translation(), world_T_camera.rotationMatrix(vector(distortedImagePoint, true /*makeUnitVector*/)));
2516}
2517
2518template <typename T, typename TCameraWrapperBase>
2520{
2521 ocean_assert(TCameraWrapperBase::isValid());
2522
2523 return LineT3<T>(VectorT3<T>(0, 0, 0), vector(distortedImagePoint, true /*makeUnitVector*/));
2524}
2525
2526template <typename T, typename TCameraWrapperBase>
2527inline void CameraWrapperT<T, TCameraWrapperBase>::pointJacobian2nx3IF(const VectorT3<T>* flippedCameraObjectPoints, const size_t numberObjectPoints, T* jacobians) const
2528{
2529 ocean_assert(flippedCameraObjectPoints != nullptr);
2530 ocean_assert(numberObjectPoints >= 1);
2531 ocean_assert(jacobians != nullptr);
2532
2533 for (size_t n = 0; n < numberObjectPoints; ++n)
2534 {
2535 TCameraWrapperBase::pointJacobian2x3IF(flippedCameraObjectPoints[n], jacobians + 0, jacobians + 3);
2536 jacobians += 6;
2537 }
2538}
2539
2540template <typename T>
2542 actualCamera_(std::move(actualCamera))
2543{
2544 // nothing to do here
2545}
2546
2547template <typename T>
2549 actualCamera_(actualCamera)
2550{
2551 // nothing to do here
2552}
2553
2554template <typename T>
2556{
2557 return actualCamera_;
2558}
2559
2560template <typename T>
2561inline unsigned int CameraWrapperBasePinholeT<T>::width() const
2562{
2563 return actualCamera_.width();
2564}
2565
2566template <typename T>
2567inline unsigned int CameraWrapperBasePinholeT<T>::height() const
2568{
2569 return actualCamera_.height();
2570}
2571
2572template <typename T>
2574{
2575 return T(actualCamera_.principalPointX());
2576}
2577
2578template <typename T>
2580{
2581 return T(actualCamera_.principalPointY());
2582}
2583
2584template <typename T>
2586{
2587 return T(actualCamera_.focalLengthX());
2588}
2589
2590template <typename T>
2592{
2593 return T(actualCamera_.focalLengthY());
2594}
2595
2596template <typename T>
2598{
2599 return T(actualCamera_.inverseFocalLengthX());
2600}
2601
2602template <typename T>
2604{
2605 return T(actualCamera_.inverseFocalLengthY());
2606}
2607
2608template <typename T>
2610{
2611 return VectorT2<T>(actualCamera_.template projectToImageIF<true>(HomogenousMatrixT4<T>(true), objectPoint, true));
2612}
2613
2614template <typename T>
2615inline VectorT2<T> CameraWrapperBasePinholeT<T>::projectToImageIF(const HomogenousMatrixT4<T>& flippedCamera_T_world, const VectorT3<T>& objectPoint) const
2616{
2617 return VectorT2<T>(actualCamera_.template projectToImageIF<true>(flippedCamera_T_world, objectPoint, true));
2618}
2619
2620template <typename T>
2621inline void CameraWrapperBasePinholeT<T>::projectToImageIF(const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const
2622{
2623 ocean_assert(size == 0 || objectPoints != nullptr);
2624 ocean_assert(size == 0 || imagePoints != nullptr);
2625
2626 for (size_t n = 0; n < size; ++n)
2627 {
2628 imagePoints[n] = projectToImageIF(objectPoints[n]);
2629 }
2630}
2631
2632template <typename T>
2633inline void CameraWrapperBasePinholeT<T>::projectToImageIF(const HomogenousMatrixT4<T>& flippedCamera_T_world, const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const
2634{
2635 ocean_assert(size == 0 || objectPoints != nullptr);
2636 ocean_assert(size == 0 || imagePoints != nullptr);
2637
2638 for (size_t n = 0; n < size; ++n)
2639 {
2640 imagePoints[n] = projectToImageIF(flippedCamera_T_world, objectPoints[n]);
2641 }
2642}
2643
2644template <typename T>
2645inline VectorT3<T> CameraWrapperBasePinholeT<T>::vectorIF(const VectorT2<T>& distortedImagePoint, const bool makeUnitVector) const
2646{
2647 const VectorT2<T> undistortedImagePoint(actualCamera_.template undistort<true>(distortedImagePoint));
2648
2649 return VectorT3<T>(actualCamera_.vectorIF(undistortedImagePoint, makeUnitVector));
2650}
2651
2652template <typename T>
2653inline void CameraWrapperBasePinholeT<T>::vectorIF(const VectorT2<T>* distortedImagePoints, const size_t size, VectorT3<T>* vectors, const bool makeUnitVector) const
2654{
2655 ocean_assert(distortedImagePoints != nullptr && size > 0);
2656 ocean_assert(vectors != nullptr);
2657
2658 for (size_t n = 0; n < size; ++n)
2659 {
2660 vectors[n] = vectorIF(distortedImagePoints[n], makeUnitVector);
2661 }
2662}
2663
2664template <typename T>
2665inline void CameraWrapperBasePinholeT<T>::pointJacobian2x3IF(const VectorT3<T>& flippedCameraObjectPoint, T* jx, T* jy) const
2666{
2667 ocean_assert(jx != nullptr && jy != nullptr);
2668 actualCamera_.template pointJacobian2x3IF<T, true>(flippedCameraObjectPoint, jx, jy);
2669}
2670
2671template <typename T>
2672inline bool CameraWrapperBasePinholeT<T>::isEqual(const CameraWrapperBasePinholeT<T>& basePinhole, const T eps) const
2673{
2674 ocean_assert(eps >= T(0));
2675
2676 return actualCamera_.isEqual(basePinhole.actualCamera_, eps);
2677}
2678
2679template <typename T>
2681{
2682 return actualCamera_.isValid();
2683}
2684
2685template <typename T>
2686template <typename U>
2687inline std::unique_ptr<AnyCameraT<U>> CameraWrapperBasePinholeT<T>::clone(const unsigned int width, const unsigned int height) const
2688{
2689 ocean_assert(actualCamera_.isValid());
2690
2691 if constexpr (std::is_same<T, U>::value)
2692 {
2693 if ((width == 0u && height == 0u) || (width == actualCamera_.width() && height == actualCamera_.height()))
2694 {
2695 return std::make_unique<AnyCameraWrappingT<U, CameraWrapperT<U, CameraWrapperBasePinholeT<U>>>>(actualCamera_);
2696 }
2697
2698 const unsigned int validWidth = (height * actualCamera_.width() + actualCamera_.height() / 2u) / actualCamera_.height();
2699 const unsigned int validHeight = (width * actualCamera_.height() + actualCamera_.width() / 2u) / actualCamera_.width();
2700
2701 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
2702 {
2703 ocean_assert(false && "Wrong aspect ratio!");
2704 return nullptr;
2705 }
2706
2707 return std::make_unique<AnyCameraWrappingT<U, CameraWrapperT<U, CameraWrapperBasePinholeT<U>>>>(PinholeCameraT<U>(width, height, actualCamera_));
2708 }
2709 else
2710 {
2711 const PinholeCameraT<U> convertedPinholeCamera(actualCamera_);
2712
2713 if ((width == 0u && height == 0u) || (width == actualCamera_.width() && height == actualCamera_.height()))
2714 {
2715 return std::make_unique<AnyCameraWrappingT<U, CameraWrapperT<U, CameraWrapperBasePinholeT<U>>>>(convertedPinholeCamera);
2716 }
2717
2718 const unsigned int validWidth = (height * actualCamera_.width() + actualCamera_.height() / 2u) / actualCamera_.height();
2719 const unsigned int validHeight = (width * actualCamera_.height() + actualCamera_.width() / 2u) / actualCamera_.width();
2720
2721 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
2722 {
2723 ocean_assert(false && "Wrong aspect ratio!");
2724 return nullptr;
2725 }
2726
2727 return std::make_unique<AnyCameraWrappingT<U, CameraWrapperT<U, CameraWrapperBasePinholeT<U>>>>(PinholeCameraT<U>(width, height, convertedPinholeCamera));
2728 }
2729}
2730
2731template <typename T>
2736
2737template <typename T>
2739{
2740 return std::string("Ocean Pinhole");
2741}
2742
2743template <typename T>
2745 actualCamera_(std::move(camera))
2746{
2747 // nothing to do here
2748}
2749
2750template <typename T>
2752 actualCamera_(camera)
2753{
2754 // nothing to do here
2755}
2756
2757template <typename T>
2759{
2760 return actualCamera_;
2761}
2762
2763template <typename T>
2764inline unsigned int CameraWrapperBaseFisheyeT<T>::width() const
2765{
2766 return actualCamera_.width();
2767}
2768
2769template <typename T>
2770inline unsigned int CameraWrapperBaseFisheyeT<T>::height() const
2771{
2772 return actualCamera_.height();
2773}
2774
2775template <typename T>
2777{
2778 return actualCamera_.principalPoint();
2779}
2780
2781template <typename T>
2783{
2784 return actualCamera_.principalPointX();
2785}
2786
2787template <typename T>
2789{
2790 return actualCamera_.principalPointY();
2791}
2792
2793template <typename T>
2795{
2796 return actualCamera_.focalLengthX();
2797}
2798
2799template <typename T>
2801{
2802 return actualCamera_.focalLengthY();
2803}
2804
2805template <typename T>
2807{
2808 return actualCamera_.inverseFocalLengthX();
2809}
2810
2811template <typename T>
2813{
2814 return actualCamera_.inverseFocalLengthY();
2815}
2816
2817template <typename T>
2819{
2820 return actualCamera_.projectToImageIF(objectPoint);
2821}
2822
2823template <typename T>
2824inline VectorT2<T> CameraWrapperBaseFisheyeT<T>::projectToImageIF(const HomogenousMatrixT4<T>& flippedCamera_T_world, const VectorT3<T>& objectPoint) const
2825{
2826 return actualCamera_.projectToImageIF(flippedCamera_T_world, objectPoint);
2827}
2828
2829template <typename T>
2830inline void CameraWrapperBaseFisheyeT<T>::projectToImageIF(const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const
2831{
2832 ocean_assert(size == 0 || objectPoints != nullptr);
2833 ocean_assert(size == 0 || imagePoints != nullptr);
2834
2835 for (size_t n = 0; n < size; ++n)
2836 {
2837 imagePoints[n] = projectToImageIF(objectPoints[n]);
2838 }
2839}
2840
2841template <typename T>
2842inline void CameraWrapperBaseFisheyeT<T>::projectToImageIF(const HomogenousMatrixT4<T>& flippedCamera_T_world, const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const
2843{
2844 ocean_assert(size == 0 || objectPoints != nullptr);
2845 ocean_assert(size == 0 || imagePoints != nullptr);
2846
2847 for (size_t n = 0; n < size; ++n)
2848 {
2849 imagePoints[n] = projectToImageIF(flippedCamera_T_world, objectPoints[n]);
2850 }
2851}
2852
2853template <typename T>
2854inline VectorT3<T> CameraWrapperBaseFisheyeT<T>::vectorIF(const VectorT2<T>& distortedImagePoint, const bool makeUnitVector) const
2855{
2856 return actualCamera_.vectorIF(distortedImagePoint, makeUnitVector);
2857}
2858
2859template <typename T>
2860inline void CameraWrapperBaseFisheyeT<T>::vectorIF(const VectorT2<T>* distortedImagePoints, const size_t size, VectorT3<T>* vectors, const bool makeUnitVector) const
2861{
2862 ocean_assert(distortedImagePoints != nullptr && size > 0);
2863 ocean_assert(vectors != nullptr);
2864
2865 for (size_t n = 0; n < size; ++n)
2866 {
2867 vectors[n] = vectorIF(distortedImagePoints[n], makeUnitVector);
2868 }
2869}
2870
2871template <typename T>
2872inline void CameraWrapperBaseFisheyeT<T>::pointJacobian2x3IF(const VectorT3<T>& flippedCameraObjectPoint, T* jx, T* jy) const
2873{
2874 actualCamera_.pointJacobian2x3IF(flippedCameraObjectPoint, jx, jy);
2875}
2876
2877template <typename T>
2878inline bool CameraWrapperBaseFisheyeT<T>::isEqual(const CameraWrapperBaseFisheyeT& baseFisheye, const T eps) const
2879{
2880 ocean_assert(eps >= T(0));
2881
2882 return actualCamera_.isEqual(baseFisheye.actualCamera_, eps);
2883}
2884
2885template <typename T>
2887{
2888 return actualCamera_.isValid();
2889}
2890
2891template <typename T>
2892template <typename U>
2893inline std::unique_ptr<AnyCameraT<U>> CameraWrapperBaseFisheyeT<T>::clone(const unsigned int width, const unsigned int height) const
2894{
2895 ocean_assert(actualCamera_.isValid());
2896
2897 if ((width == 0u && height == 0u) || (width == actualCamera_.width() && height == actualCamera_.height()))
2898 {
2899 return std::make_unique<AnyCameraWrappingT<U, CameraWrapperT<U, CameraWrapperBaseFisheyeT<U>>>>(FisheyeCameraT<U>(actualCamera_));
2900 }
2901
2902 const unsigned int validWidth = (height * actualCamera_.width() + actualCamera_.height() / 2u) / actualCamera_.height();
2903 const unsigned int validHeight = (width * actualCamera_.height() + actualCamera_.width() / 2u) / actualCamera_.width();
2904
2905 if (!NumericT<unsigned int>::isEqual(width, validWidth, 1u) && !NumericT<unsigned int>::isEqual(height, validHeight, 1u))
2906 {
2907 ocean_assert(false && "Wrong aspect ratio!");
2908 return nullptr;
2909 }
2910
2911 const T xFactor = T(width) / T(actualCamera_.width());
2912 const T yFactor = T(height) / T(actualCamera_.height());
2913
2914 const U newPrincipalX = U(actualCamera_.principalPointX() * xFactor);
2915 const U newPrincipalY = U(actualCamera_.principalPointY() * yFactor);
2916
2917 const U newFocalLengthX = U(actualCamera_.focalLengthX() * xFactor);
2918 const U newFocalLengthY = U(actualCamera_.focalLengthY() * yFactor);
2919
2920 U radialDistortion[6];
2921 for (unsigned int n = 0u; n < 6u; ++n)
2922 {
2923 radialDistortion[n] = U(actualCamera_.radialDistortion()[n]);
2924 }
2925
2926 const U tangentialDistortion[2] =
2927 {
2928 U(actualCamera_.tangentialDistortion()[0]),
2929 U(actualCamera_.tangentialDistortion()[1])
2930 };
2931
2932 return std::make_unique<AnyCameraWrappingT<U, CameraWrapperT<U, CameraWrapperBaseFisheyeT<U>>>>(FisheyeCameraT<U>(width, height, newFocalLengthX, newFocalLengthY, newPrincipalX, newPrincipalY, radialDistortion, tangentialDistortion));
2933}
2934
2935template <typename T>
2940
2941template <typename T>
2943{
2944 return std::string("Ocean Fisheye");
2945}
2946
2947template <typename T>
2949 actualCamera_(std::move(camera))
2950{
2951 // nothing to do here
2952}
2953
2954template <typename T>
2956 actualCamera_(camera)
2957{
2958 // nothing to do here
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 actualCamera_;
2969}
2970
2971template <typename T>
2972inline unsigned int CameraWrapperBaseInvalidT<T>::width() const
2973{
2974 Log::error() << "Invalid camera: " << actualCamera_.reason();
2975
2976 ocean_assert(false && "This function must never be called.");
2977
2978 return (unsigned int)(-1);
2979}
2980
2981template <typename T>
2982inline unsigned int CameraWrapperBaseInvalidT<T>::height() const
2983{
2984 Log::error() << "Invalid camera: " << actualCamera_.reason();
2985
2986 ocean_assert(false && "This function must never be called.");
2987
2988 return (unsigned int)(-1);
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
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
3028 return NumericT<T>::minValue();
3029}
3030
3031template <typename T>
3033{
3034 Log::error() << "Invalid camera: " << actualCamera_.reason();
3035
3036 ocean_assert(false && "This function must never be called.");
3037
3038 return NumericT<T>::minValue();
3039}
3040
3041template <typename T>
3043{
3044 Log::error() << "Invalid camera: " << actualCamera_.reason();
3045
3046 ocean_assert(false && "This function must never be called.");
3047
3048 return NumericT<T>::minValue();
3049}
3050
3051template <typename T>
3053{
3054 Log::error() << "Invalid camera: " << actualCamera_.reason();
3055
3056 ocean_assert(false && "This function must never be called.");
3057
3058 return NumericT<T>::minValue();
3059}
3060
3061template <typename T>
3063{
3064 Log::error() << "Invalid camera: " << actualCamera_.reason();
3065
3066 ocean_assert(false && "This function must never be called.");
3067
3069}
3070
3071template <typename T>
3072inline VectorT2<T> CameraWrapperBaseInvalidT<T>::projectToImageIF(const HomogenousMatrixT4<T>& /*flippedCamera_T_world*/, const VectorT3<T>& /*objectPoint*/) const
3073{
3074 Log::error() << "Invalid camera: " << actualCamera_.reason();
3075
3076 ocean_assert(false && "This function must never be called.");
3077
3079}
3080
3081template <typename T>
3082inline void CameraWrapperBaseInvalidT<T>::projectToImageIF(const VectorT3<T>* /*objectPoints*/, const size_t /*size*/, VectorT2<T>* /*imagePoints*/) const
3083{
3084 Log::error() << "Invalid camera: " << actualCamera_.reason();
3085
3086 ocean_assert(false && "This function must never be called.");
3087
3088}
3089
3090template <typename T>
3091inline void CameraWrapperBaseInvalidT<T>::projectToImageIF(const HomogenousMatrixT4<T>& /*flippedCamera_T_world*/, const VectorT3<T>* /*objectPoints*/, const size_t /*size*/, VectorT2<T>* /*imagePoints*/) const
3092{
3093 Log::error() << "Invalid camera: " << actualCamera_.reason();
3094
3095 ocean_assert(false && "This function must never be called.");
3096}
3097
3098template <typename T>
3099inline VectorT3<T> CameraWrapperBaseInvalidT<T>::vectorIF(const VectorT2<T>& /*distortedImagePoint*/, const bool /*makeUnitVector*/) const
3100{
3101 Log::error() << "Invalid camera: " << actualCamera_.reason();
3102
3103 ocean_assert(false && "This function must never be called.");
3104
3106}
3107
3108template <typename T>
3109inline void CameraWrapperBaseInvalidT<T>::vectorIF(const VectorT2<T>* /*distortedImagePoints*/, const size_t /*size*/, VectorT3<T>* /*vectors*/, const bool /*makeUnitVector*/) const
3110{
3111 Log::error() << "Invalid camera: " << actualCamera_.reason();
3112
3113 ocean_assert(false && "This function must never be called.");
3114}
3115
3116template <typename T>
3117inline void CameraWrapperBaseInvalidT<T>::pointJacobian2x3IF(const VectorT3<T>& /*flippedCameraObjectPoint*/, T* /*jx*/, T* /*jy*/) const
3118{
3119 Log::error() << "Invalid camera: " << actualCamera_.reason();
3120
3121 ocean_assert(false && "This function must never be called.");
3122}
3123
3124template <typename T>
3125inline bool CameraWrapperBaseInvalidT<T>::isEqual(const CameraWrapperBaseInvalidT& /*baseFisheye*/, const T /*eps*/) const
3126{
3127 Log::error() << "Invalid camera: " << actualCamera_.reason();
3128
3129 ocean_assert(false && "This function must never be called.");
3130
3131 return false;
3132}
3133
3134template <typename T>
3136{
3137 return false;
3138}
3139
3140template <typename T>
3141template <typename U>
3142inline std::unique_ptr<AnyCameraT<U>> CameraWrapperBaseInvalidT<T>::clone(const unsigned int /*width*/, const unsigned int /*height*/) const
3143{
3144 Log::error() << "Invalid camera: " << actualCamera_.reason();
3145
3146 ocean_assert(false && "This function must never be called.");
3147
3148 return nullptr;
3149}
3150
3151template <typename T>
3156
3157template <typename T>
3159{
3160 return std::string("Invalid camera");
3161}
3162
3163template <typename T>
3164InvalidCameraT<T>::InvalidCameraT(const std::string& reason) :
3165 reason_(reason)
3166{
3167 // nothing to do here
3168}
3169
3170template <typename T>
3171const std::string& InvalidCameraT<T>::reason() const
3172{
3173 return reason_;
3174}
3175
3176}
3177
3178#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:1733
bool isValid() const
Returns whether this clipper holds a valid camera model and is ready to be used.
Definition AnyCamera.h:1860
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:1999
AnyCameraClipperT()=default
Default constructor creating an invalid object.
unsigned int height() const
Returns the height of the camera profile.
Definition AnyCamera.h:1783
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:1854
FiniteLinesT2< T > cameraBoundarySegments_
The 2D line segments defined in the camera's normalized image plane defining the camera's boundary,...
Definition AnyCamera.h:624
const SharedAnyCameraT< T > & camera() const
Returns the camera model of this clipper.
Definition AnyCamera.h:1766
unsigned int width() const
Returns the width of the camera profile.
Definition AnyCamera.h:1772
SharedAnyCameraT< T > camera_
The actual camera model this clipper is based on.
Definition AnyCamera.h:621
void update(const SharedAnyCameraT< T > &camera, const size_t segmentSteps=10)
Updates the clipper with a new camera model.
Definition AnyCamera.h:1794
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:1868
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:2046
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:2114
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:638
VectorT2< T > principalPoint() const override
Returns the coordinate of the principal point of the camera image in the pixel domain.
Definition AnyCamera.h:2178
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:2328
VectorT2< T > projectToImage(const VectorT3< T > &objectPoint) const override
Projects a 3D object point into the camera frame.
Definition AnyCamera.h:2238
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:2334
unsigned int width() const override
Returns the width of the camera image.
Definition AnyCamera.h:2166
unsigned int height() const override
Returns the height of the camera image.
Definition AnyCamera.h:2172
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:2154
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:2148
T focalLengthY() const override
Returns the vertical focal length parameter.
Definition AnyCamera.h:2202
bool isValid() const override
Returns whether this camera is valid.
Definition AnyCamera.h:2359
AnyCameraType anyCameraType() const override
Returns the type of this camera.
Definition AnyCamera.h:2136
T inverseFocalLengthX() const override
Returns the inverse horizontal focal length parameter.
Definition AnyCamera.h:2208
T principalPointY() const override
Returns the y-value of the principal point of the camera image in the pixel domain.
Definition AnyCamera.h:2190
AnyCameraWrappingT(ActualCamera &&actualCamera)
Creates a new AnyCamera object wrapping the actual camera model.
Definition AnyCamera.h:2122
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:2286
VectorT2< T > projectToImageIF(const VectorT3< T > &objectPoint) const override
Projects a 3D object point into the camera frame.
Definition AnyCamera.h:2250
T TScalar
The scalar data type of this object.
Definition AnyCamera.h:642
T focalLengthX() const override
Returns the horizontal focal length parameter.
Definition AnyCamera.h:2196
T fovX() const override
Returns the field of view in x direction of the camera.
Definition AnyCamera.h:2220
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:2232
std::string name() const override
Returns the name of this camera.
Definition AnyCamera.h:2142
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:2310
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:2298
typename TCameraWrapper::ActualCamera ActualCamera
The actual camera object wrapped by this class.
Definition AnyCamera.h:648
T principalPointX() const override
Returns the x-value of the principal point of the camera image in the pixel domain.
Definition AnyCamera.h:2184
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:2160
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:2322
T fovY() const override
Returns the field of view in x direction of the camera.
Definition AnyCamera.h:2226
T inverseFocalLengthY() const override
Returns the inverse vertical focal length parameter.
Definition AnyCamera.h:2214
This class implements the base class for all cameras.
Definition Camera.h:99
This class implements the base wrapper around Ocean's fisheye camera profile.
Definition AnyCamera.h:1247
T principalPointX() const
Returns the x-value of the principal point of the camera image in the pixel domain.
Definition AnyCamera.h:2782
T inverseFocalLengthX() const
Returns the inverse horizontal focal length parameter.
Definition AnyCamera.h:2806
ActualCamera actualCamera_
The actual fisheye camera object.
Definition AnyCamera.h:1410
unsigned int height() const
Returns the height of the camera image.
Definition AnyCamera.h:2770
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:2872
unsigned int width() const
Returns the width of the camera image.
Definition AnyCamera.h:2764
bool isValid() const
Returns whether this camera is valid.
Definition AnyCamera.h:2886
FisheyeCameraT< T > ActualCamera
Definition of the actual camera object wrapped by this class.
Definition AnyCamera.h:1253
T inverseFocalLengthY() const
Returns the inverse vertical focal length parameter.
Definition AnyCamera.h:2812
static AnyCameraType anyCameraType()
Returns the type of this camera.
Definition AnyCamera.h:2936
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:2854
const ActualCamera & actualCamera() const
Returns the actual camera object wrapped in this class.
Definition AnyCamera.h:2758
VectorT2< T > principalPoint() const
Returns the coordinate of the principal point of the camera image in the pixel domain.
Definition AnyCamera.h:2776
T principalPointY() const
Returns the y-value of the principal point of the camera image in the pixel domain.
Definition AnyCamera.h:2788
static std::string name()
Returns the name of this camera.
Definition AnyCamera.h:2942
T focalLengthX() const
Returns the horizontal focal length parameter.
Definition AnyCamera.h:2794
T focalLengthY() const
Returns the vertical focal length parameter.
Definition AnyCamera.h:2800
VectorT2< T > projectToImageIF(const VectorT3< T > &objectPoint) const
Projects a 3D object point into the camera frame.
Definition AnyCamera.h:2818
CameraWrapperBaseFisheyeT(ActualCamera &&actualCamera)
Creates a new CameraWrapperBaseFisheyeT object wrapping the actual camera model.
Definition AnyCamera.h:2744
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:2893
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:2878
This class implements the base wrapper around an invalid camera profile.
Definition AnyCamera.h:1470
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:3125
InvalidCameraT< T > ActualCamera
Definition of the actual camera object wrapped by this class.
Definition AnyCamera.h:1476
VectorT2< T > projectToImageIF(const VectorT3< T > &objectPoint) const
Projects a 3D object point into the camera frame.
Definition AnyCamera.h:3062
CameraWrapperBaseInvalidT(ActualCamera &&actualCamera)
Creates a new CameraWrapperBaseInvalidT object wrapping the actual camera model.
Definition AnyCamera.h:2948
unsigned int height() const
Returns the height of the camera image.
Definition AnyCamera.h:2982
const ActualCamera & actualCamera() const
Returns the actual camera object wrapped in this class.
Definition AnyCamera.h:2962
static std::string name()
Returns the name of this camera.
Definition AnyCamera.h:3158
ActualCamera actualCamera_
The actual invalid camera.
Definition AnyCamera.h:1633
T principalPointX() const
Returns the x-value of the principal point of the camera image in the pixel domain.
Definition AnyCamera.h:3002
VectorT2< T > principalPoint() const
Returns the coordinate of the principal point of the camera image in the pixel domain.
Definition AnyCamera.h:2992
T inverseFocalLengthX() const
Returns the inverse horizontal focal length parameter.
Definition AnyCamera.h:3042
bool isValid() const
Returns whether this camera is valid.
Definition AnyCamera.h:3135
static AnyCameraType anyCameraType()
Returns the type of this camera.
Definition AnyCamera.h:3152
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:3142
T inverseFocalLengthY() const
Returns the inverse vertical focal length parameter.
Definition AnyCamera.h:3052
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:3117
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:3099
T focalLengthY() const
Returns the vertical focal length parameter.
Definition AnyCamera.h:3032
T principalPointY() const
Returns the y-value of the principal point of the camera image in the pixel domain.
Definition AnyCamera.h:3012
T focalLengthX() const
Returns the horizontal focal length parameter.
Definition AnyCamera.h:3022
unsigned int width() const
Returns the width of the camera image.
Definition AnyCamera.h:2972
This class implements the base wrapper around Ocean's pinhole camera profile.
Definition AnyCamera.h:1078
T inverseFocalLengthX() const
Returns the inverse horizontal focal length parameter.
Definition AnyCamera.h:2597
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:2665
PinholeCameraT< T > ActualCamera
Definition of the actual camera object wrapped by this class.
Definition AnyCamera.h:1084
unsigned int height() const
Returns the height of the camera image.
Definition AnyCamera.h:2567
bool isValid() const
Returns whether this camera is valid.
Definition AnyCamera.h:2680
T principalPointY() const
Returns the y-value of the principal point of the camera image in the pixel domain.
Definition AnyCamera.h:2579
T inverseFocalLengthY() const
Returns the inverse vertical focal length parameter.
Definition AnyCamera.h:2603
static std::string name()
Returns the name of this camera.
Definition AnyCamera.h:2738
ActualCamera actualCamera_
The actual pinhole camera.
Definition AnyCamera.h:1236
const ActualCamera & actualCamera() const
Returns the actual camera object wrapped in this class.
Definition AnyCamera.h:2555
unsigned int width() const
Returns the width of the camera image.
Definition AnyCamera.h:2561
CameraWrapperBasePinholeT(ActualCamera &&actualCamera)
Creates a new CameraWrapperBasePinholeT object wrapping the actual camera model.
Definition AnyCamera.h:2541
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:2645
VectorT2< T > projectToImageIF(const VectorT3< T > &objectPoint) const
Projects a 3D object point into the camera frame.
Definition AnyCamera.h:2609
static AnyCameraType anyCameraType()
Returns the type of this camera.
Definition AnyCamera.h:2732
T principalPointX() const
Returns the x-value of the principal point of the camera image in the pixel domain.
Definition AnyCamera.h:2573
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:2672
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:2687
T focalLengthY() const
Returns the vertical focal length parameter.
Definition AnyCamera.h:2591
T focalLengthX() const
Returns the horizontal focal length parameter.
Definition AnyCamera.h:2585
This class implements a wrapper for an actual camera object.
Definition AnyCamera.h:969
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:2511
T fovY() const
Returns the field of view in x direction of the camera.
Definition AnyCamera.h:2415
T fovX() const
Returns the field of view in x direction of the camera.
Definition AnyCamera.h:2385
CameraWrapperT(ActualCamera &&actualCamera)
Creates a new CameraWrapperT object wrapping the actual camera model.
Definition AnyCamera.h:2365
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:2490
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:2527
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:2445
VectorT2< T > principalPoint() const
Returns the coordinate of the principal point of the camera image in the pixel domain.
Definition AnyCamera.h:2379
VectorT2< T > projectToImage(const VectorT3< T > &objectPoint) const
Projects a 3D object point into the camera frame.
Definition AnyCamera.h:2459
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:1487
VectorT3< T > translation() const
Returns the translation of the transformation.
Definition HomogenousMatrix4.h:1375
bool isValid() const
Returns whether this matrix is a valid homogeneous transformation.
Definition HomogenousMatrix4.h:1800
This class implements invalid camera profiles, e.g.
Definition AnyCamera.h:1420
const std::string & reason() const
Returns the reason of this invalid camera.
Definition AnyCamera.h:3171
std::string reason_
The reason why no valid camera is available.
Definition AnyCamera.h:1438
InvalidCameraT(const std::string &reason)
Creates an invalid camera.
Definition AnyCamera.h:3164
This class implements an infinite line in 3D space.
Definition Line3.h:69
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 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:703
const T & y() const noexcept
Returns the y value.
Definition Vector2.h:715
bool isNull() const
Returns whether this vector is a null vector up to a small epsilon.
Definition Vector2.h:739
T sqrDistance(const VectorT2< T > &right) const
Returns the square distance between this 2D position and a second 2D position.
Definition Vector2.h:638
This class implements a vector with three elements.
Definition Vector3.h:97
const T & y() const noexcept
Returns the y value.
Definition Vector3.h:816
const T & x() const noexcept
Returns the x value.
Definition Vector3.h:804
VectorT2< T > xy() const noexcept
Returns the x and y component of the vector as new 2D vector.
Definition Vector3.h:840
static VectorT3< T > minValue()
Returns a 3D vector with all elements set to NumericT::minValue().
Definition Vector3.h:1036
const T & z() const noexcept
Returns the z value.
Definition Vector3.h:828
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