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