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 const T leftAngle = NumericT<T>::abs(NumericT<T>::atan(-TCameraWrapperBase::principalPointX() * TCameraWrapperBase::inverseFocalLengthX()));
2401
2402 if (T(TCameraWrapperBase::width()) <= TCameraWrapperBase::principalPointX())
2403 {
2404 ocean_assert(false && "Invalid principal point");
2405 return T(2) * leftAngle;
2406 }
2407
2408 const T rightAngle = NumericT<T>::atan((T(TCameraWrapperBase::width()) - TCameraWrapperBase::principalPointX()) * TCameraWrapperBase::inverseFocalLengthX());
2409
2410 return leftAngle + rightAngle;
2411}
2412
2413template <typename T, typename TCameraWrapperBase>
2415{
2416 ocean_assert(TCameraWrapperBase::isValid());
2417
2418 /**
2419 * y = Fy * Y / Z + my
2420 *
2421 * (y - my) / Fy = Y / Z
2422 */
2423
2424 if (NumericT<T>::isEqualEps(TCameraWrapperBase::focalLengthY()))
2425 {
2426 return T(0);
2427 }
2428
2429 const T topAngle = NumericT<T>::abs(NumericT<T>::atan(-TCameraWrapperBase::principalPointY() * TCameraWrapperBase::inverseFocalLengthY()));
2430
2431 if (T(TCameraWrapperBase::height()) <= TCameraWrapperBase::principalPointY())
2432 {
2433 ocean_assert(false && "Invalid principal point");
2434 return T(2) * topAngle;
2435 }
2436
2437 const T bottomAngle = NumericT<T>::atan((T(TCameraWrapperBase::height()) - TCameraWrapperBase::principalPointY()) * TCameraWrapperBase::inverseFocalLengthY());
2438
2439 return topAngle + bottomAngle;
2440}
2441
2442template <typename T, typename TCameraWrapperBase>
2443inline bool CameraWrapperT<T, TCameraWrapperBase>::isInside(const VectorT2<T>& imagePoint, const T signedBorder) const
2444{
2445 ocean_assert(TCameraWrapperBase::isValid());
2446
2447 const unsigned int cameraWidth = TCameraWrapperBase::width();
2448 const unsigned int cameraHeight = TCameraWrapperBase::height();
2449
2450 ocean_assert(signedBorder < T(std::min(cameraWidth / 2u, cameraHeight / 2u)));
2451
2452 return imagePoint.x() >= signedBorder && imagePoint.y() >= signedBorder
2453 && imagePoint.x() < T(cameraWidth) - signedBorder && imagePoint.y() < T(cameraHeight) - signedBorder;
2454}
2455
2456template <typename T, typename TCameraWrapperBase>
2458{
2459 return TCameraWrapperBase::projectToImageIF(VectorT3<T>(objectPoint.x(), -objectPoint.y(), -objectPoint.z()));
2460}
2461
2462template <typename T, typename TCameraWrapperBase>
2464{
2465 return TCameraWrapperBase::projectToImageIF(CameraT<T>::standard2InvertedFlipped(world_T_camera), objectPoint);
2466}
2467
2468template <typename T, typename TCameraWrapperBase>
2469inline void CameraWrapperT<T, TCameraWrapperBase>::projectToImage(const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const
2470{
2471 ocean_assert(size == 0 || objectPoints != nullptr);
2472 ocean_assert(size == 0 || imagePoints != nullptr);
2473
2474 for (size_t n = 0; n < size; ++n)
2475 {
2476 const VectorT3<T>& objectPoint = objectPoints[n];
2477 imagePoints[n] = TCameraWrapperBase::projectToImageIF(VectorT3<T>(objectPoint.x(), -objectPoint.y(), -objectPoint.z()));
2478 }
2479}
2480
2481template <typename T, typename TCameraWrapperBase>
2482inline void CameraWrapperT<T, TCameraWrapperBase>::projectToImage(const HomogenousMatrixT4<T>& world_T_camera, const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const
2483{
2484 return TCameraWrapperBase::projectToImageIF(CameraT<T>::standard2InvertedFlipped(world_T_camera), objectPoints, size, imagePoints);
2485}
2486
2487template <typename T, typename TCameraWrapperBase>
2488inline VectorT3<T> CameraWrapperT<T, TCameraWrapperBase>::vector(const VectorT2<T>& distortedImagePoint, const bool makeUnitVector) const
2489{
2490 const VectorT3<T> localVectorIF(TCameraWrapperBase::vectorIF(distortedImagePoint, makeUnitVector));
2491
2492 return VectorT3<T>(localVectorIF.x(), -localVectorIF.y(), -localVectorIF.z());
2493}
2494
2495template <typename T, typename TCameraWrapperBase>
2496inline void CameraWrapperT<T, TCameraWrapperBase>::vector(const VectorT2<T>* distortedImagePoints, const size_t size, VectorT3<T>* vectors, const bool makeUnitVector) const
2497{
2498 TCameraWrapperBase::vectorIF(distortedImagePoints, size, vectors, makeUnitVector);
2499
2500 for (size_t n = 0; n < size; ++n)
2501 {
2502 const VectorT3<T>& localVectorIF = vectors[n];
2503
2504 vectors[n] = VectorT3<T>(localVectorIF.x(), -localVectorIF.y(), -localVectorIF.z());
2505 }
2506}
2507
2508template <typename T, typename TCameraWrapperBase>
2509inline LineT3<T> CameraWrapperT<T, TCameraWrapperBase>::ray(const VectorT2<T>& distortedImagePoint, const HomogenousMatrixT4<T>& world_T_camera) const
2510{
2511 ocean_assert(TCameraWrapperBase::isValid() && world_T_camera.isValid());
2512
2513 return LineT3<T>(world_T_camera.translation(), world_T_camera.rotationMatrix(vector(distortedImagePoint, true /*makeUnitVector*/)));
2514}
2515
2516template <typename T, typename TCameraWrapperBase>
2518{
2519 ocean_assert(TCameraWrapperBase::isValid());
2520
2521 return LineT3<T>(VectorT3<T>(0, 0, 0), vector(distortedImagePoint, true /*makeUnitVector*/));
2522}
2523
2524template <typename T, typename TCameraWrapperBase>
2525inline void CameraWrapperT<T, TCameraWrapperBase>::pointJacobian2nx3IF(const VectorT3<T>* flippedCameraObjectPoints, const size_t numberObjectPoints, T* jacobians) const
2526{
2527 ocean_assert(flippedCameraObjectPoints != nullptr);
2528 ocean_assert(numberObjectPoints >= 1);
2529 ocean_assert(jacobians != nullptr);
2530
2531 for (size_t n = 0; n < numberObjectPoints; ++n)
2532 {
2533 TCameraWrapperBase::pointJacobian2x3IF(flippedCameraObjectPoints[n], jacobians + 0, jacobians + 3);
2534 jacobians += 6;
2535 }
2536}
2537
2538template <typename T>
2540 actualCamera_(std::move(actualCamera))
2541{
2542 // nothing to do here
2543}
2544
2545template <typename T>
2547 actualCamera_(actualCamera)
2548{
2549 // nothing to do here
2550}
2551
2552template <typename T>
2554{
2555 return actualCamera_;
2556}
2557
2558template <typename T>
2559inline unsigned int CameraWrapperBasePinholeT<T>::width() const
2560{
2561 return actualCamera_.width();
2562}
2563
2564template <typename T>
2565inline unsigned int CameraWrapperBasePinholeT<T>::height() const
2566{
2567 return actualCamera_.height();
2568}
2569
2570template <typename T>
2572{
2573 return T(actualCamera_.principalPointX());
2574}
2575
2576template <typename T>
2578{
2579 return T(actualCamera_.principalPointY());
2580}
2581
2582template <typename T>
2584{
2585 return T(actualCamera_.focalLengthX());
2586}
2587
2588template <typename T>
2590{
2591 return T(actualCamera_.focalLengthY());
2592}
2593
2594template <typename T>
2596{
2597 return T(actualCamera_.inverseFocalLengthX());
2598}
2599
2600template <typename T>
2602{
2603 return T(actualCamera_.inverseFocalLengthY());
2604}
2605
2606template <typename T>
2608{
2609 return VectorT2<T>(actualCamera_.template projectToImageIF<true>(HomogenousMatrixT4<T>(true), objectPoint, true));
2610}
2611
2612template <typename T>
2613inline VectorT2<T> CameraWrapperBasePinholeT<T>::projectToImageIF(const HomogenousMatrixT4<T>& flippedCamera_T_world, const VectorT3<T>& objectPoint) const
2614{
2615 return VectorT2<T>(actualCamera_.template projectToImageIF<true>(flippedCamera_T_world, objectPoint, true));
2616}
2617
2618template <typename T>
2619inline void CameraWrapperBasePinholeT<T>::projectToImageIF(const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const
2620{
2621 ocean_assert(size == 0 || objectPoints != nullptr);
2622 ocean_assert(size == 0 || imagePoints != nullptr);
2623
2624 for (size_t n = 0; n < size; ++n)
2625 {
2626 imagePoints[n] = projectToImageIF(objectPoints[n]);
2627 }
2628}
2629
2630template <typename T>
2631inline void CameraWrapperBasePinholeT<T>::projectToImageIF(const HomogenousMatrixT4<T>& flippedCamera_T_world, const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const
2632{
2633 ocean_assert(size == 0 || objectPoints != nullptr);
2634 ocean_assert(size == 0 || imagePoints != nullptr);
2635
2636 for (size_t n = 0; n < size; ++n)
2637 {
2638 imagePoints[n] = projectToImageIF(flippedCamera_T_world, objectPoints[n]);
2639 }
2640}
2641
2642template <typename T>
2643inline VectorT3<T> CameraWrapperBasePinholeT<T>::vectorIF(const VectorT2<T>& distortedImagePoint, const bool makeUnitVector) const
2644{
2645 const VectorT2<T> undistortedImagePoint(actualCamera_.template undistort<true>(distortedImagePoint));
2646
2647 return VectorT3<T>(actualCamera_.vectorIF(undistortedImagePoint, makeUnitVector));
2648}
2649
2650template <typename T>
2651inline void CameraWrapperBasePinholeT<T>::vectorIF(const VectorT2<T>* distortedImagePoints, const size_t size, VectorT3<T>* vectors, const bool makeUnitVector) const
2652{
2653 ocean_assert(distortedImagePoints != nullptr && size > 0);
2654 ocean_assert(vectors != nullptr);
2655
2656 for (size_t n = 0; n < size; ++n)
2657 {
2658 vectors[n] = vectorIF(distortedImagePoints[n], makeUnitVector);
2659 }
2660}
2661
2662template <typename T>
2663inline void CameraWrapperBasePinholeT<T>::pointJacobian2x3IF(const VectorT3<T>& flippedCameraObjectPoint, T* jx, T* jy) const
2664{
2665 ocean_assert(jx != nullptr && jy != nullptr);
2666 actualCamera_.template pointJacobian2x3IF<T, true>(flippedCameraObjectPoint, jx, jy);
2667}
2668
2669template <typename T>
2670inline bool CameraWrapperBasePinholeT<T>::isEqual(const CameraWrapperBasePinholeT<T>& basePinhole, const T eps) const
2671{
2672 ocean_assert(eps >= T(0));
2673
2674 return actualCamera_.isEqual(basePinhole.actualCamera_, eps);
2675}
2676
2677template <typename T>
2679{
2680 return actualCamera_.isValid();
2681}
2682
2683template <typename T>
2684template <typename U>
2685inline std::unique_ptr<AnyCameraT<U>> CameraWrapperBasePinholeT<T>::clone(const unsigned int width, const unsigned int height) const
2686{
2687 ocean_assert(actualCamera_.isValid());
2688
2689 if constexpr (std::is_same<T, U>::value)
2690 {
2691 if ((width == 0u && height == 0u) || (width == actualCamera_.width() && height == actualCamera_.height()))
2692 {
2693 return std::make_unique<AnyCameraWrappingT<U, CameraWrapperT<U, CameraWrapperBasePinholeT<U>>>>(actualCamera_);
2694 }
2695
2696 const unsigned int validWidth = (height * actualCamera_.width() + actualCamera_.height() / 2u) / actualCamera_.height();
2697 const unsigned int validHeight = (width * actualCamera_.height() + actualCamera_.width() / 2u) / actualCamera_.width();
2698
2699 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
2700 {
2701 ocean_assert(false && "Wrong aspect ratio!");
2702 return nullptr;
2703 }
2704
2705 return std::make_unique<AnyCameraWrappingT<U, CameraWrapperT<U, CameraWrapperBasePinholeT<U>>>>(PinholeCameraT<U>(width, height, actualCamera_));
2706 }
2707 else
2708 {
2709 const PinholeCameraT<U> convertedPinholeCamera(actualCamera_);
2710
2711 if ((width == 0u && height == 0u) || (width == actualCamera_.width() && height == actualCamera_.height()))
2712 {
2713 return std::make_unique<AnyCameraWrappingT<U, CameraWrapperT<U, CameraWrapperBasePinholeT<U>>>>(convertedPinholeCamera);
2714 }
2715
2716 const unsigned int validWidth = (height * actualCamera_.width() + actualCamera_.height() / 2u) / actualCamera_.height();
2717 const unsigned int validHeight = (width * actualCamera_.height() + actualCamera_.width() / 2u) / actualCamera_.width();
2718
2719 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
2720 {
2721 ocean_assert(false && "Wrong aspect ratio!");
2722 return nullptr;
2723 }
2724
2725 return std::make_unique<AnyCameraWrappingT<U, CameraWrapperT<U, CameraWrapperBasePinholeT<U>>>>(PinholeCameraT<U>(width, height, convertedPinholeCamera));
2726 }
2727}
2728
2729template <typename T>
2734
2735template <typename T>
2737{
2738 return std::string("Ocean Pinhole");
2739}
2740
2741template <typename T>
2743 actualCamera_(std::move(camera))
2744{
2745 // nothing to do here
2746}
2747
2748template <typename T>
2750 actualCamera_(camera)
2751{
2752 // nothing to do here
2753}
2754
2755template <typename T>
2757{
2758 return actualCamera_;
2759}
2760
2761template <typename T>
2762inline unsigned int CameraWrapperBaseFisheyeT<T>::width() const
2763{
2764 return actualCamera_.width();
2765}
2766
2767template <typename T>
2768inline unsigned int CameraWrapperBaseFisheyeT<T>::height() const
2769{
2770 return actualCamera_.height();
2771}
2772
2773template <typename T>
2775{
2776 return actualCamera_.principalPoint();
2777}
2778
2779template <typename T>
2781{
2782 return actualCamera_.principalPointX();
2783}
2784
2785template <typename T>
2787{
2788 return actualCamera_.principalPointY();
2789}
2790
2791template <typename T>
2793{
2794 return actualCamera_.focalLengthX();
2795}
2796
2797template <typename T>
2799{
2800 return actualCamera_.focalLengthY();
2801}
2802
2803template <typename T>
2805{
2806 return actualCamera_.inverseFocalLengthX();
2807}
2808
2809template <typename T>
2811{
2812 return actualCamera_.inverseFocalLengthY();
2813}
2814
2815template <typename T>
2817{
2818 return actualCamera_.projectToImageIF(objectPoint);
2819}
2820
2821template <typename T>
2822inline VectorT2<T> CameraWrapperBaseFisheyeT<T>::projectToImageIF(const HomogenousMatrixT4<T>& flippedCamera_T_world, const VectorT3<T>& objectPoint) const
2823{
2824 return actualCamera_.projectToImageIF(flippedCamera_T_world, objectPoint);
2825}
2826
2827template <typename T>
2828inline void CameraWrapperBaseFisheyeT<T>::projectToImageIF(const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const
2829{
2830 ocean_assert(size == 0 || objectPoints != nullptr);
2831 ocean_assert(size == 0 || imagePoints != nullptr);
2832
2833 for (size_t n = 0; n < size; ++n)
2834 {
2835 imagePoints[n] = projectToImageIF(objectPoints[n]);
2836 }
2837}
2838
2839template <typename T>
2840inline void CameraWrapperBaseFisheyeT<T>::projectToImageIF(const HomogenousMatrixT4<T>& flippedCamera_T_world, const VectorT3<T>* objectPoints, const size_t size, VectorT2<T>* imagePoints) const
2841{
2842 ocean_assert(size == 0 || objectPoints != nullptr);
2843 ocean_assert(size == 0 || imagePoints != nullptr);
2844
2845 for (size_t n = 0; n < size; ++n)
2846 {
2847 imagePoints[n] = projectToImageIF(flippedCamera_T_world, objectPoints[n]);
2848 }
2849}
2850
2851template <typename T>
2852inline VectorT3<T> CameraWrapperBaseFisheyeT<T>::vectorIF(const VectorT2<T>& distortedImagePoint, const bool makeUnitVector) const
2853{
2854 return actualCamera_.vectorIF(distortedImagePoint, makeUnitVector);
2855}
2856
2857template <typename T>
2858inline void CameraWrapperBaseFisheyeT<T>::vectorIF(const VectorT2<T>* distortedImagePoints, const size_t size, VectorT3<T>* vectors, const bool makeUnitVector) const
2859{
2860 ocean_assert(distortedImagePoints != nullptr && size > 0);
2861 ocean_assert(vectors != nullptr);
2862
2863 for (size_t n = 0; n < size; ++n)
2864 {
2865 vectors[n] = vectorIF(distortedImagePoints[n], makeUnitVector);
2866 }
2867}
2868
2869template <typename T>
2870inline void CameraWrapperBaseFisheyeT<T>::pointJacobian2x3IF(const VectorT3<T>& flippedCameraObjectPoint, T* jx, T* jy) const
2871{
2872 actualCamera_.pointJacobian2x3IF(flippedCameraObjectPoint, jx, jy);
2873}
2874
2875template <typename T>
2876inline bool CameraWrapperBaseFisheyeT<T>::isEqual(const CameraWrapperBaseFisheyeT& baseFisheye, const T eps) const
2877{
2878 ocean_assert(eps >= T(0));
2879
2880 return actualCamera_.isEqual(baseFisheye.actualCamera_, eps);
2881}
2882
2883template <typename T>
2885{
2886 return actualCamera_.isValid();
2887}
2888
2889template <typename T>
2890template <typename U>
2891inline std::unique_ptr<AnyCameraT<U>> CameraWrapperBaseFisheyeT<T>::clone(const unsigned int width, const unsigned int height) const
2892{
2893 ocean_assert(actualCamera_.isValid());
2894
2895 if ((width == 0u && height == 0u) || (width == actualCamera_.width() && height == actualCamera_.height()))
2896 {
2897 return std::make_unique<AnyCameraWrappingT<U, CameraWrapperT<U, CameraWrapperBaseFisheyeT<U>>>>(FisheyeCameraT<U>(actualCamera_));
2898 }
2899
2900 const unsigned int validWidth = (height * actualCamera_.width() + actualCamera_.height() / 2u) / actualCamera_.height();
2901 const unsigned int validHeight = (width * actualCamera_.height() + actualCamera_.width() / 2u) / actualCamera_.width();
2902
2903 if (!NumericT<unsigned int>::isEqual(width, validWidth, 1u) && !NumericT<unsigned int>::isEqual(height, validHeight, 1u))
2904 {
2905 ocean_assert(false && "Wrong aspect ratio!");
2906 return nullptr;
2907 }
2908
2909 const T xFactor = T(width) / T(actualCamera_.width());
2910 const T yFactor = T(height) / T(actualCamera_.height());
2911
2912 const U newPrincipalX = U(actualCamera_.principalPointX() * xFactor);
2913 const U newPrincipalY = U(actualCamera_.principalPointY() * yFactor);
2914
2915 const U newFocalLengthX = U(actualCamera_.focalLengthX() * xFactor);
2916 const U newFocalLengthY = U(actualCamera_.focalLengthY() * yFactor);
2917
2918 U radialDistortion[6];
2919 for (unsigned int n = 0u; n < 6u; ++n)
2920 {
2921 radialDistortion[n] = U(actualCamera_.radialDistortion()[n]);
2922 }
2923
2924 const U tangentialDistortion[2] =
2925 {
2926 U(actualCamera_.tangentialDistortion()[0]),
2927 U(actualCamera_.tangentialDistortion()[1])
2928 };
2929
2930 return std::make_unique<AnyCameraWrappingT<U, CameraWrapperT<U, CameraWrapperBaseFisheyeT<U>>>>(FisheyeCameraT<U>(width, height, newFocalLengthX, newFocalLengthY, newPrincipalX, newPrincipalY, radialDistortion, tangentialDistortion));
2931}
2932
2933template <typename T>
2938
2939template <typename T>
2941{
2942 return std::string("Ocean Fisheye");
2943}
2944
2945template <typename T>
2947 actualCamera_(std::move(camera))
2948{
2949 // nothing to do here
2950}
2951
2952template <typename T>
2954 actualCamera_(camera)
2955{
2956 // nothing to do here
2957}
2958
2959template <typename T>
2961{
2962 Log::error() << "Invalid camera: " << actualCamera_.reason();
2963
2964 ocean_assert(false && "This function must never be called.");
2965
2966 return actualCamera_;
2967}
2968
2969template <typename T>
2970inline unsigned int CameraWrapperBaseInvalidT<T>::width() const
2971{
2972 Log::error() << "Invalid camera: " << actualCamera_.reason();
2973
2974 ocean_assert(false && "This function must never be called.");
2975
2976 return (unsigned int)(-1);
2977}
2978
2979template <typename T>
2980inline unsigned int CameraWrapperBaseInvalidT<T>::height() const
2981{
2982 Log::error() << "Invalid camera: " << actualCamera_.reason();
2983
2984 ocean_assert(false && "This function must never be called.");
2985
2986 return (unsigned int)(-1);
2987}
2988
2989template <typename T>
2991{
2992 Log::error() << "Invalid camera: " << actualCamera_.reason();
2993
2994 ocean_assert(false && "This function must never be called.");
2995
2997}
2998
2999template <typename T>
3001{
3002 Log::error() << "Invalid camera: " << actualCamera_.reason();
3003
3004 ocean_assert(false && "This function must never be called.");
3005
3006 return NumericT<T>::minValue();
3007}
3008
3009template <typename T>
3011{
3012 Log::error() << "Invalid camera: " << actualCamera_.reason();
3013
3014 ocean_assert(false && "This function must never be called.");
3015
3016 return NumericT<T>::minValue();
3017}
3018
3019template <typename T>
3021{
3022 Log::error() << "Invalid camera: " << actualCamera_.reason();
3023
3024 ocean_assert(false && "This function must never be called.");
3025
3026 return NumericT<T>::minValue();
3027}
3028
3029template <typename T>
3031{
3032 Log::error() << "Invalid camera: " << actualCamera_.reason();
3033
3034 ocean_assert(false && "This function must never be called.");
3035
3036 return NumericT<T>::minValue();
3037}
3038
3039template <typename T>
3041{
3042 Log::error() << "Invalid camera: " << actualCamera_.reason();
3043
3044 ocean_assert(false && "This function must never be called.");
3045
3046 return NumericT<T>::minValue();
3047}
3048
3049template <typename T>
3051{
3052 Log::error() << "Invalid camera: " << actualCamera_.reason();
3053
3054 ocean_assert(false && "This function must never be called.");
3055
3056 return NumericT<T>::minValue();
3057}
3058
3059template <typename T>
3061{
3062 Log::error() << "Invalid camera: " << actualCamera_.reason();
3063
3064 ocean_assert(false && "This function must never be called.");
3065
3067}
3068
3069template <typename T>
3070inline VectorT2<T> CameraWrapperBaseInvalidT<T>::projectToImageIF(const HomogenousMatrixT4<T>& /*flippedCamera_T_world*/, const VectorT3<T>& /*objectPoint*/) const
3071{
3072 Log::error() << "Invalid camera: " << actualCamera_.reason();
3073
3074 ocean_assert(false && "This function must never be called.");
3075
3077}
3078
3079template <typename T>
3080inline void CameraWrapperBaseInvalidT<T>::projectToImageIF(const VectorT3<T>* /*objectPoints*/, const size_t /*size*/, VectorT2<T>* /*imagePoints*/) const
3081{
3082 Log::error() << "Invalid camera: " << actualCamera_.reason();
3083
3084 ocean_assert(false && "This function must never be called.");
3085
3086}
3087
3088template <typename T>
3089inline void CameraWrapperBaseInvalidT<T>::projectToImageIF(const HomogenousMatrixT4<T>& /*flippedCamera_T_world*/, const VectorT3<T>* /*objectPoints*/, const size_t /*size*/, VectorT2<T>* /*imagePoints*/) const
3090{
3091 Log::error() << "Invalid camera: " << actualCamera_.reason();
3092
3093 ocean_assert(false && "This function must never be called.");
3094}
3095
3096template <typename T>
3097inline VectorT3<T> CameraWrapperBaseInvalidT<T>::vectorIF(const VectorT2<T>& /*distortedImagePoint*/, const bool /*makeUnitVector*/) const
3098{
3099 Log::error() << "Invalid camera: " << actualCamera_.reason();
3100
3101 ocean_assert(false && "This function must never be called.");
3102
3104}
3105
3106template <typename T>
3107inline void CameraWrapperBaseInvalidT<T>::vectorIF(const VectorT2<T>* /*distortedImagePoints*/, const size_t /*size*/, VectorT3<T>* /*vectors*/, const bool /*makeUnitVector*/) const
3108{
3109 Log::error() << "Invalid camera: " << actualCamera_.reason();
3110
3111 ocean_assert(false && "This function must never be called.");
3112}
3113
3114template <typename T>
3115inline void CameraWrapperBaseInvalidT<T>::pointJacobian2x3IF(const VectorT3<T>& /*flippedCameraObjectPoint*/, T* /*jx*/, T* /*jy*/) const
3116{
3117 Log::error() << "Invalid camera: " << actualCamera_.reason();
3118
3119 ocean_assert(false && "This function must never be called.");
3120}
3121
3122template <typename T>
3123inline bool CameraWrapperBaseInvalidT<T>::isEqual(const CameraWrapperBaseInvalidT& /*baseFisheye*/, const T /*eps*/) const
3124{
3125 Log::error() << "Invalid camera: " << actualCamera_.reason();
3126
3127 ocean_assert(false && "This function must never be called.");
3128
3129 return false;
3130}
3131
3132template <typename T>
3134{
3135 return false;
3136}
3137
3138template <typename T>
3139template <typename U>
3140inline std::unique_ptr<AnyCameraT<U>> CameraWrapperBaseInvalidT<T>::clone(const unsigned int /*width*/, const unsigned int /*height*/) const
3141{
3142 Log::error() << "Invalid camera: " << actualCamera_.reason();
3143
3144 ocean_assert(false && "This function must never be called.");
3145
3146 return nullptr;
3147}
3148
3149template <typename T>
3154
3155template <typename T>
3157{
3158 return std::string("Invalid camera");
3159}
3160
3161template <typename T>
3162InvalidCameraT<T>::InvalidCameraT(const std::string& reason) :
3163 reason_(reason)
3164{
3165 // nothing to do here
3166}
3167
3168template <typename T>
3169const std::string& InvalidCameraT<T>::reason() const
3170{
3171 return reason_;
3172}
3173
3174}
3175
3176#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:2780
T inverseFocalLengthX() const
Returns the inverse horizontal focal length parameter.
Definition AnyCamera.h:2804
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:2768
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:2870
unsigned int width() const
Returns the width of the camera image.
Definition AnyCamera.h:2762
bool isValid() const
Returns whether this camera is valid.
Definition AnyCamera.h:2884
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:2810
static AnyCameraType anyCameraType()
Returns the type of this camera.
Definition AnyCamera.h:2934
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:2852
const ActualCamera & actualCamera() const
Returns the actual camera object wrapped in this class.
Definition AnyCamera.h:2756
VectorT2< T > principalPoint() const
Returns the coordinate of the principal point of the camera image in the pixel domain.
Definition AnyCamera.h:2774
T principalPointY() const
Returns the y-value of the principal point of the camera image in the pixel domain.
Definition AnyCamera.h:2786
static std::string name()
Returns the name of this camera.
Definition AnyCamera.h:2940
T focalLengthX() const
Returns the horizontal focal length parameter.
Definition AnyCamera.h:2792
T focalLengthY() const
Returns the vertical focal length parameter.
Definition AnyCamera.h:2798
VectorT2< T > projectToImageIF(const VectorT3< T > &objectPoint) const
Projects a 3D object point into the camera frame.
Definition AnyCamera.h:2816
CameraWrapperBaseFisheyeT(ActualCamera &&actualCamera)
Creates a new CameraWrapperBaseFisheyeT object wrapping the actual camera model.
Definition AnyCamera.h:2742
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:2891
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:2876
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:3123
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:3060
CameraWrapperBaseInvalidT(ActualCamera &&actualCamera)
Creates a new CameraWrapperBaseInvalidT object wrapping the actual camera model.
Definition AnyCamera.h:2946
unsigned int height() const
Returns the height of the camera image.
Definition AnyCamera.h:2980
const ActualCamera & actualCamera() const
Returns the actual camera object wrapped in this class.
Definition AnyCamera.h:2960
static std::string name()
Returns the name of this camera.
Definition AnyCamera.h:3156
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:3000
VectorT2< T > principalPoint() const
Returns the coordinate of the principal point of the camera image in the pixel domain.
Definition AnyCamera.h:2990
T inverseFocalLengthX() const
Returns the inverse horizontal focal length parameter.
Definition AnyCamera.h:3040
bool isValid() const
Returns whether this camera is valid.
Definition AnyCamera.h:3133
static AnyCameraType anyCameraType()
Returns the type of this camera.
Definition AnyCamera.h:3150
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:3140
T inverseFocalLengthY() const
Returns the inverse vertical focal length parameter.
Definition AnyCamera.h:3050
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:3115
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:3097
T focalLengthY() const
Returns the vertical focal length parameter.
Definition AnyCamera.h:3030
T principalPointY() const
Returns the y-value of the principal point of the camera image in the pixel domain.
Definition AnyCamera.h:3010
T focalLengthX() const
Returns the horizontal focal length parameter.
Definition AnyCamera.h:3020
unsigned int width() const
Returns the width of the camera image.
Definition AnyCamera.h:2970
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:2595
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:2663
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:2565
bool isValid() const
Returns whether this camera is valid.
Definition AnyCamera.h:2678
T principalPointY() const
Returns the y-value of the principal point of the camera image in the pixel domain.
Definition AnyCamera.h:2577
T inverseFocalLengthY() const
Returns the inverse vertical focal length parameter.
Definition AnyCamera.h:2601
static std::string name()
Returns the name of this camera.
Definition AnyCamera.h:2736
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:2553
unsigned int width() const
Returns the width of the camera image.
Definition AnyCamera.h:2559
CameraWrapperBasePinholeT(ActualCamera &&actualCamera)
Creates a new CameraWrapperBasePinholeT object wrapping the actual camera model.
Definition AnyCamera.h:2539
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:2643
VectorT2< T > projectToImageIF(const VectorT3< T > &objectPoint) const
Projects a 3D object point into the camera frame.
Definition AnyCamera.h:2607
static AnyCameraType anyCameraType()
Returns the type of this camera.
Definition AnyCamera.h:2730
T principalPointX() const
Returns the x-value of the principal point of the camera image in the pixel domain.
Definition AnyCamera.h:2571
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:2670
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:2685
T focalLengthY() const
Returns the vertical focal length parameter.
Definition AnyCamera.h:2589
T focalLengthX() const
Returns the horizontal focal length parameter.
Definition AnyCamera.h:2583
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:2509
T fovY() const
Returns the field of view in x direction of the camera.
Definition AnyCamera.h:2414
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:2488
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:2525
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:2443
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:2457
This class implements an finite line in 2D space.
Definition FiniteLine2.h:82
Class representing a fisheye camera.
Definition FisheyeCamera.h:106
This class implements a 4x4 homogeneous transformation matrix using floating point values with the pr...
Definition HomogenousMatrix4.h:110
SquareMatrixT3< T > rotationMatrix() const
Returns the rotation matrix of the transformation.
Definition HomogenousMatrix4.h:1493
VectorT3< T > translation() const
Returns the translation of the transformation.
Definition HomogenousMatrix4.h:1381
bool isValid() const
Returns whether this matrix is a valid homogeneous transformation.
Definition HomogenousMatrix4.h:1806
This class implements invalid camera profiles, e.g.
Definition AnyCamera.h:1420
const std::string & reason() const
Returns the reason of this invalid camera.
Definition AnyCamera.h:3169
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:3162
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 T abs(const T value)
Returns the absolute value of a given value.
Definition Numeric.h:1220
static bool isEqual(const T first, const T second)
Returns whether two values are equal up to a small epsilon.
Definition Numeric.h:2395
static constexpr T sqr(const T value)
Returns the square of a given value.
Definition Numeric.h:1499
Definition of a pinhole camera model.
Definition PinholeCamera.h:114
This class implements a vector with two elements.
Definition Vector2.h:96
const T & x() const noexcept
Returns the x value.
Definition Vector2.h:710
const T & y() const noexcept
Returns the y value.
Definition Vector2.h:722
bool isNull() const
Returns whether this vector is a null vector up to a small epsilon.
Definition Vector2.h:746
T sqrDistance(const VectorT2< T > &right) const
Returns the square distance between this 2D position and a second 2D position.
Definition Vector2.h:645
This class implements a vector with three elements.
Definition Vector3.h:97
const T & y() const noexcept
Returns the y value.
Definition Vector3.h:824
const T & x() const noexcept
Returns the x value.
Definition Vector3.h:812
VectorT2< T > xy() const noexcept
Returns the x and y component of the vector as new 2D vector.
Definition Vector3.h:848
static VectorT3< T > minValue()
Returns a 3D vector with all elements set to NumericT::minValue().
Definition Vector3.h:1059
const T & z() const noexcept
Returns the z value.
Definition Vector3.h:836
std::shared_ptr< AnyCameraD > SharedAnyCameraD
Definition of a shared pointer holding an AnyCamera object with double precision.
Definition AnyCamera.h:68
std::shared_ptr< AnyCamera > SharedAnyCamera
Definition of a shared pointer holding an AnyCamera object with Scalar precision.
Definition AnyCamera.h:61
std::vector< FiniteLineT2< T > > FiniteLinesT2
Definition of a typename alias for vectors with FiniteLineT2 objects.
Definition FiniteLine2.h:50
std::vector< VectorT2< T > > VectorsT2
Definition of a typename alias for vectors with VectorT2 objects.
Definition Vector2.h:57
SharedAnyCamerasT< float > SharedAnyCamerasF
Definition of a vector holding AnyCameraF objects.
Definition AnyCamera.h:105
SharedAnyCamerasT< double > SharedAnyCamerasD
Definition of a vector holding AnyCameraD objects.
Definition AnyCamera.h:98
AnyCameraType
Definition of individual camera types.
Definition AnyCamera.h:112
std::shared_ptr< AnyCameraF > SharedAnyCameraF
Definition of a shared pointer holding an AnyCamera object with float precision.
Definition AnyCamera.h:75
std::vector< std::shared_ptr< AnyCameraT< T > > > SharedAnyCamerasT
Definition of a typename alias for vectors with shared AnyCameraT objects.
Definition AnyCamera.h:84
SharedAnyCamerasT< Scalar > SharedAnyCameras
Definition of a vector holding AnyCamera objects.
Definition AnyCamera.h:91
std::shared_ptr< AnyCameraT< T > > SharedAnyCameraT
Definition of a shared pointer holding an AnyCamera object with Scalar precision.
Definition AnyCamera.h:54
@ FISHEYE
A fisheye camera.
@ PINHOLE
A pinhole camera.
@ INVALID
An invalid camera type.
The namespace covering the entire Ocean framework.
Definition Accessor.h:15