Ocean
Loading...
Searching...
No Matches
Database.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_TRACKING_DATABASE_H
9#define META_OCEAN_TRACKING_DATABASE_H
10
12
13#include "ocean/base/Accessor.h"
15#include "ocean/base/Subset.h"
16#include "ocean/base/Worker.h"
17
20
21namespace Ocean
22{
23
24namespace Tracking
25{
26
27/**
28 * This class implements a database for 3D object points, 2D image points and 6DOF camera poses.
29 * Any 2D image point is located in a camera frame, while any camera frame has an own camera pose.<br>
30 * Corresponding image points in consecutive camera frames can belong to the same 3D object point.<br>
31 * This database stores ids for image points, object points, priority values of object points, camera poses and field of views of camera poses.<br>
32 * Further, the topology between the individual database elements can be defined.<br>
33 * The locations of the image points (2D positions within the camera frames) must be valid always.<br>
34 * The locations of the object points or the transformation values of the camera poses may be invalid as in this case the location of the transformation has not been determined yet.<br>
35 *
36 * An id of an image point has the following connections:
37 * <pre>
38 * image point id -> 2D point location (always valid)
39 * -> camera pose id (the id of the camera pose in which frame the image point is located)
40 * -> 3D object point id (the id of the object point which projects to the image point)
41 * </pre>
42 *
43 * Due to performance issues object points and camera poses store mappings to their corresponding image points.<br>
44 * An id of an object point has the following connections:
45 * <pre>
46 * object point id -> 3D point location (may be invalid)
47 * -> Priority value
48 * -> image point ids (the ids of all image points which are projections of the object points)
49 * </pre>
50 * An id of a camera pose has the following connections:
51 * <pre>
52 * camera pose id -> 6DOF pose (may be invalid)
53 * -> Field of View value
54 * -> image point ids (the ids of all image points visible in the camera frame belonging to the camera pose)
55 * </pre>
56 *
57 * Finally, the database stores a mapping between a pair of pose ids and object points ids and image points ids:
58 * <pre>
59 * pose id, object point id -> image point id
60 * </pre>
61 *
62 * The internal data structure of this database allows arbitrary element access with almost O(log n).<br>
63 * Due to the performance issue connections between the individual objects are necessary.<br>
64 * @ingroup tracking
65 */
66class OCEAN_TRACKING_EXPORT Database
67{
68 public:
69
70 /**
71 * Definition of an invalid id.
72 */
73 const static Index32 invalidId = Index32(-1);
74
75 /**
76 * Returns an invalid object point.
77 * @return Invalid object point
78 */
79 static inline Vector3 invalidObjectPoint();
80
81 /**
82 * Definition of a map mapping ids to 2D image point object.
83 */
84 using IdPointMap = std::map<Index32, Vector2>;
85
86 /**
87 * Definition of a pair of ids and 2D image points.
88 */
89 using IdPointPair = std::pair<Index32, Vector2>;
90
91 /**
92 * Definition of a vector holding pairs of ids and 2D image points.
93 */
94 using IdPointPairs = std::vector<IdPointPair>;
95
96 /**
97 * Definition of a map mapping ids to 2D image point id pairs.
98 */
99 using IdIdPointPairsMap = std::map<Index32, IdPointPairs>;
100
101 /**
102 * Definition of a map mapping ids to 2D vectors.
103 */
104 using ImagePointsMap = std::map<Index32, Vectors2>;
105
106 /**
107 * Definition of a vector holding 2D vectors.
108 */
109 using ImagePointGroups = std::vector<Vectors2>;
110
111 /**
112 * This class implements an object storing an id of an image point.
113 */
115 {
116 public:
117
118 /**
119 * Creates a new object.
120 * @param imagePointId The id of the image point, may be invalid
121 */
122 explicit inline ImagePointObject(const Index32 imagePointId = invalidId);
123
124 /**
125 * Returns the id of the image point of this object.
126 * @return The image point id, may be invalid
127 */
128 inline Index32 imagePointId() const;
129
130 /**
131 * Sets or changes the id of the image point of this object.
132 * @param imagePointId The image point id to be set, may be invalid
133 */
134 inline void setImagePointId(const Index32 imagePointId);
135
136 protected:
137
138 /// The image point id of this object.
139 Index32 imagePointId_ = invalidId;
140 };
141
142 /**
143 * This class implements an object storing an id of an object point.
144 */
146 {
147 public:
148
149 /**
150 * Creates a new object.
151 * @param objectPointId The id of the object point, may be invalid
152 */
153 explicit inline ObjectPointObject(const Index32 objectPointId = invalidId);
154
155 /**
156 * Returns the id of the object point of this object.
157 * @return The object point id, may be invalid
158 */
159 inline Index32 objectPointId() const;
160
161 /**
162 * Sets or changes the id of the object point of this object.
163 * @param objectPointId The object point id to be set, may be invalid
164 */
165 inline void setObjectPointId(const Index32 objectPointId);
166
167 protected:
168
169 /// The object point id of this object.
170 Index32 objectPointId_ = invalidId;
171 };
172
173 /**
174 * This class implements an object storing an id of an pose object.
175 */
177 {
178 public:
179
180 /**
181 * Creates a new object.
182 * @param poseId The id of the pose, may be invalid
183 */
184 explicit inline PoseObject(const Index32 poseId = invalidId);
185
186 /**
187 * Returns the id of the camera pose of this object.
188 * @return The camera pose id, may be invalid
189 */
190 inline Index32 poseId() const;
191
192 /**
193 * Sets or changes the id of the camera pose of this object.
194 * @param poseId The camera pose id to set, may be invalid
195 */
196 inline void setPoseId(const Index32 poseId);
197
198 protected:
199
200 /// The camera pose id of this object.
201 Index32 poseId_ = invalidId;
202 };
203
204 /**
205 * This class defines the topology between a camera pose id, an object point id and an image point id.
206 * An image point can be visible in only one camera frame, while the camera frame belongs to only one camera pose.<br>
207 * The image point can be a projection of only one object point if a valid camera pose is known.<br>
208 */
210 public PoseObject,
211 public ObjectPointObject,
212 public ImagePointObject
213 {
214 public:
215
216 /**
217 * Creates a new topology object.
218 * @param poseId The id of the camera pose of the new object
219 * @param objectPointId The id of the object point of the new object
220 * @param imagePointId The id of the image point of the new object
221 */
222 explicit inline TopologyTriple(const Index32 poseId = invalidId, const Index32 objectPointId = invalidId, const Index32 imagePointId = invalidId);
223 };
224
225 /**
226 * This class stores a pair of pose id and image point id.
227 */
229 public ImagePointObject,
230 public PoseObject
231 {
232 public:
233
234 /**
235 * Creates a new pair object.
236 * @param poseId The id of the pose, may be invalid
237 * @param imagePointId The id of the image point, may be invalid
238 */
239 explicit inline PoseImagePointPair(const Index32 poseId = invalidId, const Index32 imagePointId = invalidId);
240 };
241
242 /**
243 * Definition of a vector holding several pairs of pose and image point ids.
244 */
245 using PoseImagePointTopology = std::vector<PoseImagePointPair>;
246
247 /**
248 * Definition of a vector holding several groups of pairs of pose and image point ids.
249 */
250 using PoseImagePointTopologyGroups = std::vector< std::pair<Index32, PoseImagePointTopology> >;
251
252 /**
253 * Definition of a vector holding object of topology triple.
254 */
255 using TopologyTriples = std::vector<TopologyTriple>;
256
257 /**
258 * This class implements an accessor object for image points based on a set of image point ids.
259 * @tparam tThreadSafe True, to call the thread-safe functions of the database
260 */
261 template <bool tThreadSafe>
263 {
264 public:
265
266 /**
267 * Creates a new accessor object by providing the references of the database and the image point ids.
268 * Beware: Neither the database nor the image point ids are copied; thus the given references must be valid as long as this accessor object exists.<br>
269 * @param database The database object holding the image points
270 * @param imagePointIds The image point ids of all image points that can be accessed through this object
271 */
272 inline ConstImagePointAccessorIds(const Database& database, const Indices32& imagePointIds);
273
274 /**
275 * Returns the number of image points of this accessor.
276 * @return The number of image points
277 */
278 size_t size() const override;
279
280 /**
281 * Returns a specific image point identified by the index within from the specified image point ids.
282 * @param index The index within the given image point ids, with range [0, size())
283 * @return The reference to the image point
284 */
285 const Vector2& operator[](const size_t& index) const override;
286
287 protected:
288
289 /// The reference to the database holding the individual image points.
291
292 /// The reference to the image point ids.
294 };
295
296 /**
297 * This class implements an accessor object for image points based on a topology between poses and image points.
298 * @tparam tThreadSafe True, to call the thread-safe functions of the database
299 */
300 template <bool tThreadSafe>
302 {
303 public:
304
305 /**
306 * Creates a new accessor object by providing the references of the database and the topology.
307 * Beware: Neither the database nor the image point ids are copied; thus the given references must be valid as long as this accessor object exists.<br>
308 * @param database The database object holding the image points
309 * @param topology The topology providing access to the individual image points
310 */
311 inline ConstImagePointAccessorTopology(const Database& database, const PoseImagePointTopology& topology);
312
313 /**
314 * Returns the number of image points of this accessor.
315 * @return The number of image points
316 */
317 size_t size() const override;
318
319 /**
320 * Returns a specific image point identified by the index within from the specified topology.
321 * @param index The index within the given topology, with range [0, size())
322 * @return The reference to the image point
323 */
324 const Vector2& operator[](const size_t& index) const override;
325
326 protected:
327
328 /// The reference to the database holding the individual image points.
330
331 /// The topology between poses and image points.
333 };
334
335 /**
336 * This class implements an accessor object for object points based on a set of object point ids.
337 * @tparam tThreadSafe True, to call the thread-safe functions of the database
338 */
339 template <bool tThreadSafe>
341 {
342 public:
343
344 /**
345 * Creates a new accessor object by providing the references of the database and the object point ids.
346 * Beware: Neither the database nor the object point ids are copied; thus the given references must be valid as long as this accessor object exists.<br>
347 * @param database The database object holding the object points
348 * @param objectPointIds The object point ids of all object points that can be accessed through this object
349 */
350 inline ConstObjectPointAccessorIds(const Database& database, const Indices32& objectPointIds);
351
352 /**
353 * Returns the number of object points of this accessor.
354 * @return The number of object points
355 */
356 size_t size() const override;
357
358 /**
359 * Returns a specific object point identified by the index within from the specified object point ids.
360 * @param index The index within the given object point ids, with range [0, size())
361 * @return The reference to the object point
362 */
363 const Vector3& operator[](const size_t& index) const override;
364
365 protected:
366
367 /// The reference to the database holding the individual object points.
369
370 /// The reference to the object point ids.
372 };
373
374 /**
375 * This class implements an accessor object for poses based on a set of pose ids.
376 * @tparam tThreadSafe True, to call the thread-safe functions of the database
377 */
378 template <bool tThreadSafe>
379 class ConstPoseAccessorIds : public ConstIndexedAccessor<HomogenousMatrix4>
380 {
381 public:
382
383 /**
384 * Creates a new accessor object by providing the references of the database and the pose ids.
385 * Beware: Neither the database nor the pose ids are copied; thus the given references must be valid as long as this accessor object exists.<br>
386 * @param database The database object holding the object points
387 * @param poseIds The pose ids of all poses that can be accessed through this object
388 */
389 inline ConstPoseAccessorIds(const Database& database, const Indices32& poseIds);
390
391 /**
392 * Returns the number of poses of this accessor.
393 * @return The number of poses
394 */
395 size_t size() const override;
396
397 /**
398 * Returns a specific pose identified by the index within from the specified pose ids.
399 * @param index The index within the given pose ids, with range [0, size())
400 * @return The reference to the pose
401 */
402 const HomogenousMatrix4& operator[](const size_t& index) const override;
403
404 protected:
405
406 /// The reference to the database holding the individual object points.
408
409 /// The reference to the pose ids.
411 };
412
413 /**
414 * This class implements an accessor object for poses based on a topology between poses and image points.
415 * @tparam tThreadSafe True, to call the thread-safe functions of the database
416 */
417 template <bool tThreadSafe>
418 class ConstPoseAccessorTopology : public ConstIndexedAccessor<HomogenousMatrix4>
419 {
420 public:
421
422 /**
423 * Creates a new accessor object by providing the references of the database and the topology.
424 * Beware: Neither the database nor the image point ids are copied; thus the given references must be valid as long as this accessor object exists.<br>
425 * @param database The database object holding the image points
426 * @param topology The topology providing access to the individual poses
427 */
428 inline ConstPoseAccessorTopology(const Database& database, const PoseImagePointTopology& topology);
429
430 /**
431 * Returns the number of poses of this accessor.
432 * @return The number of poses
433 */
434 size_t size() const override;
435
436 /**
437 * Returns a specific pose identified by the index within from the specified topology.
438 * @param index The index within the given topology, with range [0, size())
439 * @return The reference to the pose
440 */
441 const HomogenousMatrix4& operator[](const size_t& index) const override;
442
443 protected:
444
445 /// The reference to the database holding the individual image points.
447
448 /// The topology between poses and image points.
450 };
451
452 protected:
453
454 /**
455 * This class implements a data object storing the information connected with an id of an image point.
456 */
458 {
459 public:
460
461 /**
462 * Creates a default object.
463 */
464 ImagePointData() = default;
465
466 /**
467 * Creates a new image point object.
468 * @param point The 2D location of the new object
469 * @param poseId The id of the pose which belongs to the new object
470 * @param objectPointId The id of the object point which belongs to the new object
471 */
472 inline ImagePointData(const Vector2& point, const Index32 poseId = invalidId, const Index32 objectPointId = invalidId);
473
474 /**
475 * Returns the 2D location of the image point of this object.
476 * @return The 2D image point
477 */
478 inline const Vector2& point() const;
479
480 /**
481 * Returns the id of the pose which belongs to the image point of this object.
482 * @return The camera pose id, an invalid id if no pose has been registered
483 */
484 inline Index32 poseId() const;
485
486 /**
487 * Returns the ids of the 3D object point which belongs to the image point of this object.
488 * @return The object point id, an invalid id if no object point has been registered
489 */
490 inline Index32 objectPointId() const;
491
492 /**
493 * Sets the location of the image point of this object.
494 * @param point The 2D location of the image point
495 */
496 inline void setPoint(const Vector2& point);
497
498 /**
499 * Sets the id of the pose belonging to this image point object.
500 * @param poseId The pose id to be set
501 */
502 inline void setPoseId(const Index32 poseId);
503
504 /**
505 * Sets the id of the object point belonging to this image point object.
506 * @param objectPointId The object point id to be set
507 */
508 inline void setObjectPointId(const Index32 objectPointId);
509
510 protected:
511
512 /// The location of the 2D image point of this object.
513 Vector2 point_ = Vector2(Numeric::minValue(), Numeric::minValue());
514
515 /// The id of the pose which belongs to this object.
516 Index32 poseId_ = invalidId;
517
518 /// The id of the object point which belongs to this object.
519 Index32 objectPointId_ = invalidId;
520 };
521
522 /**
523 * The base class for all data object storing a set of image point ids.
524 */
525 class Data
526 {
527 public:
528
529 /**
530 * Returns the image point ids of this object.
531 * @return Image point ids
532 */
533 inline const IndexSet32& imagePointIds() const;
534
535 /**
536 * Registers (adds) a new image point id at this data object.
537 * @param imagePointId The new id to be registered, must be valid and must not already be part of this data object
538 */
539 inline void registerImagePoint(const Index32 imagePointId);
540
541 /**
542 * Unregisters (removes) an image point id from this data object.
543 * @param imagePointId The id to be unregistered, must be valid and must be part of this data object
544 */
545 inline void unregisterImagePoint(const Index32 imagePointId);
546
547 protected:
548
549 /// The set of registered image point ids of this object.
551 };
552
553 /**
554 * The data object encapsulating a 6DOF camera pose.
555 */
556 class PoseData : public Data
557 {
558 public:
559
560 /**
561 * Creates a new object with specified pose.
562 * @param world_T_camera The pose of this object, may be invalid if e.g., unknown at this moment
563 * @param fov The fov value of this object, may be invalid if e.g., unknown at this moment
564 */
565 explicit inline PoseData(const HomogenousMatrix4& world_T_camera = HomogenousMatrix4(false), const Scalar fov = -1);
566
567 /**
568 * Returns the pose of this object.
569 * @return The object's pose, may be invalid
570 */
571 inline const HomogenousMatrix4& pose() const;
572
573 /**
574 * Returns the field of view value of this object.
575 * @return The fov value, may be invalid
576 */
577 inline Scalar fov() const;
578
579 /**
580 * Sets (changes) the pose of this object.
581 * @param world_T_camera The pose to be set, may be invalid
582 */
583 inline void setPose(const HomogenousMatrix4& world_T_camera);
584
585 /**
586 * Sets (changes) the field of view value of this object.
587 * @param fov The fov value to be set, may be invalid
588 */
589 inline void setFov(const Scalar fov);
590
591 protected:
592
593 /// The pose of this object.
594 HomogenousMatrix4 world_T_camera_ = HomogenousMatrix4(false);
595
596 /// The field of view value of this object.
597 Scalar fov_ = Scalar(-1);
598 };
599
600 /**
601 * The data object encapsulating a 3D object point.
602 */
603 class ObjectPointData : public Data
604 {
605 public:
606
607 /**
608 * Creates an object with invalid object point.
609 * @param point The 3D object point of this object, may be invalid if e.g., unknown at this moment
610 * @param priority The priority value of this object, may be invalid if e.g., unknown at this moment
611 */
612 explicit inline ObjectPointData(const Vector3& point = invalidObjectPoint(), const Scalar priority = -1);
613
614 /**
615 * Returns the 3D object point of this object.
616 * @return The object point, may be invalid
617 */
618 inline const Vector3& point() const;
619
620 /**
621 * Returns the priority value of this object.
622 * @return The priority value, may be invalid
623 */
624 inline Scalar priority() const;
625
626 /**
627 * Sets (changes) the 3D object point of this object.
628 * @param point The 3D object point to be set, may be invalid
629 */
630 inline void setPoint(const Vector3& point);
631
632 /**
633 * Sets (changes) the priority value of this object.
634 * @param priority The priority value to be set, may be invalid
635 */
636 inline void setPriority(const Scalar priority);
637
638 protected:
639
640 /// The 3D object point of this object.
641 Vector3 point_ = invalidObjectPoint();
642
643 /// The priority value of this object.
644 Scalar priority_ = Scalar(-1);
645 };
646
647 /**
648 * Definition of an (ordered) map mapping pose ids to pose data objects, we use an ordered map as poses have an order.
649 */
650 using PoseMap = std::map<Index32, PoseData>;
651
652 /**
653 * Definition of an (unordered) map mapping object point ids to object point data objects.
654 */
655 using ObjectPointMap = std::unordered_map<Index32, ObjectPointData>;
656
657 /**
658 * Definition of an (unordered) map mapping image point ids to image point data objects.
659 */
660 using ImagePointMap = std::unordered_map<Index32, ImagePointData>;
661
662 /**
663 * Definition of an (unordered) map mapping 32 bit ids to 32 bit ids.
664 */
665 using Index32To32Map = std::unordered_map<Index32, Index32>;
666
667 /**
668 * Definition of an (unordered) map mapping 64 bit ids to 32 bit ids.
669 */
670 using Index64To32Map = std::unordered_map<Index64, Index32>;
671
672 public:
673
674 /**
675 * Creates a new empty database object.
676 */
677 Database() = default;
678
679 /**
680 * Copy constructor.
681 * @param database The database object to be copied
682 */
683 inline Database(const Database& database);
684
685 /**
686 * Move constructor.
687 * @param database The database object to be moved
688 */
689 inline Database(Database&& database) noexcept;
690
691 /**
692 * Returns a reference to the lock object of this database object.
693 * @return The lock object's reference
694 */
695 inline Lock& lock();
696
697 /**
698 * Returns whether this database holds at least one image point, one object point or one camera pose.
699 * @return True, if so
700 * @tparam tThreadSafe True, to call this function thread-safe
701 */
702 template <bool tThreadSafe>
703 inline bool isEmpty() const;
704
705 /**
706 * Returns the number of poses of this database.
707 * @return The database's pose number
708 */
709 template <bool tThreadSafe>
710 inline size_t poseNumber() const;
711
712 /**
713 * Returns the number of object point ids in this database.
714 * @return The database's object point id number
715 */
716 template <bool tThreadSafe>
717 inline size_t objectPointNumber() const;
718
719 /**
720 * Returns the number of image point ids in this database.
721 * @return The database's image point id number
722 */
723 template <bool tThreadSafe>
724 inline size_t imagePointNumber() const;
725
726 /**
727 * Returns the location of an image point which is specified by the id of the image point.
728 * Beware: The requested image point must exist in this database.<br>
729 * @param imagePointId The unique id of the image point, must be valid
730 * @return The location of the specified image point
731 * @tparam tThreadSafe True, to call this function thread-safe
732 */
733 template <bool tThreadSafe>
734 inline const Vector2& imagePoint(const Index32 imagePointId) const;
735
736 /**
737 * Returns the positions of 2D image points specified by the ids of the image points.
738 * @param imagePointIds The ids of the image points for which the positions will be returned, must be valid
739 * @return The resulting image point positions, one position for each id
740 * @tparam tThreadSafe True, to call this function thread-safe
741 */
742 template <bool tThreadSafe>
743 inline Vectors2 imagePoints(const Indices32& imagePointIds) const;
744
745 /**
746 * Returns the positions of 2D image points specified by the ids of the image points.
747 * @param imagePointIds The ids of the image points for which the positions will be returned, must be valid
748 * @return The resulting image point positions, one position for each id
749 * @tparam tThreadSafe True, to call this function thread-safe
750 */
751 template <bool tThreadSafe>
752 inline Vectors2 imagePoints(const IndexSet32& imagePointIds) const;
753
754 /**
755 * Returns whether an object point is visible in a specified frame, and optional the location and id of the corresponding image point.
756 * @param poseId The id of the camera pose for which the visibility of the object point is checked, must be valid
757 * @param objectPointId The unique id of the object point, must be valid
758 * @param point Optional resulting location of the image point, if any
759 * @param pointId Optional resulting unique id of the image point, if any
760 * @return True, if the defined object point has a visible image point in the specified camera pose
761 * @tparam tThreadSafe True, to call this function thread-safe
762 */
763 template <bool tThreadSafe>
764 bool hasObservation(const Index32 poseId, const Index32 objectPointId, Vector2* point = nullptr, Index32* pointId = nullptr) const;
765
766 /**
767 * Returns the location of an object point which is specified by the id of the object point.
768 * Beware: The requested object point must exist in this database.<br>
769 * @param objectPointId The unique id of the object point, must be valid
770 * @return The location of the specified object point
771 * @tparam tThreadSafe True, to call this function thread-safe
772 */
773 template <bool tThreadSafe>
774 inline const Vector3& objectPoint(const Index32 objectPointId) const;
775
776 /**
777 * Returns the location and priority of an object point which is specified by the id of the object point.
778 * Beware: The requested object point must exist in this database.<br>
779 * @param objectPointId The unique id of the object point, must be valid
780 * @param objectPointPriority The resulting priority of the specified object point
781 * @return The location of the specified object point
782 * @tparam tThreadSafe True, to call this function thread-safe
783 */
784 template <bool tThreadSafe>
785 inline const Vector3& objectPoint(const Index32 objectPointId, Scalar& objectPointPriority) const;
786
787 /**
788 * Returns the priority of an object point which is specified by the id of the object point.
789 * Beware: The requested object point must exist in this database.<br>
790 * @param objectPointId The unique id of the object point, must be valid
791 * @return The priority of the specified object point
792 * @tparam tThreadSafe True, to call this function thread-safe
793 */
794 template <bool tThreadSafe>
795 inline Scalar objectPointPriority(const Index32 objectPointId) const;
796
797 /**
798 * Returns the positions of all 3D object points.
799 * @return The resulting object point positions
800 * @tparam tThreadSafe True, to call this function thread-safe
801 */
802 template <bool tThreadSafe>
803 inline Vectors3 objectPoints() const;
804
805 /**
806 * Returns the positions of all 3D object points that match or that do not match the position of a specified reference object point and which have a specified minimal priority value.
807 * @return The resulting object point positions
808 * @param referencePosition An object point position which is used to filter the resulting object points
809 * @param objectPointIds Optional resulting ids of the resulting valid object points, on id for each object point
810 * @param minimalPriority The minimal priority value an object points must have to be returned
811 * @tparam tThreadSafe True, to call this function thread-safe
812 * @tparam tMatchPosition True, if the defined reference position will match the positions of the resulting object points; False, if the defined reference position will not match the positions of the resulting object points
813 * @see objectPointIds().
814 */
815 template <bool tThreadSafe, bool tMatchPosition>
816 inline Vectors3 objectPoints(const Vector3& referencePosition, Indices32* objectPointIds = nullptr, const Scalar minimalPriority = Scalar(-1)) const;
817
818 /**
819 * Returns the positions of 3D object points specified by the ids of the object points.
820 * @param objectPointIds The ids of the object points for which the positions will be returned, must be valid
821 * @return The resulting object point positions, one position for each id
822 * @tparam tThreadSafe True, to call this function thread-safe
823 */
824 template <bool tThreadSafe>
825 inline Vectors3 objectPoints(const Indices32& objectPointIds) const;
826
827 /**
828 * Returns the 6DOF pose of a camera frame which is specified by the id of the pose.
829 * Beware: The requested pose must exist in this database.<br>
830 * @param poseId The unique id of the pose, must be valid
831 * @return The specified pose
832 * @tparam tThreadSafe True, to call this function thread-safe
833 * @see poses().
834 */
835 template <bool tThreadSafe>
836 inline const HomogenousMatrix4& pose(const Index32 poseId) const;
837
838 /**
839 * Returns the 6DOF pose values for all specified pose ids.
840 * @param poseIds The ids of the poses for which the 6DOF values will be returned, each pose id must be valid and must exist
841 * @param size The number of given pose ids
842 * @return The resulting 6DOF pose values, one value for each id
843 * @tparam tThreadSafe True, to call this function thread-safe
844 * @see pose().
845 */
846 template <bool tThreadSafe>
847 inline HomogenousMatrices4 poses(const Index32* poseIds, const size_t size) const;
848
849 /**
850 * Returns the 3DOF rotational part of the 6DOF pose values for all specified pose ids.
851 * The camera motion of this database must be pure rotational so that the position of each camera pose is in the origin of the coordinate system.<br>
852 * @param poseIds The ids of the poses for which the rotational values will be returned, each pose id must be valid and must exist
853 * @param size The number of given pose ids
854 * @return The resulting 3DOF orientations of the camera, one value for each id
855 * @tparam tThreadSafe True, to call this function thread-safe
856 * @see pose().
857 */
858 template <bool tThreadSafe>
859 inline SquareMatrices3 rotationalPoses(const Index32* poseIds, const size_t size) const;
860
861 /**
862 * Returns all 6DOF poses which match a given reference pose or which do not match a given reference pose.
863 * @param referencePose A reference pose allowing to filter the resulting poses
864 * @param poseIds Optional resulting ids of the resulting valid poses, on id for each valid pose
865 * @return The resulting valid poses
866 * @tparam tThreadSafe True, to call this function thread-safe
867 * @tparam tMatchPose True, if the defined pose will match the values of the resulting poses; False, if the defined pose will not match the values of the resulting poses
868 * @see poseIds().
869 */
870 template <bool tThreadSafe, bool tMatchPose>
871 inline HomogenousMatrices4 poses(const HomogenousMatrix4& referencePose, Indices32* poseIds = nullptr) const;
872
873 /**
874 * Returns all 6DOF poses (valid or invalid) lying between a specified range of pose ids.
875 * For unknown frame ids an invalid pose is provided.
876 * @param lowerPoseId The id (index) of the frame defining the lower border of camera poses which will be investigated
877 * @param upperPoseId The id (index) of the frame defining the upper border of camera poses which will be investigated, with range [lowerFrame, infinity)
878 * @return The poses of this database, the first pose corresponds to the 'lowerFrame' while the last pose corresponds to the 'upperFrame'
879 * @tparam tThreadSafe True, to call this function thread-safe
880 */
881 template <bool tThreadSafe>
882 inline HomogenousMatrices4 poses(const Index32 lowerPoseId, const Index32 upperPoseId) const;
883
884 /**
885 * Returns the ids of specific 6DOF poses.
886 * @param referencePose A pose allowing to filter the resulting pose ids
887 * @param poses Optional resulting poses, on pose for each id
888 * @return The resulting ids of all poses
889 * @tparam tThreadSafe True, to call this function thread-safe
890 * @tparam tMatchPose True, if the defined pose will match the values of the resulting poses; False, if the defined pose will not match the values of the resulting poses
891 * @see poses().
892 */
893 template <bool tThreadSafe, bool tMatchPose>
894 inline Indices32 poseIds(const HomogenousMatrix4& referencePose, HomogenousMatrices4* poses = nullptr) const;
895
896 /**
897 * Returns the smallest id (the id of the lower frame border) and the largest id (the id of the upper frame border) of all poses that are known in this database.
898 * This function checks whether the pose (camera frame) is known only, thus the corresponding poses can either be valid or invalid.
899 * @param lowerPoseId Resulting id of the frame defining the lower border of the camera frames which are known
900 * @param upperPoseId Resulting id of the frame defining the upper border of the camera frames which are known
901 * @return True, if at least one pose is known
902 * @tparam tThreadSafe True, to call this function thread-safe
903 * @see validPoseBorders(), validPoseRange().
904 */
905 template <bool tThreadSafe>
906 inline bool poseBorders(Index32& lowerPoseId, Index32& upperPoseId) const;
907
908 /**
909 * Returns the smallest id (the id of the lower frame border) and the largest id (the id of the upper frame border) with a valid pose (from all known poses in this database.
910 * Beware: There may be frame ids with invalid poses in-between.
911 * @param rangeLowerPoseId Resulting id of the frame defining the lower border of the camera frames with valid pose
912 * @param rangeUpperPoseId Resulting id of the frame defining the upper border of the camera frames with valid pose
913 * @return True, if at least one valid pose is known
914 * @tparam tThreadSafe True, to call this function thread-safe
915 * @see poseBorders().
916 */
917 template <bool tThreadSafe>
918 inline bool validPoseBorders(Index32& rangeLowerPoseId, Index32& rangeUpperPoseId) const;
919
920 /**
921 * Determines the pose id range (around a specified start frame) for which the database holds valid poses.
922 * @param lowerPoseId The id of the frame defining the lower border of the camera poses which will be investigated, with range [0, infinity)
923 * @param startPoseId The id of the start frame / start pose, with range [lowerPoseId, upperPoseId]
924 * @param upperPoseId The id of the frame defining the upper border of the camera poses which will be investigated, with range [startPoseId, infinity)
925 * @param rangeLowerPoseId Resulting id of the first camera pose/camera frame with valid camera pose, with range [lowerPoseId, upperPoseId]
926 * @param rangeUpperPoseId Resulting id of the last camera pose/camera frame with valid camera pose, with range [rangeLowerPoseId, upperPoseId]
927 * @return True, if the resulting range holds at least one valid pose
928 * @tparam tThreadSafe True, to call this function thread-safe
929 * @see largestValidPoseRange(), poseBorders().
930 */
931 template <bool tThreadSafe>
932 inline bool validPoseRange(const Index32 lowerPoseId, const Index32 startPoseId, const Index32 upperPoseId, Index32& rangeLowerPoseId, Index32& rangeUpperPoseId) const;
933
934 /**
935 * Determines the largest pose id range for which the database holds valid poses.
936 * @param lowerPoseId The id of the frame defining the lower border of the camera poses which will be investigated, with range [0, infinity)
937 * @param upperPoseId The id of the frame defining the upper border of the camera poses which will be investigated, with range [lowerPoseId, infinity)
938 * @param rangeLowerPoseId Resulting id of the first camera pose/camera frame with valid camera pose, with range [lowerPoseId, upperPoseId]
939 * @param rangeUpperPoseId Resulting id of the last camera pose/camera frame with valid camera pose, with range [rangeLowerPoseId, upperPoseId]
940 * @return True, if the resulting range holds at least one valid pose
941 * @tparam tThreadSafe True, to call this function thread-safe
942 * @see validPoseRange(), poseBorders().
943 */
944 template <bool tThreadSafe>
945 inline bool largestValidPoseRange(const Index32 lowerPoseId, const Index32 upperPoseId, Index32& rangeLowerPoseId, Index32& rangeUpperPoseId) const;
946
947 /**
948 * Determines the pose id for which the database holds the most number of point correspondences (between e.g., valid or invalid object points and image points).
949 * @param lowerPoseId The id of the frame defining the lower border of the camera poses which will be investigated, with range [0, infinity)
950 * @param upperPoseId The id of the frame defining the upper border of the camera poses which will be investigated, with range [lowerPoseId, infinity)
951 * @param poseId Optional resulting id of the valid pose with most correspondences, with range [lowerPoseId, upperPoseId]
952 * @param correspondences Optional resulting number of correspondences for the resulting pose
953 * @param referenceObjectPoint A reference object point allowing to filter the correspondences to count
954 * @return True, if a pose with at least one correspondence could be found
955 * @tparam tThreadSafe True, to call this function thread-safe
956 * @tparam tMatchPosition True, if the defined position will match the positions of the correspondences; False, if the defined position will not match the positions of the correspondences
957 * @tparam tNeedValidPose True, if the pose must be valid so that the number of valid correspondences will be determined
958 * @see poseWithLeastCorrespondences().
959 */
960 template <bool tThreadSafe, bool tMatchPosition, bool tNeedValidPose>
961 inline bool poseWithMostCorrespondences(const Index32 lowerPoseId, const Index32 upperPoseId, Index32* poseId = nullptr, unsigned int* correspondences = nullptr, const Vector3& referenceObjectPoint = invalidObjectPoint()) const;
962
963 /**
964 * Determines the pose id for which the database holds the least number of point correspondences (between e.g., valid or invalid object points and image points).
965 * @param lowerPoseId The id of the frame defining the lower border of the camera poses which will be investigated, with range [0, infinity)
966 * @param upperPoseId The id of the frame defining the upper border of the camera poses which will be investigated, with range [lowerPoseId, infinity)
967 * @param poseId Optional resulting id of the valid pose with least correspondences, with range [lowerPoseId, upperPoseId]
968 * @param correspondences Optional resulting number of correspondences for the resulting pose
969 * @param referenceObjectPoint A reference object point allowing to filter the correspondences to count
970 * @tparam tThreadSafe True, to call this function thread-safe
971 * @tparam tMatchPosition True, if the defined position will match the positions of the correspondences; False, if the defined position will not match the positions of the correspondences
972 * @tparam tNeedValidPose True, if the pose must be valid so that the number of valid correspondences will be determined
973 * @see poseWithMostCorrespondences().
974 */
975 template <bool tThreadSafe, bool tMatchPosition, bool tNeedValidPose>
976 inline bool poseWithLeastCorrespondences(const Index32 lowerPoseId, const Index32 upperPoseId, Index32* poseId = nullptr, unsigned int* correspondences = nullptr, const Vector3& referenceObjectPoint = invalidObjectPoint()) const;
977
978 /**
979 * Determines the pose id from a set of given pose id candidates for which the database holds the most observations from a set of given object point ids.
980 * The major object point ids are the essential object point for which the most observations will be determined.<br>
981 * If more than one pose with the same number of most major object point observations can be determined the second set of object points (the minor object points) are used to identify the final pose with most observations.<br>
982 * @param poseCandidates The ids of all poses from which the best pose is determined
983 * @param majorObjectPointIds The ids of all major object points which are the essential object points for the resulting pose, at least one
984 * @param minorObjectPointIds The ids of all minor object points
985 * @param poseId The resulting id of the pose with most visible major object points (and minor object points, if more than two poses exist with same number of best visible major object points)
986 * @param visibleMajorObjectPointIds Optional resulting ids of all major object points visible in the resulting pose
987 * @param visibleMinorObjectPointIds Optional resulting ids of all minor object points visible in the resulting pose
988 * @return True, at least one pose exists in which at least one major object point is visible
989 * @tparam tThreadSafe True, to call this function thread-safe
990 */
991 template <bool tThreadSafe>
992 inline bool poseWithMostObservations(const IndexSet32& poseCandidates, const IndexSet32& majorObjectPointIds, const IndexSet32& minorObjectPointIds, Index32& poseId, Indices32* visibleMajorObjectPointIds = nullptr, Indices32* visibleMinorObjectPointIds = nullptr) const;
993
994 /**
995 * Counts the number of observations of a given set of object point ids for a specific camera frame.
996 * @param poseId The id of the pose for which the number of visible object points is determined
997 * @param objectPointIds the ids of the object point for which the number of observations is determined
998 * @return The number of object points (from the given set of object points) which are visible in the defined pose
999 * @tparam tThreadSafe True, to call this function thread-safe
1000 */
1001 template <bool tThreadSafe>
1002 inline unsigned int numberObservations(const Index32 poseId, const Indices32& objectPointIds) const;
1003
1004 /**
1005 * Counts the number of correspondences (e.g., valid or invalid) between image and object points for a specified pose.
1006 * @param poseId The id of the pose for which the number of point correspondences is determined
1007 * @param referenceObjectPoint A reference object point allowing to filter the correspondences to count
1008 * @param minimalPriority The minimal priority value an object point must have so that is will be investigated
1009 * @return The resulting number of correspondences
1010 * @tparam tThreadSafe True, to call this function thread-safe
1011 * @tparam tMatchPosition True, if the defined position will match the positions of the correspondences; False, if the defined position will not match the positions of the correspondences
1012 * @tparam tNeedValidPose True, if the pose must be valid so that the number of valid correspondences will be determined, otherwise the number of correspondences will be zero
1013 */
1014 template <bool tThreadSafe, bool tMatchPosition, bool tNeedValidPose>
1015 inline unsigned int numberCorrespondences(const Index32 poseId, const Vector3& referenceObjectPoint, const Scalar minimalPriority = Scalar(-1)) const;
1016
1017 /**
1018 * Counts the number of valid correspondences between image and object points for several poses individually.
1019 * @param lowerPoseId The id (index) of the frame defining the lower border of camera poses which will be investigated
1020 * @param upperPoseId The id (index) of the frame defining the upper border of camera poses which will be investigated, with range [lowerFrame, infinity)
1021 * @param referenceObjectPoint A reference object point allowing to filter the correspondences to count
1022 * @param minimalPriority The minimal priority value an object point must have so that is will be investigated
1023 * @param worker Optional worker to distribute the computation
1024 * @return The number of correspondences for each pose in the range [lowerPoseId, upperPoseId] starting with 'lowerPoseId' (the first entry corresponds to 'lowerPoseId' and so on)
1025 * @tparam tThreadSafe True, to call this function thread-safe
1026 * @tparam tMatchPosition True, if the defined position will match the positions of the correspondences; False, if the defined position will not match the positions of the correspondences
1027 * @tparam tNeedValidPose True, if the pose must be valid so that the number of valid correspondences will be determined, otherwise the number of correspondences will be zero
1028 */
1029 template <bool tThreadSafe, bool tMatchPosition, bool tNeedValidPose>
1030 inline Indices32 numberCorrespondences(const Index32 lowerPoseId, const Index32 upperPoseId, const Vector3& referenceObjectPoint, const Scalar minimalPriority = Scalar(-1), Worker* worker = nullptr) const;
1031
1032 /**
1033 * Returns whether this database holds a specified image point.
1034 * @param imagePointId The unique id of the image point which will be checked
1035 * @param imagePoint Optional resulting image point value of the defined image point id
1036 * @return True, if so
1037 * @tparam tThreadSafe True, to call this function thread-safe
1038 */
1039 template <bool tThreadSafe>
1040 inline bool hasImagePoint(const Index32 imagePointId, Vector2* imagePoint = nullptr) const;
1041
1042 /**
1043 * Adds a new 2D image point to this database.
1044 * @param imagePoint The image point to be added
1045 * @return The unique id of the new image point
1046 * @tparam tThreadSafe True, to call this function thread-safe
1047 */
1048 template <bool tThreadSafe>
1049 inline Index32 addImagePoint(const Vector2& imagePoint);
1050
1051 /**
1052 * Removes an image point from this database.
1053 * Beware: The specified image point must exist in this database.<br>
1054 * @param imagePointId The id of the image point which will be removed, must be valid
1055 * @tparam tThreadSafe True, to call this function thread-safe
1056 */
1057 template <bool tThreadSafe>
1058 inline void removeImagePoint(const Index32 imagePointId);
1059
1060 /**
1061 * Returns whether this database holds a specified object point.
1062 * @param objectPointId The unique id of the object point which will be checked
1063 * @param objectPoint Optional resulting object point value of the defined object point id
1064 * @return True, if so
1065 * @tparam tThreadSafe True, to call this function thread-safe
1066 */
1067 template <bool tThreadSafe>
1068 inline bool hasObjectPoint(const Index32 objectPointId, Vector3* objectPoint = nullptr) const;
1069
1070 /**
1071 * Adds a new 3D object point to this database.
1072 * This function uses the internal id counter for object points to create a new id.<br>
1073 * Beware: Do not mix calls with the add-objectPoint-function not creating the id on its own.
1074 * @param objectPoint The object point to be added
1075 * @param priority The priority value of the object point
1076 * @return The unique id of the new object point
1077 * @tparam tThreadSafe True, to call this function thread-safe
1078 */
1079 template <bool tThreadSafe>
1080 inline Index32 addObjectPoint(const Vector3& objectPoint, const Scalar priority = Scalar(-1));
1081
1082 /**
1083 * Adds a new 3D object point to this database.
1084 * This function does not use the internal id counter for object points to create a new id.<br>
1085 * Instead, this function takes an explicit object point id.<br>
1086 * Beware: Do not mix calls with the add-objectPoint-function creating the id on its own.
1087 * @param objectPointId The unique id of the new object point, must not exist already
1088 * @param objectPoint The object point to be added
1089 * @param priority The priority value of the object point
1090 * @tparam tThreadSafe True, to call this function thread-safe
1091 * @see hasObjectPoint().
1092 */
1093 template <bool tThreadSafe>
1094 inline void addObjectPoint(const Index32 objectPointId, const Vector3& objectPoint, const Scalar priority = Scalar(-1));
1095
1096 /**
1097 * Adds an object point from another database, adds all connected image points, registers unknown poses, and adds the topology.
1098 * Thus, this function mainly merges a track from a second database to this database.
1099 * Beware: This function is not thread-safe (as we need to prevent possible dead locks).
1100 * @param secondDatabase The second database from which the track (the object point and all connected information) will be copied
1101 * @param secondDatabaseObjectPointId The id of the object point in the second database to be copied
1102 * @param imagePointTransformation A transformation which will be applied to each connected image point (from the second database) before the image point is added to this database, an identity transformation to keep the image points as they are, the transformation defines: thisDatabaseImagePoint = imagePointTransformation * secondDatabaseImagePoint, must not be singular
1103 * @param newObjectPointId Optional explicit id of the new object point in this database, must not exist in this database if defined, an invalid id to generate a new id automatically
1104 * @param secondDatabaseLowerPoseId Optional pose id defining the lower border of the pose range from which observations (image points) of the object point will be copied, an invalid id to copy all possible observations, with range [0, secondDatabaseUpperPoseId] or invalidId
1105 * @param secondDatabaseUpperPoseId Optional pose id defining the upper border of the pose range from which observations (image points) of the object point will be copied, an invalid id to copy all possible observations, with range [secondDatabaseLowerPoseId, infinity) or invalidId
1106 * @param forExistingPosesOnly True, to avoid the creation of new poses in this database (and to skip observations/image points); False, to create new poses in this database if not existing already
1107 * @return The id of the new object point in this database, an invalid id if the track could not be copied
1108 */
1109 inline Index32 addObjectPointFromDatabase(const Database& secondDatabase, const Index32 secondDatabaseObjectPointId, const SquareMatrix3& imagePointTransformation = SquareMatrix3(true), const Index32 newObjectPointId = invalidId, const Index32 secondDatabaseLowerPoseId = invalidId, const Index32 secondDatabaseUpperPoseId = invalidId, const bool forExistingPosesOnly = false);
1110
1111 /**
1112 * Removes an object point from this database.
1113 * Beware: The specified object point must exist in this database.<br>
1114 * @param objectPointId The id of the object point which will be removed, must be valid
1115 * @tparam tThreadSafe True, to call this function thread-safe
1116 */
1117 template <bool tThreadSafe>
1118 inline void removeObjectPoint(const Index32 objectPointId);
1119
1120 /**
1121 * Removes an object point from this database and also removes all image points attached to the object point.
1122 * @param objectPointId The id of the object point which will be removed, must be valid
1123 * @tparam tThreadSafe True, to call this function thread-safe
1124 */
1125 template <bool tThreadSafe>
1126 void removeObjectPointAndAttachedImagePoints(const Index32 objectPointId);
1127
1128 /**
1129 * Renames an object point, changes the id of the object point respectively.
1130 * Beware: Do not mix calls with the add-objectPoint-function creating the id on its own.
1131 * @param oldObjectPointId The old (the current) id of the object point to be changed, must be valid
1132 * @param newObjectPointId The new id of the object point, must be valid, must not exist
1133 * @tparam tThreadSafe True, to call this function thread-safe
1134 */
1135 template <bool tThreadSafe>
1136 inline void renameObjectPoint(const Index32 oldObjectPointId, const Index32 newObjectPointId);
1137
1138 /**
1139 * Merges two object points together, afterwards one object point will be removed.
1140 * Both object points must not be visible in the same camera pose.
1141 * @param remainingObjectPointId The id of the object point which will remain after merging both object points, must be valid
1142 * @param removingObjectPointId The id of the object point which will be removed after merging both object points, must be valid
1143 * @param newPoint The location of the merged object point
1144 * @param newPriority The priority of the merged object point
1145 * @tparam tThreadSafe True, to call this function thread-safe
1146 */
1147 template <bool tThreadSafe>
1148 inline void mergeObjectPoints(const Index32 remainingObjectPointId, const Index32 removingObjectPointId, const Vector3& newPoint, const Scalar newPriority);
1149
1150 /**
1151 * Returns whether this database holds a specified camera pose.
1152 * @param poseId The unique id of the pose which will be checked
1153 * @param pose Optional resulting pose value of the defined pose id
1154 * @return True, if so
1155 * @tparam tThreadSafe True, to call this function thread-safe
1156 */
1157 template <bool tThreadSafe>
1158 inline bool hasPose(const Index32 poseId, HomogenousMatrix4* pose = nullptr) const;
1159
1160 /**
1161 * Adds a new camera pose by specifying the unique id of the new pose.
1162 * Beware: The given unique id must not exist in the database, define the pose id so that it matches to e.g., a unique frame index.<br>
1163 * @param poseId The unique id of the new pose, must be valid
1164 * @param pose The pose to be set, may be invalid
1165 * @return True, if the given pose id does not exist in the database
1166 * @tparam tThreadSafe True, to call this function thread-safe
1167 */
1168 template <bool tThreadSafe>
1169 inline bool addPose(const Index32 poseId, const HomogenousMatrix4& pose = HomogenousMatrix4(false));
1170
1171 /**
1172 * Removes a pose from this database.
1173 * Beware: The specified pose must exist in this database.<br>
1174 * @param poseId The id of the pose which will be removed, must be valid
1175 * @tparam tThreadSafe True, to call this function thread-safe
1176 */
1177 template <bool tThreadSafe>
1178 inline void removePose(const Index32 poseId);
1179
1180 /**
1181 * Determines the camera pose (camera frame) in which a specified image point is visible (to which the image point has been added).
1182 * Beware: The specified image point must exist in this database.<br>
1183 * @param imagePointId The id of the image point for which the corresponding camera pose is requested, must be valid
1184 * @return The unique id of the camera pose in which the specified image point is visible, an invalid id if the image point has not been added to any camera pose
1185 * @tparam tThreadSafe True, to call this function thread-safe
1186 * @see attachImagePointToPose(), detachImagePointFromPose().
1187 */
1188 template <bool tThreadSafe>
1189 inline Index32 poseFromImagePoint(const Index32 imagePointId) const;
1190
1191 /**
1192 * Returns the number of image point observations which belong to a given object point.
1193 * @param objectPointId The id of the object point for which the number of observations are requested, must be valid
1194 * @return The number of image point observations of the given object point
1195 * @tparam tThreadSafe True, to call this function thread-safe
1196 */
1197 template <bool tThreadSafe>
1198 inline size_t numberImagePointsFromObjectPoint(const Index32 objectPointId) const;
1199
1200 /**
1201 * Returns all observations (combination of poses and image points) which belong to a given object point.
1202 * @param objectPointId The id of the object point for which the connected observations are requested, must be valid
1203 * @param poseIds The resulting ids of the poses of the observations
1204 * @param imagePointIds The resulting ids of the image points of the observations, one id for each pose
1205 * @param imagePoints Optional resulting image points, one point for each image point id
1206 * @tparam tThreadSafe True, to call this function thread-safe
1207 */
1208 template <bool tThreadSafe>
1209 inline void observationsFromObjectPoint(const Index32 objectPointId, Indices32& poseIds, Indices32& imagePointIds, Vectors2* imagePoints = nullptr) const;
1210
1211 /**
1212 * Returns all observations (combination of poses and image points) which belong to a given object point and a set of pose candidates.
1213 * @param objectPointId The id of the object point for which the connected observations are requested, must be valid
1214 * @param poseIdCandidates The candidates of pose ids for which the observation will be checked
1215 * @param validPoseIndices The resulting indices of the valid pose candidates
1216 * @param imagePointIds Optional resulting ids of the image points for which a valid observation exists, one id for each valid pose
1217 * @param imagePoints Optional resulting image points, one point for each image point id
1218 * @tparam tThreadSafe True, to call this function thread-safe
1219 */
1220 template <bool tThreadSafe>
1221 inline void observationsFromObjectPoint(const Index32 objectPointId, const Indices32& poseIdCandidates, Indices32& validPoseIndices, Indices32* imagePointIds, Vectors2* imagePoints = nullptr) const;
1222
1223 /**
1224 * Returns the object point which belongs to a given image point.
1225 * Each image point can be the projection of at most one unique object point.<br>
1226 * Beware: The specified image point may not be connected to an object point, in this case the resulting id is an invalid id.<br>
1227 * @param imagePointId The id of the image point for which the corresponding object point is requested
1228 * @return The id of the corresponding object point, may be invalid
1229 * @tparam tThreadSafe True, to call this function thread-safe
1230 */
1231 template <bool tThreadSafe>
1232 inline Index32 objectPointFromImagePoint(const Index32 imagePointId) const;
1233
1234 /**
1235 * Returns all image points which belong to a given camera pose.
1236 * Beware: The resulting reference is valid as long as the database is not modified.
1237 * @param poseId The id of the camera pose for which the connected image points are requested, must be valid
1238 * @return The ids of all image points which are connected with the specified camera pose
1239 * @tparam tThreadSafe True, to call this function thread-safe
1240 */
1241 template <bool tThreadSafe>
1242 inline const IndexSet32& imagePointsFromPose(const Index32 poseId) const;
1243
1244 /**
1245 * Returns all image points which belong to a given object point.
1246 * Beware: The resulting reference is valid as long as the database is not modified.
1247 * @param objectPointId The id of the object point for which the connected image points are requested, must be valid
1248 * @return The ids of all image points which are connected with the specified object point
1249 * @tparam tThreadSafe True, to call this function thread-safe
1250 */
1251 template <bool tThreadSafe>
1252 inline const IndexSet32& imagePointsFromObjectPoint(const Index32 objectPointId) const;
1253
1254 /**
1255 * Returns all poses which belong to a given object point.
1256 * @param objectPointId The id of the object point for which the connected poses points are requested, must be valid
1257 * @return The ids of all poses which are connected with the specified object point
1258 * @tparam tThreadSafe True, to call this function thread-safe
1259 */
1260 template <bool tThreadSafe>
1261 inline IndexSet32 posesFromObjectPoint(const Index32 objectPointId) const;
1262
1263 /**
1264 * Attaches an existing image point to an existing object points (defines the topology between an image point and an object point).
1265 * @param imagePointId The id of the image point which will be attached to the specified object points, must be valid
1266 * @param objectPointId The id of the object points which will receive the connection to the given image point, must be valid
1267 * @tparam tThreadSafe True, to call this function thread-safe
1268 */
1269 template <bool tThreadSafe>
1270 inline void attachImagePointToObjectPoint(const Index32 imagePointId, const Index32 objectPointId);
1271
1272 /**
1273 * Detaches an image point from an object point (withdraws the topology).
1274 * @param imagePointId the id of the image point from which the topology to the object point will be removed, must be valid
1275 */
1276 template <bool tThreadSafe>
1277 inline void detachImagePointFromObjectPoint(const Index32 imagePointId);
1278
1279 /**
1280 * Attaches an existing image point to an existing camera pose (defines the topology between an image point and a camera pose).
1281 * @param imagePointId The id of the image point which will be attached to the specified object points, must be valid
1282 * @param poseId The id of the pose which will receive the connection to the given image point, must be valid
1283 * @tparam tThreadSafe True, to call this function thread-safe
1284 */
1285 template <bool tThreadSafe>
1286 inline void attachImagePointToPose(const Index32 imagePointId, const Index32 poseId);
1287
1288 /**
1289 * Detaches an image point from a camera pose (withdraws the topology).
1290 * @param imagePointId the id of the image point from which the topology to the camera pose will be removed, must be valid
1291 */
1292 template <bool tThreadSafe>
1293 inline void detachImagePointFromPose(const Index32 imagePointId);
1294
1295 /**
1296 * Sets (changes) an image point.
1297 * @param imagePointId The id of the image point which will be changed, must be valid
1298 * @param imagePoint The new 2D position of the image point
1299 * @tparam tThreadSafe True, to call this function thread-safe
1300 */
1301 template <bool tThreadSafe>
1302 inline void setImagePoint(const Index32 imagePointId, const Vector2& imagePoint);
1303
1304 /**
1305 * Sets (changes) an object point without modifying the priority value of the object point.
1306 * @param objectPointId The id of the object point which will be changed, must be valid
1307 * @param objectPoint The new 3D position of the object point
1308 * @tparam tThreadSafe True, to call this function thread-safe
1309 * @see setObjectPoints().
1310 */
1311 template <bool tThreadSafe>
1312 inline void setObjectPoint(const Index32 objectPointId, const Vector3& objectPoint);
1313
1314 /**
1315 * Sets (changes) a set of object points without modifying the priority value of the object points.
1316 * @param objectPointIds The ids of the object points which will be changed, must all be valid
1317 * @param objectPoints The new 3D positions of the object points, one position for each object point id
1318 * @param number The number of object points which will be updated
1319 * @tparam tThreadSafe True, to call this function thread-safe
1320 * @see setObjectPoint().
1321 */
1322 template <bool tThreadSafe>
1323 inline void setObjectPoints(const Index32* objectPointIds, const Vector3* objectPoints, const size_t number);
1324
1325 /**
1326 * Sets (changes) a set of object points without modifying the priority value of the object points.
1327 * All object points receive the same position e.g., an invalid object point position.
1328 * @param objectPointIds The ids of the object points which will be changed, must all be valid
1329 * @param number The number of object points which will be updated
1330 * @param referenceObjectPoint The one unique object point position to set for each specified object point
1331 * @tparam tThreadSafe True, to call this function thread-safe
1332 * @see setObjectPoint().
1333 */
1334 template <bool tThreadSafe>
1335 inline void setObjectPoints(const Index32* objectPointIds, const size_t number, const Vector3& referenceObjectPoint);
1336
1337 /**
1338 * Sets (changes) all object points to one unique position without modifying the priority value of the object points.
1339 * @param objectPoint The 3D position of all object points
1340 * @tparam tThreadSafe True, to call this function thread-safe
1341 * @see setObjectPoint().
1342 */
1343 template <bool tThreadSafe>
1344 inline void setObjectPoints(const Vector3& objectPoint = invalidObjectPoint());
1345
1346 /**
1347 * Sets (changes) an object point.
1348 * @param objectPointId The id of the object point which will be changed, must be valid
1349 * @param objectPoint The new 3D position of the object point
1350 * @param priority The new priority value of the object point
1351 * @tparam tThreadSafe True, to call this function thread-safe
1352 */
1353 template <bool tThreadSafe>
1354 inline void setObjectPoint(const Index32 objectPointId, const Vector3& objectPoint, const Scalar priority);
1355
1356 /**
1357 * Sets (changes) the priority value of an object point.
1358 * @param objectPointId The id of the object point which priority value will be changed, must be valid
1359 * @param priority The priority value to be set
1360 * @tparam tThreadSafe True, to call this function thread-safe
1361 */
1362 template <bool tThreadSafe>
1363 inline void setObjectPointPriority(const Index32 objectPointId, const Scalar priority);
1364
1365 /**
1366 * Sets (changes) a pose.
1367 * @param poseId The id of the pose to be changed, must be valid
1368 * @param pose The new pose
1369 * @tparam tThreadSafe True, to call this function thread-safe
1370 */
1371 template <bool tThreadSafe>
1372 inline void setPose(const Index32 poseId, const HomogenousMatrix4& pose);
1373
1374 /**
1375 * Sets (changes) a set of poses.
1376 * @param poseIds The ids of the poses which will be changed, must all be valid
1377 * @param poses The new poses, one pose for each pose id
1378 * @param number The number of poses which will be updated
1379 * @tparam tThreadSafe True, to call this function thread-safe
1380 * @see setPose().
1381 */
1382 template <bool tThreadSafe>
1383 inline void setPoses(const Index32* poseIds, const HomogenousMatrix4* poses, const size_t number);
1384
1385 /**
1386 * Sets (changes) a set of poses.
1387 * @param poses The poses to set, the indices of the pose correspond with the ids of the poses, each pose id must be valid
1388 * @tparam tThreadSafe True, to call this function thread-safe
1389 * @see setPose().
1390 */
1391 template <bool tThreadSafe>
1392 inline void setPoses(const ShiftVector<HomogenousMatrix4>& poses);
1393
1394 /**
1395 * Sets (changes) all poses to one unique pose value.
1396 * @param pose The pose value of all poses
1397 * @tparam tThreadSafe True, to call this function thread-safe
1398 * @see setPose().
1399 */
1400 template <bool tThreadSafe>
1401 inline void setPoses(const HomogenousMatrix4& pose);
1402
1403 /**
1404 * Returns the ids of all image points visible in a specified camera pose (camera frame).
1405 * @param poseId The id of the camera pose in which the image points are visible, must be valid
1406 * @return The indices of all image points
1407 * @tparam tThreadSafe True, to call this function thread-safe
1408 */
1409 template <bool tThreadSafe>
1410 const IndexSet32& imagePointIds(const Index32 poseId) const;
1411
1412 /**
1413 * Returns the ids of all image points which are projections of a set of object point in a specific camera frame.
1414 * @param poseId The id of the camera pose in which the image points will be located
1415 * @param objectPointIds The ids of the object points for which the image points are requested, this set will be modified so that the set finally contains only object points which have a connected image point (in the specified frame)
1416 * @return The resulting ids of the image points, one ids for each object point
1417 * @tparam tThreadSafe True, to call this function thread-safe
1418 */
1419 template <bool tThreadSafe>
1420 Indices32 imagePointIds(const Index32 poseId, Indices32& objectPointIds) const;
1421
1422 /**
1423 * Returns all image points which are located in a specified frame.
1424 * @param poseId The id of the camera pose in which frame the image points are requested
1425 * @param imagePointIds Optional resulting ids of the resulting image points one id for each point
1426 * @return All image points located in the specified frame
1427 * @tparam tThreadSafe True, to call this function thread-safe
1428 */
1429 template <bool tThreadSafe>
1430 Vectors2 imagePoints(const Index32 poseId, Indices32* imagePointIds = nullptr) const;
1431
1432 /**
1433 * Returns the ids of all image points that are part of this database.
1434 * @param imagePoints Optional resulting image points, one for each resulting image point id, nullptr if not of interest
1435 * @return The image point ids
1436 * @tparam tThreadSafe True, to call this function thread-safe
1437 */
1438 template <bool tThreadSafe>
1439 Indices32 imagePointIds(Vectors2* imagePoints = nullptr) const;
1440
1441 /**
1442 * Returns the ids of all object points that are part of this database.
1443 * @param objectPoints Optional resulting object points, one for each resulting object point id, nullptr if not of interest
1444 * @param priorities Optional resulting object point priorities, one for each resulting object point id, nullptr if not of interest
1445 * @return The object point ids
1446 * @tparam tThreadSafe True, to call this function thread-safe
1447 */
1448 template <bool tThreadSafe>
1449 Indices32 objectPointIds(Vectors3* objectPoints = nullptr, Scalars* priorities = nullptr) const;
1450
1451 /**
1452 * Returns the ids of all object points that are part of this database and which are not provided by the explicit set of outlier object point ids.
1453 * @param outlierObjectPointIds The ids of all object points which will not be returned
1454 * @return The object point ids
1455 * @tparam tThreadSafe True, to call this function thread-safe
1456 */
1457 template <bool tThreadSafe>
1458 Indices32 objectPointIds(const IndexSet32& outlierObjectPointIds) const;
1459
1460 /**
1461 * Returns the ids of all poses that are part of this database.
1462 * @param world_T_cameras Optional resulting poses, one for each resulting pose id, nullptr if not of interest
1463 * @return The pose ids
1464 * @tparam tThreadSafe True, to call this function thread-safe
1465 */
1466 template <bool tThreadSafe>
1467 Indices32 poseIds(HomogenousMatrices4* world_T_cameras = nullptr) const;
1468
1469 /**
1470 * Returns all object points with a specific location and priority value larger or equal to a given threshold.
1471 * @param referencePosition A 3D point value allowing to filter the resulting object point ids
1472 * @param objectPoints Optional resulting object point positions, one position for each resulting id
1473 * @param minimalPriority The minimal priority value an object point must have to that it will be returned (if it matches the reference position)
1474 * @return The ids of all object points that have the given position
1475 * @tparam tThreadSafe True, to call this function thread-safe
1476 * @tparam tMatchPosition True, if the defined position will match the positions of the resulting object points; False, if the defined position will not match the positions of the resulting object points
1477 * @see objectPoints().
1478 */
1479 template <bool tThreadSafe, bool tMatchPosition>
1480 Indices32 objectPointIds(const Vector3& referencePosition, Vectors3* objectPoints = nullptr, const Scalar minimalPriority = Scalar(-1)) const;
1481
1482 /**
1483 * Returns the ids of all object points with a specific location and having a priority value larger or equal to a given threshold as long as the object point is not defined in the explicit set of outlier object point ids.
1484 * @param outlierObjectPointIds The ids of all object points which will not be returned
1485 * @param referencePosition A 3D point value allowing to filter the resulting object point ids
1486 * @param objectPoints Optional resulting object point positions, one position for each resulting id
1487 * @param minimalPriority The minimal priority value an object point must have to that it will be returned (if it matches the reference position)
1488 * @return The object point ids
1489 * @tparam tThreadSafe True, to call this function thread-safe
1490 * @tparam tMatchPosition True, if the defined position will match the positions of the resulting object points; False, if the defined position will not match the positions of the resulting object points
1491 */
1492 template <bool tThreadSafe, bool tMatchPosition>
1493 Indices32 objectPointIds(const IndexSet32& outlierObjectPointIds, const Vector3& referencePosition, Vectors3* objectPoints = nullptr, const Scalar minimalPriority = Scalar(-1)) const;
1494
1495 /**
1496 * Returns pairs of object point ids combined with counts of valid observations.
1497 * The ids are id of object points which have a specified 3D position or which do not have a specified 3D position.<br>
1498 * @param referencePosition The 3D reference position which is used to filter the object points
1499 * @param minimalPriority The minimal priority value an object point must have to be identified as candidate
1500 * @param worker Optional worker object to distribute the computation
1501 * @return Pairs of object point ids and numbers of valid camera poses for the individual object points
1502 * @tparam tThreadSafe True, to call this function thread-safe
1503 * @tparam tMatchPosition True, if the defined position will match the positions of the resulting object points; False, if the defined position will not match the positions of the resulting object points
1504 */
1505 template <bool tThreadSafe, bool tMatchPosition>
1506 inline IndexPairs32 objectPointIdsWithNumberOfObservations(const Vector3& referencePosition, const Scalar minimalPriority = Scalar(-1), Worker* worker = nullptr) const;
1507
1508 /**
1509 * Returns all ids of object points which are visible in a specified frame.
1510 * @param poseId The id of the camera pose in which frame the object points are visible
1511 * @param objectPoints Optional resulting positions of the resulting object point ids
1512 * @return All object point ids visible in the specified frame
1513 * @tparam tThreadSafe True, to call this function thread-safe
1514 */
1515 template <bool tThreadSafe>
1516 Indices32 objectPointIds(const Index32 poseId, Vectors3* objectPoints = nullptr) const;
1517
1518 /**
1519 * Returns all ids of object points which are visible in a specified frame and which match or do not match a specified reference position.
1520 * @param poseId The id of the camera pose in which frame the object points are visible
1521 * @param referencePosition The 3D reference position which is used to filter the object points
1522 * @param minimalPriority The minimal priority value an object point must have so that it will be investigated
1523 * @param objectPoints Optional resulting positions of the resulting object point ids
1524 * @return All object point ids visible in the specified frame
1525 * @tparam tThreadSafe True, to call this function thread-safe
1526 * @tparam tMatchPosition True, if the defined position will match the positions of the resulting object points; False, if the defined position will not match the positions of the resulting object points
1527 */
1528 template <bool tThreadSafe, bool tMatchPosition>
1529 Indices32 objectPointIds(const Index32 poseId, const Vector3& referencePosition, const Scalar minimalPriority = Scalar(-1), Vectors3* objectPoints = nullptr) const;
1530
1531 /**
1532 * Returns all ids of object points which are visible in several specified frames.
1533 * @param poseIds The ids of the camera poses in which frame the object points are visible
1534 * @param objectPoints Optional resulting positions of the resulting object point ids
1535 * @return All object point ids visible in the specified frames
1536 * @tparam tThreadSafe True, to call this function thread-safe
1537 */
1538 template <bool tThreadSafe>
1539 Indices32 objectPointIds(const Indices32 poseIds, Vectors3* objectPoints = nullptr) const;
1540
1541 /**
1542 * Returns all ids of object points which are visible in a specified frame range.
1543 * The function allows to determine object points which are visible in all frames of the specified frame range or in any of the frames.
1544 * @param lowerPoseId Pose id defining the lower pose id border of all poses which will be investigated
1545 * @param upperPoseId Pose id defining the lower pose id border of all poses which will be investigated, with range [lowerPoseId, infinity)
1546 * @param referencePosition The 3D reference position which is used to filter the object points
1547 * @param minimalPriority The minimal priority value an object point must have so that it will be investigated
1548 * @param objectPoints Optional resulting positions of the resulting object point ids
1549 * @return All object point ids visible in the specified frames
1550 * @tparam tThreadSafe True, to call this function thread-safe
1551 * @tparam tMatchPosition True, if the defined position will match the positions of the resulting object points; False, if the defined position will not match the positions of the resulting object points
1552 * @tparam tVisibleInAllPoses True, if the object points must be visible in all poses (frames) of the specified pose range; False, if the object point can be visible in any poses (frames) within the specified pose range
1553 */
1554 template <bool tThreadSafe, bool tMatchPosition, bool tVisibleInAllPoses>
1555 Indices32 objectPointIds(const Index32 lowerPoseId, const Index32 upperPoseId, const Vector3& referencePosition = invalidObjectPoint(), const Scalar minimalPriority = Scalar(-1), Vectors3* objectPoints = nullptr) const;
1556
1557 /**
1558 * Returns all ids of object points which are visible in specified keyframes.
1559 * The function allows to determine object points which are visible in all keyframes or in any of the keyframes.
1560 * @param poseIds The ids of the keyframes which will be investigated
1561 * @param referencePosition The 3D reference position which is used to filter the object points
1562 * @param minimalPriority The minimal priority value an object point must have so that it will be investigated
1563 * @param objectPoints Optional resulting positions of the resulting object point ids
1564 * @return All object point ids visible in the specified frames
1565 * @tparam tThreadSafe True, to call this function thread-safe
1566 * @tparam tMatchPosition True, if the defined position will match the positions of the resulting object points; False, if the defined position will not match the positions of the resulting object points
1567 * @tparam tVisibleInAllPoses True, if the object points must be visible in all poses (frames) of the specified pose range; False, if the object point can be visible in any poses (frames) within the specified pose range
1568 */
1569 template <bool tThreadSafe, bool tMatchPosition, bool tVisibleInAllPoses>
1570 Indices32 objectPointIds(const Indices32& poseIds, const Vector3& referencePosition = invalidObjectPoint(), const Scalar minimalPriority = Scalar(-1), Vectors3* objectPoints = nullptr) const;
1571
1572 /**
1573 * Returns all image points which are located in a specified frame and are projections of object points.
1574 * @param poseId The id of the camera pose in which frame the image points are requested
1575 * @param objectPointIds Resulting object point ids corresponding to the individual image points
1576 * @return The resulting image points located in the specified frame and having a corresponding object point
1577 * @tparam tThreadSafe True, to call this function thread-safe
1578 * @see imagePointsFromObjectPoints().
1579 */
1580 template <bool tThreadSafe>
1581 Vectors2 imagePointsWithObjectPoints(const Index32 poseId, Indices32& objectPointIds) const;
1582
1583 /**
1584 * Returns all image points which are located in a specified frame and which are projections of a set of given object points.
1585 * As not all object points may be visible in the specified frame, the set of given object points will be modified so that set contains only visible object points after calling this function.<br>
1586 * @param poseId The id of the camera pose in which frame the image points are requested
1587 * @param objectPointIds The ids of the object points for which the corresponding image points are requested
1588 * @param imagePointIds Optional resulting image point ids of the resulting image points
1589 * @return The resulting image points located in the specified frame
1590 * @tparam tThreadSafe True, to call this function thread-safe
1591 * @see imagePointsWithObjectPoints().
1592 */
1593 template <bool tThreadSafe>
1594 Vectors2 imagePointsFromObjectPoints(const Index32 poseId, Indices32& objectPointIds, Indices32* imagePointIds = nullptr) const;
1595
1596 /**
1597 * Returns all image points which are located in a specified frame and which are projections of a set of given object points.
1598 * As not all object points may be visible in the specified frame, the number of resulting image points may be smaller than the number of specified object points.<br>
1599 * The set of specified object points is untouched, however a resulting set of indices return the indices of valid object points (indices as specified in the set of object points).<br>
1600 * @param poseId The id of the camera pose in which frame the image points are requested
1601 * @param objectPointIds The ids of the object points for which the corresponding image points are requested
1602 * @param validIndices The indices of valid object points, !not! the ids of valid object points
1603 * @param imagePointIds Optional resulting image point ids of the resulting image points
1604 * @return The image points which are visible projections of the specified object points, the number of image points is equal to the resulting set of indices of valid object points
1605 * @tparam tThreadSafe True, to call this function thread-safe
1606 */
1607 template <bool tThreadSafe>
1608 Vectors2 imagePointsFromObjectPoints(const Index32 poseId, const Indices32& objectPointIds, Indices32& validIndices, Indices32* imagePointIds = nullptr) const;
1609
1610 /**
1611 * Returns all image points which are located in a specified frame and which are projections of a set of given object points.
1612 * As not all object points may be visible in the specified frame, the number of resulting image points may be smaller than the number of specified object points.<br>
1613 * The set of specified object points is untouched, however a resulting set of indices return the indices of valid object points (indices as specified in the set of object points).<br>
1614 * @param poseId The id of the camera pose in which frame the image points are requested
1615 * @param objectPointIds The ids of the object points for which the corresponding image points are requested
1616 * @param numberObjectPointIds The number of given object point ids
1617 * @param validIndices The indices of valid object points, !not! the ids of valid object points
1618 * @param imagePointIds Optional resulting image point ids of the resulting image points
1619 * @return The image points which are visible projections of the specified object points, the number of image points is equal to the resulting set of indices of valid object points
1620 * @tparam tThreadSafe True, to call this function thread-safe
1621 */
1622 template <bool tThreadSafe>
1623 Vectors2 imagePointsFromObjectPoints(const Index32 poseId, const Index32* objectPointIds, const size_t numberObjectPointIds, Indices32& validIndices, Indices32* imagePointIds = nullptr) const;
1624
1625 /**
1626 * Determines the groups of image points matching to unique object points in individual camera poses.
1627 * Image points within one group correspond to one object point while the order of the image points correspond with the order of the given camera poses.<br>
1628 * @param poseIds The ids of the camera pose in which the object points are visible which form the groups of image points.<br>
1629 * @param objectPointIds Resulting ids of object points which are visible in all camera pose and to which the resulting groups of image points correspond
1630 * @return Resulting groups of image points one group for each resulting object point
1631 * @tparam tThreadSafe True, to call this function thread-safe
1632 */
1633 template <bool tThreadSafe>
1634 ImagePointGroups imagePointGroups(const Indices32 poseIds, Indices32& objectPointIds) const;
1635
1636 /**
1637 * Returns object points with corresponding image points entirely visible in a specific range of camera poses.
1638 * @param poseId The id of the camera pose which is the start position of the range of camera poses
1639 * @param previous True, if the range covers the previous camera poses; False, if the range covers the subsequent camera poses
1640 * @param minimalObservations The minimal number of successive camera poses in which an object point must be visible
1641 * @param maximalObservations Optional the maximal number of successive camera poses (more poses will not be investigated), 0 or with range [minimalObservations, infinity)
1642 * @return The map mapping object points to image points
1643 * @tparam tThreadSafe True, to call this function thread-safe
1644 */
1645 template <bool tThreadSafe>
1646 IdIdPointPairsMap imagePoints(const Index32 poseId, const bool previous, const size_t minimalObservations = 2, const size_t maximalObservations = 0) const;
1647
1648 /**
1649 * Determines the image points which are projections from the same object points and are visible in two individual camera poses.
1650 * @param pose0 The id of the first camera pose, must be valid
1651 * @param pose1 The id of the second camera pose, must be valid and must not be 'pose0'
1652 * @param points0 The resulting image points visible in the first camera pose
1653 * @param points1 The resulting image points visible in the second camera pose, each point corresponds to one point from 'points0'
1654 * @param objectPointIds Optional resulting ids of the object points which are visible in both camera poses
1655 * @tparam tThreadSafe True, to call this function thread-safe
1656 */
1657 template <bool tThreadSafe>
1658 void imagePoints(const Index32 pose0, const Index32 pose1, Vectors2& points0, Vectors2& points1, Indices32* objectPointIds = nullptr) const;
1659
1660 /**
1661 * Returns corresponding object points and image points for a given camera pose.
1662 * @param poseId The id of the camera pose for which the object and image points are requested
1663 * @param imagePoints The resulting image points located in the specified camera pose
1664 * @param objectPoints The resulting object points, each point corresponds to one image points from 'imagePoints'
1665 * @param referencePosition The 3D reference position which is used to filter the object points
1666 * @param minimalObservations The minimal number of observations a resulting object points must have (in arbitrary sibling camera pose)
1667 * @param imagePointIds Optional ids of the resulting image points
1668 * @param objectPointIds Optional ids of the resulting object points
1669 * @tparam tThreadSafe True, to call this function thread-safe
1670 * @tparam tMatchPosition True, if the defined position will match the positions of the resulting object points; False, if the defined position will not match the positions of the resulting object points
1671 */
1672 template <bool tThreadSafe, bool tMatchPosition>
1673 void imagePointsObjectPoints(const Index32 poseId, Vectors2& imagePoints, Vectors3& objectPoints, const Vector3& referencePosition = invalidObjectPoint(), const size_t minimalObservations = 0, Indices32* imagePointIds = nullptr, Indices32* objectPointIds = nullptr) const;
1674
1675 /**
1676 * Returns two groups of corresponding object points and image points for a given camera pose.
1677 * The first group of correspondences have object points from the given set of priority object points
1678 * The second group of correspondences have object points not given in the set of priority object points
1679 * @param poseId The id of the camera pose for which the object and image points are requested
1680 * @param priorityIds The ids of the object points which will belong to the group of priority correspondences
1681 * @param priorityImagePoints The resulting image points located in the specified camera pose belonging to the priority group
1682 * @param priorityObjectPoints The resulting object points belonging to the priority group, each point corresponds to one image points from 'imagePoints'
1683 * @param remainingImagePoints The resulting image points located in the specified camera pose belonging to the remaining group
1684 * @param remainingObjectPoints The resulting object points belonging to the remaining group, each point corresponds to one image points from 'imagePoints'
1685 * @param referencePosition The 3D reference position which is used to filter the object points
1686 * @param minimalObservations The minimal number of observations a resulting object points must have (in arbitrary sibling camera pose)
1687 * @param priorityImagePointIds Optional ids of the resulting image points belonging to the priority group
1688 * @param priorityObjectPointIds Optional ids of the resulting object points belonging to the priority group
1689 * @param remainingImagePointIds Optional ids of the resulting image points belonging to the remaining group
1690 * @param remainingObjectPointIds Optional ids of the resulting object points belonging to the remaining group
1691 * @tparam tThreadSafe True, to call this function thread-safe
1692 * @tparam tMatchPosition True, if the defined position will match the positions of the resulting object points; False, if the defined position will not match the positions of the resulting object points
1693 */
1694 template <bool tThreadSafe, bool tMatchPosition>
1695 void imagePointsObjectPoints(const Index32 poseId, const IndexSet32& priorityIds, Vectors2& priorityImagePoints, Vectors3& priorityObjectPoints, Vectors2& remainingImagePoints, Vectors3& remainingObjectPoints, const Vector3& referencePosition = invalidObjectPoint(), const size_t minimalObservations = 0, Indices32* priorityImagePointIds = nullptr, Indices32* priorityObjectPointIds = nullptr, Indices32* remainingImagePointIds = nullptr, Indices32* remainingObjectPointIds = nullptr) const;
1696
1697 /**
1698 * Returns corresponding poses and image points for a given object point from the entire range of possible camera poses.
1699 * @param objectPointId The id of the object point for which the poses and image points are requested
1700 * @param poses The resulting poses in which the object point is visible
1701 * @param imagePoints The resulting image points which are the projections of the object points, each image point corresponds with one pose
1702 * @param referencePose A pose allowing to filter the resulting poses so that either valid or invalid poses are found
1703 * @param poseIds Optional ids of the resulting poses
1704 * @param imagePointIds Optional ids of the resulting image points
1705 * @param lowerPoseId Optional pose id defining the lower pose id border, invalidId if no lower border is defined
1706 * @param upperPoseId Optional pose id defining the upper pose id border, invalidId if no upper border is defined
1707 * @tparam tThreadSafe True, to call this function thread-safe
1708 * @tparam tMatchPose True, if the defined pose will match the values of the resulting poses; False, if the defined pose will not match the values of the resulting poses
1709 */
1710 template <bool tThreadSafe, bool tMatchPose>
1711 void posesImagePoints(const Index32 objectPointId, HomogenousMatrices4& poses, Vectors2& imagePoints, const HomogenousMatrix4& referencePose = HomogenousMatrix4(false), Indices32* poseIds = nullptr, Indices32* imagePointIds = nullptr, const Index32 lowerPoseId = invalidId, const Index32 upperPoseId = invalidId) const;
1712
1713 /**
1714 * Returns topology triples with valid image points ids, object points ids and pose ids for a set of given pose ids.
1715 * @param poseIds The ids of the camera pose for which the topology triples are requested.
1716 * @return The resulting topology triples
1717 * @tparam tThreadSafe True, to call this function thread-safe
1718 */
1719 template <bool tThreadSafe>
1720 TopologyTriples topologyTriples(const Indices32& poseIds) const;
1721
1722 /**
1723 * Clears the database including all camera poses, object points, image points and any topology.
1724 * @tparam tThreadSafe True, to call this function thread-safe
1725 */
1726 template <bool tThreadSafe>
1727 inline void clear();
1728
1729 /**
1730 * Resets the geometric information of this database for 3D object points and 6DOF camera poses.
1731 * However, the 2D image point locations are untouched.
1732 * @param referenceObjectPoint The new object point value for each object point of this database
1733 * @param referencePose The new pose value for each pose of this database
1734 * @tparam tThreadSafe True, to call this function thread-safe
1735 */
1736 template <bool tThreadSafe>
1737 inline void reset(const Vector3& referenceObjectPoint = invalidObjectPoint(), const HomogenousMatrix4& referencePose = HomogenousMatrix4(false));
1738
1739 /**
1740 * Resets this database with given poses, object points, image points, and topology.
1741 * @param numberPoses The number of the provided poses, with range [0, infinity)
1742 * @param poseIds The ids of all poses, nullptr if 'numberPoses == 0'
1743 * @param poses The poses, one for each pose id, nullptr if 'numberPoses == 0'
1744 * @param numberObjectPoints The number of the provided object points, with range [0, infinity)
1745 * @param objectPointIds The ids of all object points, nullptr if 'numberObjectPoints == 0'
1746 * @param objectPoints The object points, one for each object point id, nullptr if 'numberObjectPoints == 0'
1747 * @param objectPointPriorities The priorities of the object points, one for each object point id, nullptr if 'numberObjectPoints == 0'
1748 * @param numberImagePoints The number of provided image points, with range [0, infinity)
1749 * @param imagePointIds The ids of all image points, nullptr if 'numberImagePoints == 0'
1750 * @param imagePoints The image points, one for each image point id, nullptr if 'numberImagePoints == 0'
1751 * @param topologyPoseIds The ids of the poses to which an image point belongs, one for each image point, 'invalidId' if unknown
1752 * @param topologyObjectPointIds The ids of all object points to which an image point belongs, one for each image point, 'invalidId' if unknown
1753 */
1754 template <typename T, bool tThreadSafe>
1755 void reset(const size_t numberPoses, const Index32* poseIds, const HomogenousMatrixT4<T>* poses, const size_t numberObjectPoints, const Index32* objectPointIds, const VectorT3<T>* objectPoints, const T* objectPointPriorities, const size_t numberImagePoints, const Index32* imagePointIds, const VectorT2<T>* imagePoints, const Index32* topologyPoseIds, const Index32* topologyObjectPointIds);
1756
1757 /**
1758 * Filters a set of given topology triples due to a set of given pose ids.
1759 * @param topologyTriples The set of topology triplies which will be filtered
1760 * @param poseIds The ids of the camera pose defining which triples are returned (the indices respectively)
1761 * @return The indices of the topology triples which belong to one of the given camera poses
1762 */
1763 static inline Indices32 filterTopologyTriplesPoses(const TopologyTriples& topologyTriples, const IndexSet32& poseIds);
1764
1765 /**
1766 * Filters a set of given topology triples due to a set of given object point ids.
1767 * @param topologyTriples The set of topology triplies which will be filtered
1768 * @param objectPointIds The ids of the object points defining which triples are returned (the indices respectively)
1769 * @return The indices of the topology triples which belong to one of the given object points
1770 */
1771 static inline Indices32 filterTopologyTriplesObjectPoints(const TopologyTriples& topologyTriples, const IndexSet32& objectPointIds);
1772
1773 /**
1774 * Filters a set of given topology triples due to a set of given image point ids.
1775 * @param topologyTriples The set of topology triplies which will be filtered
1776 * @param imagePointIds The ids of the image points defining which triples are returned (the indices respectively)
1777 * @return The indices of the topology triples which belong to one of the given image points
1778 */
1779 static inline Indices32 filterTopologyTriplesImagePoints(const TopologyTriples& topologyTriples, const IndexSet32& imagePointIds);
1780
1781 /**
1782 * Determines reliable object points from a set of given topology triples (by determining all object points with a minimal number of observations).
1783 * @param topologyTriples The set of topology triples from which the reliable object points are determined
1784 * @param minimalObservations The minimal number of observations (the number of camera poses in which the object point is visible) an object point must have to count as reliable
1785 * @return The ids of the reliable object points
1786 */
1787 static inline Indices32 reliableObjectPoints(const TopologyTriples& topologyTriples, const unsigned int minimalObservations);
1788
1789 /**
1790 * Converts the set of topology triples into a representation which is forced/oriented by object points so that the camera poses and image points can be accessed for a specific object points.
1791 * @param topologyTriples The set of topology triples which will be converted
1792 * @param indices Optional subset of the given topology, the indices of the topology triples that will be added to the resulting (object point forced) data structure, nullptr to use all triples
1793 * @return The object point forced data structure of the given topology triples
1794 */
1795 static PoseImagePointTopologyGroups objectPointTopology(const TopologyTriples& topologyTriples, const Indices32* indices = nullptr);
1796
1797 /**
1798 * Assign operator copying a second database to this database object.
1799 * @param database The database object to be copied
1800 * @return Reference to this object
1801 */
1802 inline Database& operator=(const Database& database);
1803
1804 /**
1805 * Move operator moving a second database to this database object.
1806 * @param database The database object to be moved
1807 * @return Reference to this object
1808 */
1809 inline Database& operator=(Database&& database) noexcept;
1810
1811 /**
1812 * Returns whether this database holds at least one image point, one object point or one camera pose.
1813 * @return True, if so
1814 */
1815 explicit inline operator bool() const;
1816
1817 protected:
1818
1819 /**
1820 * Counts the number of valid correspondences between image and object points for a subset of several poses individually.
1821 * @param lowerPoseId The id (index) of the frame defining the lower border of camera poses which will be investigated
1822 * @param referenceObjectPoint A reference object point allowing to filter the correspondences to count
1823 * @param minimalPriority The minimal priority value an object point must have so that is will be investigated
1824 * @param correspondences The resulting correspondences, one for each frame, starting with 'lowerPoseId' (the first entry corresponds to 'lowerPoseId' and so on)
1825 * @param firstPose The index (not the id) of the first pose to handle
1826 * @param numberPoses The number of poses to handle
1827 * @tparam tMatchPosition True, if the defined position will match the positions of the correspondences; False, if the defined position will not match the positions of the correspondences
1828 * @tparam tNeedValidPose True, if the pose must be valid so that the number of valid correspondences will be determined, otherwise the number of correspondences will be zero
1829 */
1830 template <bool tMatchPosition, bool tNeedValidPose>
1831 void numberCorrespondencesSubset(const Index32 lowerPoseId, const Vector3* referenceObjectPoint, const Scalar minimalPriority, unsigned int* correspondences, const unsigned int firstPose, const unsigned int numberPoses) const;
1832
1833 /**
1834 * Returns pairs of object point ids combined with counts of valid observations.
1835 * @param objectPointIds The ids of the object points for which the number of observations is determined
1836 * @param referencePosition The 3D position of the object points to find or to avoid (e.g., may be an invalid position to identify all invalid object points)
1837 * @param minimalPriority The minimal priority value an object point must have to be identified as candidate
1838 * @param pairs The resulting pairs of object point ids and numbers of valid camera poses for the individual object points
1839 * @param lock Optional lock object, must be defined if the function is executed on several threads in parallel
1840 * @param firstObjectPoint The first object point to be handled
1841 * @param numberObjectPoints The number of object points to be handled
1842 * @tparam tMatchPosition True, if the defined position will match the positions of the resulting object points; False, if the defined position will not match the positions of the resulting object points
1843 * @see objectPointIdsWithNumberOfObservations().
1844 */
1845 template <bool tMatchPosition>
1846 void objectPointIdsWithNumberOfObservationsSubset(const Index32* objectPointIds, const Vector3* referencePosition, const Scalar minimalPriority, IndexPairs32* pairs, Lock* lock, const unsigned int firstObjectPoint, const unsigned int numberObjectPoints) const;
1847
1848 /**
1849 * Counts the number of valid poses of a given object point.
1850 * @param objectPointId The id of the object point for which the number of valid poses is determined
1851 * @param imagePointIds The ids of the image points which are the projections of the defined object point (must be extracted from the ObjectPointData object of the given object point)
1852 * @return The number of valid camera poses
1853 */
1854 inline unsigned int numberValidPoses(const Index32 objectPointId, const IndexSet32& imagePointIds) const;
1855
1856 /**
1857 * Returns the first 32 bit index of a 64 bit index.
1858 * @param index The 64 bit index
1859 * @return First 32 bit index
1860 */
1861 static inline Index32 firstIndex(const Index64 index);
1862
1863 /**
1864 * Returns the second 32 bit index of a 64 bit index.
1865 * @param index The 64 bit index
1866 * @return Second 32 bit index
1867 */
1868 static inline Index32 secondIndex(const Index64 index);
1869
1870 /**
1871 * Returns the 64 bit index composed of two 32 bit indices.
1872 * @param first The first 32 bit index
1873 * @param second The second 32 bit index
1874 * @return The resulting 64 bit index
1875 */
1876 static inline Index64 index64(const Index32 first, const Index32 second);
1877
1878 protected:
1879
1880 /// The map mapping unique pose ids to pose data instances.
1882
1883 /// The map mapping unique object point ids to object point data instances.
1885
1886 /// The map mapping unique image points ids to image point data instances.
1888
1889 /// The map mapping a pair of pose id and object point id to image point ids.
1891
1892 /// The number of poses.
1893 unsigned int poses_ = 0u;
1894
1895 /// The counter for unique object point ids.
1896 Index32 objectPointIdCounter_ = invalidId;
1897
1898 /// The counter for unique image point ids.
1899 Index32 imagePointIdCounter_ = invalidId;
1900
1901 /// The lock for the entire database.
1902 mutable Lock lock_;
1903};
1904
1909
1910template <bool tThreadSafe>
1912 database_(database),
1913 imagePointIds_(imagePointIds)
1914{
1915 // nothing to do here
1916}
1917
1918template <bool tThreadSafe>
1920{
1921 return imagePointIds_.size();
1922}
1923
1924template <bool tThreadSafe>
1926{
1927 ocean_assert(index < imagePointIds_.size());
1928 return database_.imagePoint<tThreadSafe>(imagePointIds_[index]);
1929}
1930
1931template <bool tThreadSafe>
1933 database_(database),
1934 topology_(topology)
1935{
1936 // nothing to do here
1937}
1938
1939template <bool tThreadSafe>
1941{
1942 return topology_.size();
1943}
1944
1945template <bool tThreadSafe>
1947{
1948 ocean_assert(index < topology_.size());
1949 return database_.imagePoint<tThreadSafe>(topology_[index].imagePointId());
1950}
1951
1952template <bool tThreadSafe>
1954 database_(database),
1955 objectPointIds_(objectPointIds)
1956{
1957 // nothing to do here
1958}
1959
1960template <bool tThreadSafe>
1962{
1963 return objectPointIds_.size();
1964}
1965
1966template <bool tThreadSafe>
1968{
1969 ocean_assert(index < objectPointIds_.size());
1970 return database_.objectPoint<tThreadSafe>(objectPointIds_[index]);
1971}
1972
1973template <bool tThreadSafe>
1975 database_(database),
1976 poseIds_(poseIds)
1977{
1978 // nothing to do here
1979}
1980
1981template <bool tThreadSafe>
1983{
1984 return poseIds_.size();
1985}
1986
1987template <bool tThreadSafe>
1989{
1990 ocean_assert(index < poseIds_.size());
1991 return database_.pose<tThreadSafe>(poseIds_[index]);
1992}
1993
1994template <bool tThreadSafe>
1996 database_(database),
1997 topology_(topology)
1998{
1999 // nothing to do here
2000}
2001
2002template <bool tThreadSafe>
2004{
2005 return topology_.size();
2006}
2007
2008template <bool tThreadSafe>
2010{
2011 ocean_assert(index < topology_.size());
2012 return database_.pose<tThreadSafe>(topology_[index].poseId());
2013}
2014
2016 imagePointId_(imagePointId)
2017{
2018 // nothing to do here
2019}
2020
2022{
2023 return imagePointId_;
2024}
2025
2027{
2028 imagePointId_ = imagePointId;
2029}
2030
2032 objectPointId_(objectPointId)
2033{
2034 // nothing to do here
2035}
2036
2038{
2039 return objectPointId_;
2040}
2041
2043{
2044 objectPointId_ = objectPointId;
2045}
2046
2048 poseId_(poseId)
2049{
2050 // nothing to do here
2051}
2052
2054{
2055 return poseId_;
2056}
2057
2059{
2060 poseId_ = poseId;
2061}
2062
2063inline Database::TopologyTriple::TopologyTriple(const Index32 poseId, const Index32 objectPointId, const Index32 imagePointId) :
2064 PoseObject(poseId),
2065 ObjectPointObject(objectPointId),
2066 ImagePointObject(imagePointId)
2067{
2068 // nothing to do here
2069}
2070
2071inline Database::PoseImagePointPair::PoseImagePointPair(const Index32 poseId, const Index32 imagePointId) :
2072 ImagePointObject(imagePointId),
2073 PoseObject(poseId)
2074{
2075 // nothing to do here
2076}
2077
2078inline Database::ImagePointData::ImagePointData(const Vector2& point, const Index32 poseId, const Index32 objectPointId) :
2079 point_(point),
2080 poseId_(poseId),
2081 objectPointId_(objectPointId)
2082{
2083 // nothing to do here
2084}
2085
2087{
2088 return point_;
2089}
2090
2092{
2093 return poseId_;
2094}
2095
2097{
2098 return objectPointId_;
2099}
2100
2102{
2103 point_ = point;
2104}
2105
2107{
2108 poseId_ = poseId;
2109}
2110
2112{
2113 objectPointId_ = objectPointId;
2114}
2115
2117{
2118 return imagePointIds_;
2119}
2120
2121inline void Database::Data::registerImagePoint(const Index32 imagePointId)
2122{
2123 ocean_assert(imagePointIds_.find(imagePointId) == imagePointIds_.end());
2124 imagePointIds_.insert(imagePointId);
2125}
2126
2127inline void Database::Data::unregisterImagePoint(const Index32 imagePointId)
2128{
2129 ocean_assert(imagePointIds_.find(imagePointId) != imagePointIds_.end());
2130 imagePointIds_.erase(imagePointId);
2131}
2132
2133inline Database::PoseData::PoseData(const HomogenousMatrix4& world_T_camera, const Scalar fov) :
2134 world_T_camera_(world_T_camera),
2135 fov_(fov)
2136{
2137 // nothing to do here
2138}
2139
2141{
2142 return world_T_camera_;
2143}
2144
2146{
2147 return fov_;
2148}
2149
2150inline void Database::PoseData::setPose(const HomogenousMatrix4& world_T_camera)
2151{
2152 world_T_camera_ = world_T_camera;
2153}
2154
2156{
2157 fov_ = fov;
2158}
2159
2160inline Database::ObjectPointData::ObjectPointData(const Vector3& point, const Scalar priority) :
2161 point_(point),
2162 priority_(priority)
2163{
2164 // nothing to do here
2165}
2166
2168{
2169 return point_;
2170}
2171
2173{
2174 return priority_;
2175}
2176
2178{
2179 point_ = point;
2180}
2181
2183{
2184 priority_ = priority;
2185}
2186
2187inline Database::Database(const Database& database) :
2188 poseMap_(database.poseMap_),
2192 poses_(database.poses_),
2195{
2196 // nothing to do here
2197}
2198
2199inline Database::Database(Database&& database) noexcept :
2200 poseMap_(std::move(database.poseMap_)),
2201 objectPointMap_(std::move(database.objectPointMap_)),
2202 imagePointMap_(std::move(database.imagePointMap_)),
2203 poseObjectPointMap_(std::move(database.poseObjectPointMap_)),
2204 poses_(database.poses_),
2205 objectPointIdCounter_(database.objectPointIdCounter_),
2206 imagePointIdCounter_(database.imagePointIdCounter_)
2207{
2208 database.poses_ = 0u;
2209 database.objectPointIdCounter_ = invalidId;
2210 database.imagePointIdCounter_ = invalidId;
2211}
2212
2214{
2215 return lock_;
2216}
2217
2218template <bool tThreadSafe>
2219inline bool Database::isEmpty() const
2220{
2221 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
2222
2223 return poseMap_.empty() && objectPointMap_.empty() && imagePointMap_.empty();
2224}
2225
2226template <bool tThreadSafe>
2227inline size_t Database::poseNumber() const
2228{
2229 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
2230
2231 return poseMap_.size();
2232}
2233
2234template <bool tThreadSafe>
2235inline size_t Database::objectPointNumber() const
2236{
2237 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
2238
2239 return objectPointMap_.size();
2240}
2241
2242template <bool tThreadSafe>
2243inline size_t Database::imagePointNumber() const
2244{
2245 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
2246
2247 return imagePointMap_.size();
2248}
2249
2250template <bool tThreadSafe>
2251inline const Vector2& Database::imagePoint(const Index32 imagePointId) const
2252{
2253 ocean_assert(imagePointId != invalidId);
2254
2255 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
2256
2257 ocean_assert(imagePointMap_.find(imagePointId) != imagePointMap_.end());
2258 return imagePointMap_.find(imagePointId)->second.point();
2259}
2260
2261template <bool tThreadSafe>
2262inline Vectors2 Database::imagePoints(const Indices32& imagePointIds) const
2263{
2264 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
2265
2267 imagePoints.reserve(imagePointIds.size());
2268
2269 for (const Index32 imagePointId : imagePointIds)
2270 {
2271 ocean_assert(imagePointId != invalidId);
2272 ocean_assert(imagePointMap_.find(imagePointId) != imagePointMap_.end());
2273
2274 imagePoints.push_back(imagePointMap_.find(imagePointId)->second.point());
2275 }
2276
2277 return imagePoints;
2278}
2279
2280template <bool tThreadSafe>
2281inline Vectors2 Database::imagePoints(const IndexSet32& imagePointIds) const
2282{
2283 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
2284
2286 imagePoints.reserve(imagePointIds.size());
2287
2288 for (const Index32 imagePointId : imagePointIds)
2289 {
2290 ocean_assert(imagePointId != invalidId);
2291 ocean_assert(imagePointMap_.find(imagePointId) != imagePointMap_.end());
2292
2293 imagePoints.push_back(imagePointMap_.find(imagePointId)->second.point());
2294 }
2295
2296 return imagePoints;
2297}
2298
2299template <bool tThreadSafe>
2300inline bool Database::hasObservation(const Index32 poseId, const Index32 objectPointId, Vector2* point, Index32* pointId) const
2301{
2302 ocean_assert(objectPointId != invalidId && poseId != invalidId);
2303
2304 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
2305
2306 const Index64To32Map::const_iterator iPoseObjectPoint = poseObjectPointMap_.find(index64(poseId, objectPointId));
2307
2308 if (iPoseObjectPoint == poseObjectPointMap_.end())
2309 {
2310 return false;
2311 }
2312
2313 if (!point && !pointId)
2314 {
2315 return true;
2316 }
2317
2318 const ImagePointMap::const_iterator iImagePoint = imagePointMap_.find(iPoseObjectPoint->second);
2319 ocean_assert(iImagePoint != imagePointMap_.end());
2320
2321 if (point != nullptr)
2322 {
2323 *point = iImagePoint->second.point();
2324 }
2325
2326 if (pointId != nullptr)
2327 {
2328 *pointId = iImagePoint->first;
2329 }
2330
2331 return true;
2332}
2333
2334template <bool tThreadSafe>
2335inline const Vector3& Database::objectPoint(const Index32 objectPointId) const
2336{
2337 ocean_assert(objectPointId != invalidId);
2338
2339 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
2340
2341 ocean_assert(objectPointMap_.find(objectPointId) != objectPointMap_.end());
2342 return objectPointMap_.find(objectPointId)->second.point();
2343}
2344
2345template <bool tThreadSafe>
2346inline const Vector3& Database::objectPoint(const Index32 objectPointId, Scalar& objectPointPriority) const
2347{
2348 ocean_assert(objectPointId != invalidId);
2349
2350 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
2351
2352 const ObjectPointMap::const_iterator iObjectPoint = objectPointMap_.find(objectPointId);
2353 ocean_assert(iObjectPoint != objectPointMap_.end());
2354
2355 objectPointPriority = iObjectPoint->second.priority();
2356 return iObjectPoint->second.point();
2357}
2358
2359template <bool tThreadSafe>
2360inline Scalar Database::objectPointPriority(const Index32 objectPointId) const
2361{
2362 ocean_assert(objectPointId != invalidId);
2363
2364 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
2365
2366 ocean_assert(objectPointMap_.find(objectPointId) != objectPointMap_.end());
2367 return objectPointMap_.find(objectPointId)->second.priority();
2368}
2369
2370template <bool tThreadSafe>
2372{
2373 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
2374
2376 objectPoints.reserve(objectPointMap_.size());
2377
2378 for (ObjectPointMap::const_iterator iObjectPoint = objectPointMap_.cbegin(); iObjectPoint != objectPointMap_.cend(); ++iObjectPoint)
2379 {
2380 objectPoints.push_back(iObjectPoint->second.point());
2381 }
2382
2383 return objectPoints;
2384}
2385
2386template <bool tThreadSafe, bool tMatchPosition>
2387inline Vectors3 Database::objectPoints(const Vector3& referencePosition, Indices32* objectPointIds, const Scalar minimalPriority) const
2388{
2389 ocean_assert(!objectPointIds || objectPointIds->empty());
2390
2391 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
2392
2394 objectPoints.reserve(objectPointMap_.size());
2395
2396 if (objectPointIds != nullptr)
2397 {
2398 objectPointIds->clear();
2399 objectPointIds->reserve(objectPointMap_.size());
2400
2401 for (ObjectPointMap::const_iterator iObjectPoint = objectPointMap_.cbegin(); iObjectPoint != objectPointMap_.cend(); ++iObjectPoint)
2402 {
2403 if (iObjectPoint->second.priority() >= minimalPriority && ((tMatchPosition && iObjectPoint->second.point() == referencePosition) || (!tMatchPosition && iObjectPoint->second.point() != referencePosition)))
2404 {
2405 objectPoints.push_back(iObjectPoint->second.point());
2406 objectPointIds->push_back(iObjectPoint->first);
2407 }
2408 }
2409 }
2410 else
2411 {
2412 for (ObjectPointMap::const_iterator iObjectPoint = objectPointMap_.cbegin(); iObjectPoint != objectPointMap_.cend(); ++iObjectPoint)
2413 {
2414 if (iObjectPoint->second.priority() >= minimalPriority && ((tMatchPosition && iObjectPoint->second.point() == referencePosition) || (!tMatchPosition && iObjectPoint->second.point() != referencePosition)))
2415 {
2416 objectPoints.push_back(iObjectPoint->second.point());
2417 }
2418 }
2419 }
2420
2421 return objectPoints;
2422}
2423
2424template <bool tThreadSafe>
2425inline Vectors3 Database::objectPoints(const Indices32& objectPointIds) const
2426{
2427 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
2428
2430 objectPoints.reserve(objectPointIds.size());
2431
2432 for (const Index32 objectPointId : objectPointIds)
2433 {
2434 ocean_assert(objectPointId != invalidId);
2435 ocean_assert(objectPointMap_.find(objectPointId) != objectPointMap_.end());
2436
2437 objectPoints.push_back(objectPointMap_.find(objectPointId)->second.point());
2438 }
2439
2440 return objectPoints;
2441}
2442
2443template <bool tThreadSafe>
2444inline const HomogenousMatrix4& Database::pose(const Index32 poseId) const
2445{
2446 ocean_assert(poseId != invalidId);
2447
2448 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
2449
2450 ocean_assert(poseMap_.find(poseId) != poseMap_.end());
2451 return poseMap_.find(poseId)->second.pose();
2452}
2453
2454template <bool tThreadSafe>
2455inline HomogenousMatrices4 Database::poses(const Index32* poseIds, const size_t size) const
2456{
2457 ocean_assert(poseIds != nullptr && size != 0);
2458
2459 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
2460
2461 HomogenousMatrices4 result;
2462 result.reserve(size);
2463
2464 for (size_t n = 0; n < size; ++n)
2465 {
2466 ocean_assert(poseMap_.find(poseIds[n]) != poseMap_.end());
2467 result.push_back(poseMap_.find(poseIds[n])->second.pose());
2468 }
2469
2470 return result;
2471}
2472
2473template <bool tThreadSafe>
2474inline SquareMatrices3 Database::rotationalPoses(const Index32* poseIds, const size_t size) const
2475{
2476 ocean_assert(poseIds != nullptr && size != 0);
2477
2478 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
2479
2480 SquareMatrices3 result;
2481 result.reserve(size);
2482
2483 for (size_t n = 0; n < size; ++n)
2484 {
2485 ocean_assert(poseMap_.find(poseIds[n]) != poseMap_.end());
2486
2487 const HomogenousMatrix4& pose = poseMap_.find(poseIds[n])->second.pose();
2488
2489 ocean_assert(pose.translation().isNull());
2490 result.push_back(pose.rotationMatrix());
2491 }
2492
2493 return result;
2494}
2495
2496template <bool tThreadSafe, bool tMatchPose>
2497inline HomogenousMatrices4 Database::poses(const HomogenousMatrix4& referencePose, Indices32* poseIds) const
2498{
2499 ocean_assert(!poseIds || poseIds->empty());
2500
2501 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
2502
2504 poses.reserve(poseMap_.size());
2505
2506 if (poseIds != nullptr)
2507 {
2508 poseIds->clear();
2509 poseIds->reserve(poseMap_.size());
2510
2511 for (PoseMap::const_iterator iPose = poseMap_.cbegin(); iPose != poseMap_.cend(); ++iPose)
2512 {
2513 if ((tMatchPose && iPose->second.pose() == referencePose) || (!tMatchPose && iPose->second.pose() != referencePose))
2514 {
2515 poses.push_back(iPose->second.pose());
2516 poseIds->push_back(iPose->first);
2517 }
2518 }
2519 }
2520 else
2521 {
2522 for (PoseMap::const_iterator iPose = poseMap_.cbegin(); iPose != poseMap_.cend(); ++iPose)
2523 {
2524 if ((tMatchPose && iPose->second.pose() == referencePose) || (!tMatchPose && iPose->second.pose() != referencePose))
2525 {
2526 poses.push_back(iPose->second.pose());
2527 }
2528 }
2529 }
2530
2531 return poses;
2532}
2533
2534template <bool tThreadSafe>
2535inline HomogenousMatrices4 Database::poses(const Index32 lowerPoseId, const Index32 upperPoseId) const
2536{
2537 ocean_assert(lowerPoseId <= upperPoseId);
2538
2539 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
2540
2542 poses.reserve(upperPoseId - lowerPoseId + 1u);
2543
2544 for (unsigned int n = lowerPoseId; n <= upperPoseId; ++n)
2545 {
2546 // **TODO** the performance can be improved if we iterate through the map
2547 PoseMap::const_iterator iPose = poseMap_.find(n);
2548 if (iPose != poseMap_.end())
2549 {
2550 poses.push_back(iPose->second.pose());
2551 }
2552 else
2553 {
2554 poses.push_back(HomogenousMatrix4(false));
2555 }
2556 }
2557
2558 return poses;
2559}
2560
2561template <bool tThreadSafe, bool tMatchPose>
2562inline Indices32 Database::poseIds(const HomogenousMatrix4& referencePose, HomogenousMatrices4* poses) const
2563{
2564 ocean_assert(!poses || poses->empty());
2565
2566 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
2567
2569 poseIds.reserve(poseMap_.size());
2570
2571 if (poses != nullptr)
2572 {
2573 poses->clear();
2574 poses->reserve(poseMap_.size());
2575
2576 for (PoseMap::const_iterator iPose = poseMap_.cbegin(); iPose != poseMap_.cend(); ++iPose)
2577 {
2578 if ((tMatchPose && iPose->second.pose() == referencePose) || (!tMatchPose && iPose->second.pose() != referencePose))
2579 {
2580 poseIds.push_back(iPose->first);
2581 poses->push_back(iPose->second.pose());
2582 }
2583 }
2584 }
2585 else
2586 {
2587 for (PoseMap::const_iterator iPose = poseMap_.cbegin(); iPose != poseMap_.cend(); ++iPose)
2588 {
2589 if ((tMatchPose && iPose->second.pose() == referencePose) || (!tMatchPose && iPose->second.pose() != referencePose))
2590 {
2591 poseIds.push_back(iPose->first);
2592 }
2593 }
2594 }
2595
2596 return poseIds;
2597}
2598
2599template <bool tThreadSafe>
2600inline bool Database::poseBorders(Index32& lowerPoseId, Index32& upperPoseId) const
2601{
2602 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
2603
2604 if (poseMap_.empty())
2605 {
2606 return false;
2607 }
2608
2609 lowerPoseId = poseMap_.begin()->first;
2610 upperPoseId = poseMap_.rbegin()->first;
2611
2612 return true;
2613}
2614
2615template <bool tThreadSafe>
2616inline bool Database::validPoseBorders(Index32& rangeLowerPoseId, Index32& rangeUpperPoseId) const
2617{
2618 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
2619
2620 if (poseMap_.empty())
2621 {
2622 return false;
2623 }
2624
2625 rangeLowerPoseId = invalidId;
2626 rangeUpperPoseId = invalidId;
2627
2628 for (PoseMap::const_iterator iPose = poseMap_.cbegin(); iPose != poseMap_.cend(); ++iPose)
2629 {
2630 if (iPose->second.pose().isValid())
2631 {
2632 rangeLowerPoseId = iPose->first;
2633 break;
2634 }
2635 }
2636
2637 if (rangeLowerPoseId == invalidId)
2638 {
2639 return false;
2640 }
2641
2642 for (PoseMap::const_reverse_iterator iPose = poseMap_.rbegin(); iPose != poseMap_.rend(); ++iPose)
2643 {
2644 if (iPose->second.pose().isValid())
2645 {
2646 rangeUpperPoseId = iPose->first;
2647 break;
2648 }
2649 }
2650
2651 ocean_assert(rangeLowerPoseId <= rangeUpperPoseId);
2652 return true;
2653}
2654
2655template <bool tThreadSafe>
2656inline bool Database::validPoseRange(const Index32 lowerPoseId, const Index32 startPoseId, const Index32 upperPoseId, Index32& rangeLowerPoseId, Index32& rangeUpperPoseId) const
2657{
2658 ocean_assert(startPoseId != invalidId);
2659 ocean_assert(lowerPoseId <= startPoseId && startPoseId <= upperPoseId);
2660
2661 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
2662
2663 PoseMap::const_iterator iPose = poseMap_.find(startPoseId);
2664 if (iPose == poseMap_.end() || !(iPose->second.pose().isValid()))
2665 {
2666 return false;
2667 }
2668
2669 rangeLowerPoseId = startPoseId;
2670 rangeUpperPoseId = startPoseId;
2671
2672 for (unsigned int id = startPoseId - 1; id != (unsigned int)(-1) && id >= lowerPoseId; --id)
2673 {
2674 iPose = poseMap_.find(id);
2675
2676 if (iPose == poseMap_.end() || !(iPose->second.pose().isValid()))
2677 {
2678 break;
2679 }
2680
2681 rangeLowerPoseId = id;
2682 }
2683
2684 for (unsigned int id = startPoseId + 1u; id <= upperPoseId; ++id)
2685 {
2686 iPose = poseMap_.find(id);
2687
2688 if (iPose == poseMap_.end() || !(iPose->second.pose().isValid()))
2689 {
2690 break;
2691 }
2692
2693 rangeUpperPoseId = id;
2694 }
2695
2696 return true;
2697}
2698
2699template <bool tThreadSafe>
2700inline bool Database::largestValidPoseRange(const Index32 lowerPoseId, const Index32 upperPoseId, Index32& rangeLowerPoseId, Index32& rangeUpperPoseId) const
2701{
2702 ocean_assert(lowerPoseId <= upperPoseId);
2703
2704 if (lowerPoseId > upperPoseId)
2705 {
2706 return false;
2707 }
2708
2709 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
2710
2711 const HomogenousMatrices4 rangePoses(poses<false>(lowerPoseId, upperPoseId));
2712
2713 unsigned int bestRangeSize = 0u;
2714 unsigned int firstIndex = (unsigned int)(-1);
2715
2716 for (unsigned int n = 0u; n < rangePoses.size(); ++n)
2717 {
2718 if (firstIndex == (unsigned int)(-1))
2719 {
2720 if (rangePoses[n].isValid())
2721 {
2722 firstIndex = n;
2723 }
2724 }
2725 else if (!rangePoses[n].isValid())
2726 {
2727 const unsigned int lastIndex = n - 1u;
2728 ocean_assert(firstIndex >= 0u && lastIndex < (unsigned int)rangePoses.size());
2729
2730 const unsigned int rangeSize = lastIndex - firstIndex + 1u;
2731
2732 if (rangeSize > bestRangeSize)
2733 {
2734 bestRangeSize = rangeSize;
2735 rangeLowerPoseId = firstIndex + lowerPoseId;
2736 rangeUpperPoseId = lastIndex + lowerPoseId;
2737
2738 // check whether the remaining part is too small to be larger than the currently best range
2739 if (rangePoses.size() - n < bestRangeSize)
2740 {
2741 return true;
2742 }
2743 }
2744
2745 firstIndex = (unsigned int)(-1);
2746 }
2747 }
2748
2749 if (firstIndex == (unsigned int)(-1))
2750 {
2751 return bestRangeSize != 0u;
2752 }
2753
2754 const unsigned int lastIndex = (unsigned int)rangePoses.size() - 1u;
2755 ocean_assert(firstIndex >= 0u && lastIndex < (unsigned int)rangePoses.size());
2756
2757 const unsigned int rangeSize = lastIndex - firstIndex + 1u;
2758 if (rangeSize > bestRangeSize)
2759 {
2760 rangeLowerPoseId = firstIndex + lowerPoseId;
2761 rangeUpperPoseId = lastIndex + lowerPoseId;
2762
2763 bestRangeSize = rangeSize;
2764 }
2765
2766 ocean_assert(bestRangeSize != 0u);
2767 return true;
2768}
2769
2770template <bool tThreadSafe, bool tMatchPosition, bool tNeedValidPose>
2771inline bool Database::poseWithMostCorrespondences(const Index32 lowerPoseId, const Index32 upperPoseId, Index32* poseId, unsigned int* correspondences, const Vector3& referenceObjectPoint) const
2772{
2773 ocean_assert(lowerPoseId != invalidId && upperPoseId != invalidId);
2774 ocean_assert(lowerPoseId <= upperPoseId);
2775
2776 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
2777
2778 Index32 bestPoseId = invalidId;
2779 unsigned int bestCorrespondences = 0u;
2780
2781 for (unsigned int id = lowerPoseId; id <= upperPoseId; ++id)
2782 {
2783 const unsigned int value = numberCorrespondences<false, tMatchPosition, tNeedValidPose>(id, referenceObjectPoint);
2784 if (value > bestCorrespondences)
2785 {
2786 bestCorrespondences = value;
2787 bestPoseId = id;
2788 }
2789 }
2790
2791 if (poseId != nullptr)
2792 {
2793 *poseId = bestPoseId;
2794 }
2795
2796 if (correspondences != nullptr)
2797 {
2798 *correspondences = bestCorrespondences;
2799 }
2800
2801 return bestCorrespondences != 0u;
2802}
2803
2804template <bool tThreadSafe, bool tMatchPosition, bool tNeedValidPose>
2805inline bool Database::poseWithLeastCorrespondences(const Index32 lowerPoseId, const Index32 upperPoseId, Index32* poseId, unsigned int* correspondences, const Vector3& referenceObjectPoint) const
2806{
2807 ocean_assert(lowerPoseId != invalidId && upperPoseId != invalidId);
2808 ocean_assert(lowerPoseId <= upperPoseId);
2809
2810 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
2811
2812 Index32 worstPoseId = invalidId;
2813 unsigned int worstCorrespondences = (unsigned int)(-1);
2814
2816
2817 for (unsigned int id = lowerPoseId; id <= upperPoseId; ++id)
2818 {
2819 if (tNeedValidPose && (!hasPose<false>(id, &pose) || !pose.isValid()))
2820 {
2821 continue;
2822 }
2823
2824 const unsigned int value = numberCorrespondences<false, tMatchPosition, false>(id, referenceObjectPoint);
2825 if (value < worstCorrespondences)
2826 {
2827 worstCorrespondences = value;
2828 worstPoseId = id;
2829 }
2830 }
2831
2832 if (poseId != nullptr)
2833 {
2834 *poseId = worstPoseId;
2835 }
2836
2837 if (correspondences != nullptr)
2838 {
2839 *correspondences = worstCorrespondences;
2840 }
2841
2842 return worstCorrespondences != (unsigned int)(-1);
2843}
2844
2845template <bool tThreadSafe>
2846inline bool Database::poseWithMostObservations(const IndexSet32& poseCandidates, const IndexSet32& majorObjectPointIds, const IndexSet32& minorObjectPointIds, Index32& pose, Indices32* visibleMajorObjectPointIds, Indices32* visibleMinorObjectPointIds) const
2847{
2848 ocean_assert(!poseCandidates.empty());
2849 ocean_assert(!majorObjectPointIds.empty());
2850
2851 if (majorObjectPointIds.empty())
2852 {
2853 return false;
2854 }
2855
2856 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
2857
2858 unsigned int bestMajorCount = 0u;
2859 unsigned int bestMinorCount = 0u;
2860
2861 Index32 bestPoseId = invalidId;
2862
2863 for (const Index32 poseCandidate : poseCandidates)
2864 {
2865 const Index32 poseId = poseCandidate;
2866
2867 unsigned int majorCount = 0u;
2868 unsigned int remaining = (unsigned int)majorObjectPointIds.size();
2869
2870 for (IndexSet32::const_iterator iId = majorObjectPointIds.begin(); majorCount + remaining >= bestMajorCount && iId != majorObjectPointIds.end(); ++iId)
2871 {
2872 if (poseObjectPointMap_.find(index64(poseId, *iId)) != poseObjectPointMap_.end())
2873 {
2874 majorCount++;
2875 }
2876
2877 remaining--;
2878 }
2879
2880 if (majorCount >= bestMajorCount)
2881 {
2882 unsigned int minorCount = 0u;
2883 remaining = (unsigned int)minorObjectPointIds.size();
2884
2885 for (IndexSet32::const_iterator iId = minorObjectPointIds.begin(); minorCount + remaining >= bestMinorCount && iId != minorObjectPointIds.end(); ++iId)
2886 {
2887 if (poseObjectPointMap_.find(index64(poseId, *iId)) != poseObjectPointMap_.end())
2888 {
2889 minorCount++;
2890 }
2891
2892 remaining--;
2893 }
2894
2895 if (majorCount > bestMajorCount || minorCount > bestMinorCount)
2896 {
2897 bestPoseId = poseId;
2898 bestMajorCount = majorCount;
2899 bestMinorCount = minorCount;
2900 }
2901 }
2902 }
2903
2904 if (bestPoseId == invalidId)
2905 {
2906 return false;
2907 }
2908
2909 pose = bestPoseId;
2910
2911 if (visibleMajorObjectPointIds != nullptr)
2912 {
2913 ocean_assert(visibleMajorObjectPointIds->empty());
2914 visibleMajorObjectPointIds->clear();
2915 visibleMajorObjectPointIds->reserve(bestMajorCount);
2916
2917 for (const Index32 majorObjectPointId : majorObjectPointIds)
2918 {
2919 if (poseObjectPointMap_.find(index64(bestPoseId, majorObjectPointId)) != poseObjectPointMap_.end())
2920 {
2921 visibleMajorObjectPointIds->push_back(majorObjectPointId);
2922 }
2923 }
2924
2925 ocean_assert(bestMajorCount == visibleMajorObjectPointIds->size());
2926 }
2927
2928 if (visibleMinorObjectPointIds != nullptr)
2929 {
2930 ocean_assert(visibleMinorObjectPointIds->empty());
2931 visibleMinorObjectPointIds->clear();
2932 visibleMinorObjectPointIds->reserve(minorObjectPointIds.size());
2933
2934 for (const Index32 minorObjectPointId : minorObjectPointIds)
2935 {
2936 if (poseObjectPointMap_.find(index64(bestPoseId, minorObjectPointId)) != poseObjectPointMap_.end())
2937 {
2938 visibleMinorObjectPointIds->push_back(minorObjectPointId);
2939 }
2940 }
2941
2942 ocean_assert(bestMinorCount == visibleMinorObjectPointIds->size());
2943 }
2944
2945 return true;
2946}
2947
2948template <bool tThreadSafe>
2949inline unsigned int Database::numberObservations(const Index32 poseId, const Indices32& objectPointIds) const
2950{
2951 ocean_assert(poseId != invalidId);
2952
2953 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
2954
2955 unsigned int number = 0u;
2956
2957 for (const Index32 objectPointId : objectPointIds)
2958 {
2959 if (poseObjectPointMap_.find(index64(poseId, objectPointId)) != poseObjectPointMap_.end())
2960 {
2961 number++;
2962 }
2963 }
2964
2965 return number;
2966}
2967
2968template <bool tThreadSafe, bool tMatchPosition, bool tNeedValidPose>
2969inline unsigned int Database::numberCorrespondences(const Index32 poseId, const Vector3& referenceObjectPoint, const Scalar minimalPriority) const
2970{
2971 ocean_assert(poseId != invalidId);
2972
2973 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
2974
2975 const PoseMap::const_iterator iPose = poseMap_.find(poseId);
2976 if (iPose == poseMap_.end() || (tNeedValidPose && !(iPose->second.pose().isValid())))
2977 {
2978 return 0u;
2979 }
2980
2981 unsigned int count = 0u;
2982
2983 const IndexSet32& imagePointIds = iPose->second.imagePointIds();
2984 for (const Index32 imagePointId : imagePointIds)
2985 {
2986 const ImagePointMap::const_iterator iImagePoint = imagePointMap_.find(imagePointId);
2987 ocean_assert(iImagePoint != imagePointMap_.end());
2988
2989 const ObjectPointMap::const_iterator iObjectPoint = objectPointMap_.find(iImagePoint->second.objectPointId());
2990 ocean_assert(iObjectPoint != objectPointMap_.end());
2991
2992 if (iObjectPoint->second.priority() >= minimalPriority && ((tMatchPosition && iObjectPoint->second.point() == referenceObjectPoint) || (!tMatchPosition && iObjectPoint->second.point() != referenceObjectPoint)))
2993 {
2994 count++;
2995 }
2996 }
2997
2998 return count;
2999}
3000
3001template <bool tThreadSafe, bool tMatchPosition, bool tNeedValidPose>
3002inline Indices32 Database::numberCorrespondences(const Index32 lowerPoseId, const Index32 upperPoseId, const Vector3& referenceObjectPoint, const Scalar minimalPriority, Worker* worker) const
3003{
3004 ocean_assert(lowerPoseId <= upperPoseId);
3005
3006 const unsigned int frames = upperPoseId - lowerPoseId + 1u;
3007
3008 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
3009
3010 Indices32 result;
3011
3012 if (worker && frames >= 20u)
3013 {
3014 result.resize(frames);
3015
3016 worker->executeFunction(Worker::Function::create(*this, &Database::numberCorrespondencesSubset<tMatchPosition, tNeedValidPose>, lowerPoseId, &referenceObjectPoint, minimalPriority, result.data(), 0u, 0u), 0u, frames);
3017 }
3018 else
3019 {
3020 result.reserve(frames);
3021
3022 for (unsigned int n = lowerPoseId; n <= upperPoseId; ++n)
3023 {
3024 result.push_back(numberCorrespondences<false, tMatchPosition, tNeedValidPose>(n, referenceObjectPoint, minimalPriority));
3025 }
3026 }
3027
3028 return result;
3029}
3030
3031template <bool tThreadSafe>
3032inline bool Database::hasImagePoint(const Index32 imagePointId, Vector2* imagePoint) const
3033{
3034 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
3035
3036 const ImagePointMap::const_iterator iImagePoint = imagePointMap_.find(imagePointId);
3037
3038 if (iImagePoint == imagePointMap_.end())
3039 {
3040 return false;
3041 }
3042
3043 if (imagePoint != nullptr)
3044 {
3045 *imagePoint = iImagePoint->second.point();
3046 }
3047
3048 return true;
3049}
3050
3051template <bool tThreadSafe>
3052inline Index32 Database::addImagePoint(const Vector2& imagePoint)
3053{
3054 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
3055
3057 return imagePointIdCounter_;
3058}
3059
3060template <bool tThreadSafe>
3061inline void Database::removeImagePoint(const Index32 imagePointId)
3062{
3063 ocean_assert(imagePointId != invalidId);
3064
3065 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
3066
3067 const ImagePointMap::iterator iImagePoint = imagePointMap_.find(imagePointId);
3068 ocean_assert(iImagePoint != imagePointMap_.end());
3069
3070 // we need to remove all connections of the specified image point
3071 const ImagePointData& data = iImagePoint->second;
3072
3073 if (data.poseId() != invalidId)
3074 {
3075 PoseMap::iterator iPose = poseMap_.find(data.poseId());
3076 ocean_assert(iPose != poseMap_.end());
3077
3078 iPose->second.unregisterImagePoint(imagePointId);
3079 }
3080
3081 if (data.objectPointId() != invalidId)
3082 {
3083 ObjectPointMap::iterator iObjectPoint = objectPointMap_.find(data.objectPointId());
3084 ocean_assert(iObjectPoint != objectPointMap_.end());
3085
3086 iObjectPoint->second.unregisterImagePoint(imagePointId);
3087 }
3088
3089 imagePointMap_.erase(iImagePoint);
3090}
3091
3092template <bool tThreadSafe>
3093inline bool Database::hasObjectPoint(const Index32 objectPointId, Vector3* objectPoint) const
3094{
3095 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
3096
3097 const ObjectPointMap::const_iterator iObjectPoint = objectPointMap_.find(objectPointId);
3098
3099 if (iObjectPoint == objectPointMap_.end())
3100 {
3101 return false;
3102 }
3103
3104 if (objectPoint != nullptr)
3105 {
3106 *objectPoint = iObjectPoint->second.point();
3107 }
3108
3109 return true;
3110}
3111
3112template <bool tThreadSafe>
3113inline Index32 Database::addObjectPoint(const Vector3& objectPoint, const Scalar priority)
3114{
3115 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
3116
3117 ocean_assert(objectPointMap_.find(objectPointIdCounter_ + 1u) == objectPointMap_.end() && "You mixed calls with the add-objectPoint-function using external object point ids!");
3118
3119 objectPointMap_.insert(std::make_pair(++objectPointIdCounter_, ObjectPointData(objectPoint, priority)));
3120 return objectPointIdCounter_;
3121}
3122
3123template <bool tThreadSafe>
3124inline void Database::addObjectPoint(const Index32 objectPointId, const Vector3& objectPoint, const Scalar priority)
3125{
3126 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
3127
3128 ocean_assert(objectPointMap_.find(objectPointId) == objectPointMap_.end());
3129 ocean_assert((objectPointIdCounter_ == invalidId || objectPointId + 1u <= objectPointIdCounter_) && "You mixed calls with the add-objectPoint-function using external object point ids!");
3130
3131 objectPointMap_[objectPointId] = ObjectPointData(objectPoint, priority);
3132}
3133
3134inline Index32 Database::addObjectPointFromDatabase(const Database& secondDatabase, const Index32 secondDatabaseObjectPointId, const SquareMatrix3& imagePointTransformation, const Index32 newObjectPointId, const Index32 secondDatabaseLowerPoseId, const Index32 secondDatabaseUpperPoseId, const bool forExistingPosesOnly)
3135{
3136 ocean_assert(secondDatabase.hasObjectPoint<false>(secondDatabaseObjectPointId));
3137 ocean_assert(!imagePointTransformation.isSingular());
3138 ocean_assert(secondDatabaseLowerPoseId == invalidId || secondDatabaseUpperPoseId == invalidId || secondDatabaseLowerPoseId <= secondDatabaseUpperPoseId);
3139
3140 // first we copy the location of the 3D object point
3141
3143 const Vector3& objectPoint = secondDatabase.objectPoint<false>(secondDatabaseObjectPointId, objectPointPriority);
3144
3145 Index32 thisDatabaseObjectPointId = invalidId;
3146
3147 // we want to ensure that an explicit id of the new object point does not exist in this database
3148 ocean_assert(newObjectPointId == invalidId || hasObjectPoint<false>(newObjectPointId) == false);
3149 if (newObjectPointId != invalidId)
3150 {
3151 if (hasObjectPoint<false>(newObjectPointId))
3152 {
3153 return invalidId;
3154 }
3155
3156 addObjectPoint<false>(newObjectPointId, objectPoint, objectPointPriority);
3157 thisDatabaseObjectPointId = newObjectPointId;
3158 }
3159 else
3160 {
3161 thisDatabaseObjectPointId = addObjectPoint<false>(objectPoint, objectPointPriority);
3162 }
3163
3164 // now we have add the corresponding image points (and ensure that a pose exists in this database)
3165
3166 const IndexSet32& secondDatabaseImagePointIds = secondDatabase.imagePointsFromObjectPoint<false>(secondDatabaseObjectPointId);
3167
3168 for (IndexSet32::const_iterator iId = secondDatabaseImagePointIds.cbegin(); iId != secondDatabaseImagePointIds.cend(); ++iId)
3169 {
3170 const Index32& secondDatabaseImagePointId = *iId;
3171
3172 const Index32 poseId = secondDatabase.poseFromImagePoint<false>(secondDatabaseImagePointId);
3173
3174 // the pose id in the second database is identical to the pose id in this database
3175
3176 // we check whether the user had specified a pose range
3177
3178 if ((secondDatabaseLowerPoseId != invalidId && poseId < secondDatabaseLowerPoseId)
3179 || (secondDatabaseUpperPoseId != invalidId && poseId > secondDatabaseUpperPoseId))
3180 {
3181 // the pose id is outside the specified pose range, so we skip this image point (this observation)
3182 continue;
3183 }
3184
3185 if (!hasPose<false>(poseId))
3186 {
3187 if (forExistingPosesOnly)
3188 {
3189 // the user does not want us to create a new pose, so we simply skip this image point (this observation)
3190 continue;
3191 }
3192
3193 // we need to create a pose in this database
3194
3195 const HomogenousMatrix4& pose = secondDatabase.pose<false>(poseId);
3196
3197 const bool addPoseResult = addPose<false>(poseId, pose);
3198 ocean_assert_and_suppress_unused(addPoseResult, addPoseResult);
3199 }
3200
3201 // now, as we know that the pose exists in this database, we simply add the image point and register/connect it with the pose
3202
3203 const Vector2& imagePoint = secondDatabase.imagePoint<false>(secondDatabaseImagePointId);
3204
3205 // we apply the provided transformation before adding the image point to this database
3206
3207 const Index32 thisDatabaseImagePointId = addImagePoint<false>(imagePointTransformation * imagePoint);
3208
3209 attachImagePointToObjectPoint<false>(thisDatabaseImagePointId, thisDatabaseObjectPointId);
3210 attachImagePointToPose<false>(thisDatabaseImagePointId, poseId);
3211 }
3212
3213 return thisDatabaseObjectPointId;
3214}
3215
3216template <bool tThreadSafe>
3217inline void Database::removeObjectPoint(const Index32 objectPointId)
3218{
3219 ocean_assert(objectPointId != invalidId);
3220
3221 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
3222
3223 const ObjectPointMap::iterator iObjectPoint = objectPointMap_.find(objectPointId);
3224 ocean_assert(iObjectPoint != objectPointMap_.end());
3225
3226 // we need to remove all connections of the specified object point
3227
3228 const ObjectPointData& data = iObjectPoint->second;
3229
3230 for (const Index32 imagePointId : data.imagePointIds())
3231 {
3232 ImagePointMap::iterator iImagePoint = imagePointMap_.find(imagePointId);
3233 ocean_assert(iImagePoint != imagePointMap_.end());
3234
3235 if (iImagePoint->second.poseId() != invalidId)
3236 {
3237 ocean_assert(poseObjectPointMap_.find(index64(iImagePoint->second.poseId(), objectPointId)) != poseObjectPointMap_.end());
3238 poseObjectPointMap_.erase(index64(iImagePoint->second.poseId(), objectPointId));
3239 }
3240
3241 iImagePoint->second.setObjectPointId(invalidId);
3242 }
3243
3244 objectPointMap_.erase(iObjectPoint);
3245}
3246
3247template <bool tThreadSafe>
3249{
3250 ocean_assert(objectPointId != invalidId);
3251
3252 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
3253
3254 const ObjectPointMap::iterator iObjectPoint = objectPointMap_.find(objectPointId);
3255 ocean_assert(iObjectPoint != objectPointMap_.cend());
3256
3257 // we need to remove all connections of the specified object point
3258
3259 const ObjectPointData& objectPointData = iObjectPoint->second;
3260
3261 for (const Index32& imagePointId : objectPointData.imagePointIds())
3262 {
3263 const ImagePointMap::iterator iImagePoint = imagePointMap_.find(imagePointId);
3264 ocean_assert(iImagePoint != imagePointMap_.cend());
3265
3266 const Index32 poseId = iImagePoint->second.poseId();
3267
3268 if (poseId != invalidId)
3269 {
3270 ocean_assert(poseObjectPointMap_.find(index64(poseId, objectPointId)) != poseObjectPointMap_.cend());
3271 poseObjectPointMap_.erase(index64(poseId, objectPointId));
3272
3273 const PoseMap::iterator iPose = poseMap_.find(poseId);
3274 ocean_assert(iPose != poseMap_.cend());
3275
3276 iPose->second.unregisterImagePoint(imagePointId);
3277 }
3278
3279 imagePointMap_.erase(iImagePoint);
3280 }
3281
3282 objectPointMap_.erase(iObjectPoint);
3283}
3284
3285template <bool tThreadSafe>
3286inline void Database::renameObjectPoint(const Index32 oldObjectPointId, const Index32 newObjectPointId)
3287{
3288 ocean_assert(oldObjectPointId != invalidId && newObjectPointId != invalidId);
3289
3290 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
3291
3292 ocean_assert(objectPointMap_.find(newObjectPointId) == objectPointMap_.end());
3293
3294 ObjectPointMap::iterator iObjectPoint = objectPointMap_.find(oldObjectPointId);
3295 ocean_assert(iObjectPoint != objectPointMap_.end());
3296
3297 const IndexSet32& imagePointIds = iObjectPoint->second.imagePointIds();
3298
3299 for (const Index32 imagePointId : imagePointIds)
3300 {
3301 ImagePointMap::iterator iImagePoint = imagePointMap_.find(imagePointId);
3302 ocean_assert(iImagePoint != imagePointMap_.end());
3303
3304 ocean_assert(iImagePoint->second.objectPointId() == oldObjectPointId);
3305 iImagePoint->second.setObjectPointId(newObjectPointId);
3306
3307 if (iImagePoint->second.poseId() != invalidId)
3308 {
3309 const Index64 oldPoseObjectPointId = index64(iImagePoint->second.poseId(), oldObjectPointId);
3310
3311 ocean_assert(poseObjectPointMap_.find(oldPoseObjectPointId) != poseObjectPointMap_.cend());
3312 poseObjectPointMap_.erase(oldPoseObjectPointId);
3313
3314 const Index64 newPoseObjectPointId = index64(iImagePoint->second.poseId(), newObjectPointId);
3315
3316 ocean_assert(poseObjectPointMap_.find(newPoseObjectPointId) == poseObjectPointMap_.cend());
3317 poseObjectPointMap_.insert(std::make_pair(newPoseObjectPointId, imagePointId));
3318 }
3319 }
3320
3321 objectPointMap_.insert(std::make_pair(newObjectPointId, std::move(iObjectPoint->second)));
3322 objectPointMap_.erase(iObjectPoint);
3323}
3324
3325template <bool tThreadSafe>
3326inline void Database::mergeObjectPoints(const Index32 remainingObjectPointId, const Index32 removingObjectPointId, const Vector3& newPoint, const Scalar newPriority)
3327{
3328 ocean_assert(remainingObjectPointId != invalidId && removingObjectPointId != invalidId && remainingObjectPointId != removingObjectPointId);
3329
3330 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
3331
3332 ObjectPointMap::iterator iObjectPointRemaining = objectPointMap_.find(remainingObjectPointId);
3333 ocean_assert(iObjectPointRemaining != objectPointMap_.cend());
3334
3335 ObjectPointMap::const_iterator iObjectPointRemoving = objectPointMap_.find(removingObjectPointId);
3336 ocean_assert(iObjectPointRemoving != objectPointMap_.cend());
3337
3338#ifdef OCEAN_DEBUG
3339 const IndexSet32 debugPoseIdsRemaining = posesFromObjectPoint<false>(remainingObjectPointId);
3340 const IndexSet32 debugPoseIdsRemoving = posesFromObjectPoint<false>(removingObjectPointId);
3341 ocean_assert(!Subset::hasIntersectingElement(debugPoseIdsRemaining, debugPoseIdsRemoving));
3342#endif
3343
3344 for (const Index32& imagePointIdRemoving : iObjectPointRemoving->second.imagePointIds())
3345 {
3346 iObjectPointRemaining->second.registerImagePoint(imagePointIdRemoving);
3347
3348 ImagePointMap::iterator iImagePointRemoving = imagePointMap_.find(imagePointIdRemoving);
3349 ocean_assert(iImagePointRemoving != imagePointMap_.cend());
3350
3351 const Index32 poseIdRemoving = iImagePointRemoving->second.poseId();
3352
3353 ocean_assert(poseObjectPointMap_.find(index64(poseIdRemoving, removingObjectPointId)) != poseObjectPointMap_.cend());
3354 poseObjectPointMap_.erase(index64(poseIdRemoving, removingObjectPointId));
3355
3356 ocean_assert(poseObjectPointMap_.find(index64(poseIdRemoving, remainingObjectPointId)) == poseObjectPointMap_.cend());
3357 poseObjectPointMap_.emplace(index64(poseIdRemoving, remainingObjectPointId), imagePointIdRemoving);
3358
3359 iImagePointRemoving->second.setObjectPointId(remainingObjectPointId);
3360 }
3361
3362 iObjectPointRemaining->second.setPoint(newPoint);
3363 iObjectPointRemaining->second.setPriority(newPriority);
3364
3365 objectPointMap_.erase(iObjectPointRemoving);
3366}
3367
3368template <bool tThreadSafe>
3369inline bool Database::hasPose(const Index32 poseId, HomogenousMatrix4* pose) const
3370{
3371 ocean_assert(poseId != invalidId);
3372
3373 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
3374
3375 const PoseMap::const_iterator iPose = poseMap_.find(poseId);
3376 if (iPose == poseMap_.end())
3377 {
3378 return false;
3379 }
3380
3381 if (pose != nullptr)
3382 {
3383 *pose = iPose->second.pose();
3384 }
3385
3386 return true;
3387}
3388
3389template <bool tThreadSafe>
3390inline bool Database::addPose(const Index32 poseId, const HomogenousMatrix4& pose)
3391{
3392 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
3393
3394 const PoseMap::const_iterator iPose = poseMap_.find(poseId);
3395 if (iPose != poseMap_.end())
3396 {
3397 ocean_assert(false && "Invalid pose id!");
3398 return false;
3399 }
3400
3401 poseMap_.insert(std::make_pair(poseId, PoseData(pose)));
3402
3403 poses_ = max(poses_, poseId + 1u);
3404
3405 return true;
3406}
3407
3408template <bool tThreadSafe>
3409inline void Database::removePose(const Index32 poseId)
3410{
3411 ocean_assert(poseId != invalidId);
3412
3413 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
3414
3415 const PoseMap::iterator iPose = poseMap_.find(poseId);
3416 ocean_assert(iPose != poseMap_.end());
3417
3418 // we need to remove all connections of the specified pose
3419
3420 const PoseData& data = iPose->second;
3421
3422 for (const Index32 imagePointId : data.imagePointIds())
3423 {
3424 ImagePointMap::iterator iImagePoint = imagePointMap_.find(imagePointId);
3425 ocean_assert(iImagePoint != imagePointMap_.end());
3426
3427 iImagePoint->second.setPoseId(invalidId);
3428 }
3429
3430 poseMap_.erase(iPose);
3431}
3432
3433template <bool tThreadSafe>
3434inline Index32 Database::poseFromImagePoint(const Index32 imagePointId) const
3435{
3436 ocean_assert(imagePointId != invalidId);
3437
3438 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
3439
3440 const ImagePointMap::const_iterator iImagePoint = imagePointMap_.find(imagePointId);
3441 ocean_assert(iImagePoint != imagePointMap_.end());
3442
3443 return iImagePoint->second.poseId();
3444}
3445
3446template <bool tThreadSafe>
3447inline size_t Database::numberImagePointsFromObjectPoint(const Index32 objectPointId) const
3448{
3449 ocean_assert(objectPointId != invalidId);
3450
3451 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
3452
3453 const ObjectPointMap::const_iterator iObjectPoint = objectPointMap_.find(objectPointId);
3454 ocean_assert(iObjectPoint != objectPointMap_.end());
3455
3456 const IndexSet32& ids = iObjectPoint->second.imagePointIds();
3457
3458 return ids.size();
3459}
3460
3461template <bool tThreadSafe>
3462inline void Database::observationsFromObjectPoint(const Index32 objectPointId, Indices32& poseIds, Indices32& imagePointIds, Vectors2* imagePoints) const
3463{
3464 ocean_assert(objectPointId != invalidId);
3465 ocean_assert(poseIds.empty() && imagePointIds.empty());
3466 ocean_assert(imagePoints == nullptr || imagePoints->empty());
3467
3468 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
3469
3470 const ObjectPointMap::const_iterator iObjectPoint = objectPointMap_.find(objectPointId);
3471 ocean_assert(iObjectPoint != objectPointMap_.end());
3472
3473 const IndexSet32& ids = iObjectPoint->second.imagePointIds();
3474
3475 poseIds.reserve(ids.size());
3476 imagePointIds.reserve(ids.size());
3477
3478 if (imagePoints != nullptr)
3479 {
3480 imagePoints->reserve(ids.size());
3481 }
3482
3483 for (const Index32 id : ids)
3484 {
3485 const ImagePointMap::const_iterator iImagePoint = imagePointMap_.find(id);
3486 ocean_assert(iImagePoint != imagePointMap_.end());
3487
3488 if (iImagePoint->second.poseId() != invalidId)
3489 {
3490 poseIds.push_back(iImagePoint->second.poseId());
3491 imagePointIds.push_back(id);
3492
3493 if (imagePoints != nullptr)
3494 {
3495 imagePoints->push_back(iImagePoint->second.point());
3496 }
3497 }
3498 }
3499}
3500
3501template <bool tThreadSafe>
3502inline void Database::observationsFromObjectPoint(const Index32 objectPointId, const Indices32& poseIdCandidates, Indices32& validPoseIndices, Indices32* imagePointIds, Vectors2* imagePoints) const
3503{
3504 ocean_assert(objectPointId != invalidId);
3505 ocean_assert(!poseIdCandidates.empty() && validPoseIndices.empty());
3506
3507 ocean_assert(imagePointIds == nullptr || imagePointIds->empty());
3508 ocean_assert(imagePoints == nullptr || imagePoints->empty());
3509
3510 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
3511
3512 for (size_t n = 0; n < poseIdCandidates.size(); ++n)
3513 {
3514 const Index32 poseId = poseIdCandidates[n];
3515
3516 const Index64To32Map::const_iterator iPoseObjectPoint = poseObjectPointMap_.find(index64(poseId, objectPointId));
3517
3518 if (iPoseObjectPoint != poseObjectPointMap_.end())
3519 {
3520 validPoseIndices.push_back((unsigned int)n);
3521
3522 if (imagePointIds != nullptr)
3523 {
3524 imagePointIds->push_back(iPoseObjectPoint->second);
3525 }
3526
3527 if (imagePoints != nullptr)
3528 {
3529 ocean_assert(imagePointMap_.find(iPoseObjectPoint->second) != imagePointMap_.end());
3530 imagePoints->push_back(imagePointMap_.find(iPoseObjectPoint->second)->second.point());
3531 }
3532 }
3533 }
3534}
3535
3536template <bool tThreadSafe>
3538{
3539 ocean_assert(imagePointId != invalidId);
3540
3541 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
3542
3543 const ImagePointMap::const_iterator iImagePoint = imagePointMap_.find(imagePointId);
3544 ocean_assert(iImagePoint != imagePointMap_.end());
3545
3546 return iImagePoint->second.objectPointId();
3547}
3548
3549template <bool tThreadSafe>
3550inline const IndexSet32& Database::imagePointsFromPose(const Index32 poseId) const
3551{
3552 ocean_assert(poseId != invalidId);
3553
3554 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
3555
3556 const PoseMap::const_iterator iPose = poseMap_.find(poseId);
3557 ocean_assert(iPose != poseMap_.end());
3558
3559 return iPose->second.imagePointIds();
3560}
3561
3562template <bool tThreadSafe>
3563inline const IndexSet32& Database::imagePointsFromObjectPoint(const Index32 objectPointId) const
3564{
3565 ocean_assert(objectPointId != invalidId);
3566
3567 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
3568
3569 const ObjectPointMap::const_iterator iObjectPoint = objectPointMap_.find(objectPointId);
3570 ocean_assert(iObjectPoint != objectPointMap_.cend());
3571
3572 return iObjectPoint->second.imagePointIds();
3573}
3574
3575template <bool tThreadSafe>
3576inline IndexSet32 Database::posesFromObjectPoint(const Index32 objectPointId) const
3577{
3578 ocean_assert(objectPointId != invalidId);
3579
3580 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
3581
3582 const ObjectPointMap::const_iterator iObjectPoint = objectPointMap_.find(objectPointId);
3583 ocean_assert(iObjectPoint != objectPointMap_.cend());
3584
3585 IndexSet32 result;
3586
3587 for (const Index32& imagePointId : iObjectPoint->second.imagePointIds())
3588 {
3589 const ImagePointMap::const_iterator iImagePoint = imagePointMap_.find(imagePointId);
3590 ocean_assert(iImagePoint != imagePointMap_.cend());
3591
3592 result.emplace(iImagePoint->second.poseId());
3593 }
3594
3595 return result;
3596}
3597
3598template <bool tThreadSafe>
3599inline void Database::attachImagePointToObjectPoint(const Index32 imagePointId, const Index32 objectPointId)
3600{
3601 ocean_assert(imagePointId != invalidId && objectPointId != invalidId);
3602
3603 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
3604
3605 ImagePointMap::iterator iImagePoint = imagePointMap_.find(imagePointId);
3606 ocean_assert(iImagePoint != imagePointMap_.end());
3607 ocean_assert(iImagePoint->second.objectPointId() == invalidId);
3608
3609 iImagePoint->second.setObjectPointId(objectPointId);
3610
3611 ObjectPointMap::iterator iObjectPoint = objectPointMap_.find(objectPointId);
3612 ocean_assert(iObjectPoint != objectPointMap_.end());
3613
3614 iObjectPoint->second.registerImagePoint(imagePointId);
3615
3616 if (iImagePoint->second.poseId() != invalidId)
3617 {
3618 const Index64 poseObjectPointId(index64(iImagePoint->second.poseId(), objectPointId));
3619
3620 ocean_assert(poseObjectPointMap_.find(poseObjectPointId) == poseObjectPointMap_.end());
3621 poseObjectPointMap_.insert(std::make_pair(poseObjectPointId, imagePointId));
3622 }
3623}
3624
3625template <bool tThreadSafe>
3627{
3628 ocean_assert(imagePointId != invalidId);
3629
3630 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
3631
3632 ImagePointMap::iterator iImagePoint = imagePointMap_.find(imagePointId);
3633 ocean_assert(iImagePoint != imagePointMap_.end());
3634
3635 const Index32 objectPointId = iImagePoint->second.objectPointId();
3636 ocean_assert(objectPointId != invalidId);
3637
3638 iImagePoint->second.setObjectPointId(invalidId);
3639
3640 ObjectPointMap::iterator iObjectPoint = objectPointMap_.find(objectPointId);
3641 ocean_assert(iObjectPoint != objectPointMap_.end());
3642
3643 iObjectPoint->second.unregisterImagePoint(imagePointId);
3644
3645 if (iImagePoint->second.poseId() != invalidId)
3646 {
3647 const Index64 poseObjectPointId(index64(iImagePoint->second.poseId(), objectPointId));
3648
3649 ocean_assert(poseObjectPointMap_.find(poseObjectPointId) != poseObjectPointMap_.end());
3650 poseObjectPointMap_.erase(poseObjectPointId);
3651 }
3652}
3653
3654template <bool tThreadSafe>
3655inline void Database::attachImagePointToPose(const Index32 imagePointId, const Index32 poseId)
3656{
3657 ocean_assert(imagePointId != invalidId && poseId != invalidId);
3658
3659 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
3660
3661 ImagePointMap::iterator iImagePoint = imagePointMap_.find(imagePointId);
3662 ocean_assert(iImagePoint != imagePointMap_.end());
3663 ocean_assert(iImagePoint->second.poseId() == invalidId);
3664
3665 iImagePoint->second.setPoseId(poseId);
3666
3667 PoseMap::iterator iPose = poseMap_.find(poseId);
3668 ocean_assert(iPose != poseMap_.end());
3669
3670 iPose->second.registerImagePoint(imagePointId);
3671
3672 if (iImagePoint->second.objectPointId() != invalidId)
3673 {
3674 const Index64 poseObjectPointId(index64(poseId, iImagePoint->second.objectPointId()));
3675
3676 ocean_assert(poseObjectPointMap_.find(poseObjectPointId) == poseObjectPointMap_.end());
3677 poseObjectPointMap_.insert(std::make_pair(poseObjectPointId, imagePointId));
3678 }
3679}
3680
3681template <bool tThreadSafe>
3682inline void Database::detachImagePointFromPose(const Index32 imagePointId)
3683{
3684 ocean_assert(imagePointId != invalidId);
3685
3686 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
3687
3688 ImagePointMap::iterator iImagePoint = imagePointMap_.find(imagePointId);
3689 ocean_assert(iImagePoint != imagePointMap_.end());
3690
3691 const Index32 poseId = iImagePoint->second.poseId();
3692 ocean_assert(poseId != invalidId);
3693
3694 iImagePoint->second.setPoseId(invalidId);
3695
3696 PoseMap::iterator iPose = poseMap_.find(poseId);
3697 ocean_assert(iPose != poseMap_.end());
3698
3699 iPose->second.unregisterImagePoint(imagePointId);
3700
3701 if (iImagePoint->second.objectPointId() != invalidId)
3702 {
3703 const Index64 poseObjectPointId(index64(poseId, iImagePoint->second.objectPointId()));
3704
3705 ocean_assert(poseObjectPointMap_.find(poseObjectPointId) != poseObjectPointMap_.end());
3706 poseObjectPointMap_.erase(poseObjectPointId);
3707 }
3708}
3709
3710template <bool tThreadSafe>
3711inline void Database::setImagePoint(const Index32 imagePointId, const Vector2& imagePoint)
3712{
3713 ocean_assert(imagePointId != invalidId);
3714
3715 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
3716
3717 const ImagePointMap::iterator iImagePoint = imagePointMap_.find(imagePointId);
3718 ocean_assert(iImagePoint != imagePointMap_.end());
3719
3720 iImagePoint->second.setPoint(imagePoint);
3721}
3722
3723template <bool tThreadSafe>
3724inline void Database::setObjectPoint(const Index32 objectPointId, const Vector3& objectPoint)
3725{
3726 ocean_assert(objectPointId != invalidId);
3727
3728 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
3729
3730 const ObjectPointMap::iterator iObjectPoint = objectPointMap_.find(objectPointId);
3731 ocean_assert(iObjectPoint != objectPointMap_.end());
3732
3733 iObjectPoint->second.setPoint(objectPoint);
3734}
3735
3736template <bool tThreadSafe>
3737inline void Database::setObjectPoints(const Index32* objectPointIds, const Vector3* objectPoints, const size_t number)
3738{
3739 ocean_assert(objectPointIds && objectPoints);
3740
3741 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
3742
3743 for (size_t n = 0; n < number; ++ n)
3744 {
3745 const ObjectPointMap::iterator iObjectPoint = objectPointMap_.find(objectPointIds[n]);
3746 ocean_assert(iObjectPoint != objectPointMap_.end());
3747
3748 iObjectPoint->second.setPoint(objectPoints[n]);
3749 }
3750}
3751
3752template <bool tThreadSafe>
3753inline void Database::setObjectPoints(const Index32* objectPointIds, const size_t number, const Vector3& referenceObjectPoint)
3754{
3755 ocean_assert(objectPointIds);
3756
3757 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
3758
3759 for (size_t n = 0; n < number; ++ n)
3760 {
3761 const ObjectPointMap::iterator iObjectPoint = objectPointMap_.find(objectPointIds[n]);
3762 ocean_assert(iObjectPoint != objectPointMap_.end());
3763
3764 iObjectPoint->second.setPoint(referenceObjectPoint);
3765 }
3766}
3767
3768template <bool tThreadSafe>
3769inline void Database::setObjectPoints(const Vector3& objectPoint)
3770{
3771 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
3772
3773 for (ObjectPointMap::iterator iObjectPoint = objectPointMap_.begin(); iObjectPoint != objectPointMap_.end(); ++iObjectPoint)
3774 {
3775 iObjectPoint->second.setPoint(objectPoint);
3776 }
3777}
3778
3779template <bool tThreadSafe>
3780inline void Database::setObjectPoint(const Index32 objectPointId, const Vector3& objectPoint, const Scalar priority)
3781{
3782 ocean_assert(objectPointId != invalidId);
3783
3784 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
3785
3786 const ObjectPointMap::iterator iObjectPoint = objectPointMap_.find(objectPointId);
3787 ocean_assert(iObjectPoint != objectPointMap_.end());
3788
3789 iObjectPoint->second.setPoint(objectPoint);
3790 iObjectPoint->second.setPriority(priority);
3791}
3792
3793template <bool tThreadSafe>
3794inline void Database::setObjectPointPriority(const Index32 objectPointId, const Scalar priority)
3795{
3796 ocean_assert(objectPointId != invalidId);
3797
3798 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
3799
3800 const ObjectPointMap::iterator iObjectPoint = objectPointMap_.find(objectPointId);
3801 ocean_assert(iObjectPoint != objectPointMap_.end());
3802
3803 iObjectPoint->second.setPriority(priority);
3804}
3805
3806template <bool tThreadSafe>
3807inline void Database::setPose(const Index32 poseId, const HomogenousMatrix4& pose)
3808{
3809 ocean_assert(poseId != invalidId);
3810
3811 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
3812
3813 const PoseMap::iterator iPose = poseMap_.find(poseId);
3814 ocean_assert(iPose != poseMap_.end());
3815
3816 iPose->second.setPose(pose);
3817}
3818
3819template <bool tThreadSafe>
3820inline void Database::setPoses(const Index32* poseIds, const HomogenousMatrix4* poses, const size_t number)
3821{
3822 ocean_assert(poseIds && poses);
3823
3824 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
3825
3826 for (size_t n = 0; n < number; ++n)
3827 {
3828 const PoseMap::iterator iPose = poseMap_.find(poseIds[n]);
3829 ocean_assert(iPose != poseMap_.end());
3830
3831 iPose->second.setPose(poses[n]);
3832 }
3833}
3834
3835template <bool tThreadSafe>
3837{
3838 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
3839
3840 for (ShiftVector<HomogenousMatrix4>::Index n = poses.firstIndex(); n < poses.endIndex(); ++n)
3841 {
3842 ocean_assert(n >= 0);
3843 const unsigned int poseId = (unsigned int)n;
3844
3845 const PoseMap::iterator iPose = poseMap_.find(poseId);
3846 ocean_assert(iPose != poseMap_.end());
3847
3848 iPose->second.setPose(poses[n]);
3849 }
3850}
3851
3852template <bool tThreadSafe>
3854{
3855 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
3856
3857 for (PoseMap::iterator iPose = poseMap_.begin(); iPose != poseMap_.end(); ++iPose)
3858 {
3859 iPose->second.setPose(pose);
3860 }
3861}
3862
3863template <bool tThreadSafe>
3865{
3866 ocean_assert(poseId != invalidId);
3867
3868 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
3869
3870 const PoseMap::const_iterator iPose = poseMap_.find(poseId);
3871 ocean_assert(iPose != poseMap_.end());
3872
3873 return iPose->second.imagePointIds();
3874}
3875
3876template <bool tThreadSafe>
3877inline Indices32 Database::imagePointIds(const Index32 poseId, Indices32& objectPointIds) const
3878{
3879 ocean_assert(poseId != invalidId);
3880 ocean_assert(!objectPointIds.empty());
3881
3882 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
3883
3884 Indices32 ids;
3885 ids.reserve(objectPointIds.size());
3886
3887 Indices32 validObjectPointIds;
3888 validObjectPointIds.reserve(objectPointIds.size());
3889
3890 for (const Index32 objectPointId : objectPointIds)
3891 {
3892 const Index64To32Map::const_iterator iPoseObjectPoint = poseObjectPointMap_.find(index64(poseId, objectPointId));
3893
3894 if (iPoseObjectPoint != poseObjectPointMap_.end())
3895 {
3896 ocean_assert(imagePointMap_.find(iPoseObjectPoint->second) != imagePointMap_.end());
3897
3898 ids.push_back(iPoseObjectPoint->second);
3899 validObjectPointIds.push_back(objectPointId);
3900 }
3901 }
3902
3903 objectPointIds = std::move(validObjectPointIds);
3904 return ids;
3905}
3906
3907template <bool tThreadSafe>
3909{
3910 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
3911
3912 Indices32 result;
3913 result.reserve(imagePointMap_.size());
3914
3915 if (imagePoints != nullptr)
3916 {
3917 for (ImagePointMap::const_iterator iImagePoint = imagePointMap_.cbegin(); iImagePoint != imagePointMap_.cend(); ++iImagePoint)
3918 {
3919 result.emplace_back(iImagePoint->first);
3920
3921 imagePoints->emplace_back(iImagePoint->second.point());
3922 }
3923 }
3924 else
3925 {
3926 for (ImagePointMap::const_iterator iImagePoint = imagePointMap_.cbegin(); iImagePoint != imagePointMap_.cend(); ++iImagePoint)
3927 {
3928 result.emplace_back(iImagePoint->first);
3929 }
3930 }
3931
3932 return result;
3933}
3934
3935template <bool tThreadSafe>
3936Indices32 Database::objectPointIds(Vectors3* objectPoints, Scalars* priorities) const
3937{
3938 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
3939
3940 Indices32 result;
3941 result.reserve(objectPointMap_.size());
3942
3943 if (objectPoints != nullptr)
3944 {
3945 objectPoints->clear();
3946 objectPoints->reserve(objectPointMap_.size());
3947
3948 for (ObjectPointMap::const_iterator iObjectPoint = objectPointMap_.cbegin(); iObjectPoint != objectPointMap_.cend(); ++iObjectPoint)
3949 {
3950 result.emplace_back(iObjectPoint->first);
3951
3952 objectPoints->emplace_back(iObjectPoint->second.point());
3953 }
3954 }
3955 else
3956 {
3957 for (ObjectPointMap::const_iterator iObjectPoint = objectPointMap_.cbegin(); iObjectPoint != objectPointMap_.cend(); ++iObjectPoint)
3958 {
3959 result.emplace_back(iObjectPoint->first);
3960 }
3961 }
3962
3963 if (priorities != nullptr)
3964 {
3965 priorities->clear();
3966 priorities->reserve(objectPointMap_.size());
3967
3968 for (ObjectPointMap::const_iterator iObjectPoint = objectPointMap_.cbegin(); iObjectPoint != objectPointMap_.cend(); ++iObjectPoint)
3969 {
3970 priorities->emplace_back(iObjectPoint->second.priority());
3971 }
3972 }
3973
3974 return result;
3975}
3976
3977template <bool tThreadSafe>
3978Indices32 Database::objectPointIds(const IndexSet32& outlierObjectPointIds) const
3979{
3980 if (outlierObjectPointIds.empty())
3981 {
3982 return objectPointIds<tThreadSafe>();
3983 }
3984
3985 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
3986
3987 Indices32 result;
3988 result.reserve(objectPointMap_.size());
3989
3990 for (ObjectPointMap::const_iterator iObjectPoint = objectPointMap_.cbegin(); iObjectPoint != objectPointMap_.cend(); ++iObjectPoint)
3991 {
3992 if (outlierObjectPointIds.find(iObjectPoint->first) == outlierObjectPointIds.end())
3993 {
3994 result.push_back(iObjectPoint->first);
3995 }
3996 }
3997
3998 return result;
3999}
4000
4001template <bool tThreadSafe>
4003{
4004 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
4005
4006 Indices32 result;
4007 result.reserve(poseMap_.size());
4008
4009 if (world_T_cameras != nullptr)
4010 {
4011 world_T_cameras->clear();
4012 world_T_cameras->reserve(poseMap_.size());
4013
4014 for (PoseMap::const_iterator iPose = poseMap_.cbegin(); iPose != poseMap_.cend(); ++iPose)
4015 {
4016 result.emplace_back(iPose->first);
4017
4018 world_T_cameras->emplace_back(iPose->second.pose());
4019 }
4020 }
4021 else
4022 {
4023 for (PoseMap::const_iterator iPose = poseMap_.cbegin(); iPose != poseMap_.cend(); ++iPose)
4024 {
4025 result.emplace_back(iPose->first);
4026 }
4027 }
4028
4029 return result;
4030}
4031
4032template <bool tThreadSafe>
4033Vectors2 Database::imagePoints(const Index32 poseId, Indices32* imagePointIds) const
4034{
4035 ocean_assert(poseId != invalidId);
4036 ocean_assert(imagePointIds == nullptr || imagePointIds->empty());
4037
4038 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
4039
4040 const PoseMap::const_iterator iPose = poseMap_.find(poseId);
4041 ocean_assert(iPose != poseMap_.end());
4042
4043 Vectors2 result;
4044 result.reserve(iPose->second.imagePointIds().size());
4045
4046 if (imagePointIds != nullptr)
4047 {
4048 imagePointIds->reserve(iPose->second.imagePointIds().size());
4049 }
4050
4051 for (const Index32 imagePointId : iPose->second.imagePointIds())
4052 {
4053 ocean_assert(imagePointId != invalidId);
4054
4055 const ImagePointMap::const_iterator iImagePoint = imagePointMap_.find(imagePointId);
4056 ocean_assert(iImagePoint != imagePointMap_.end());
4057
4058 result.push_back(iImagePoint->second.point());
4059
4060 if (imagePointIds != nullptr)
4061 {
4062 imagePointIds->push_back(imagePointId);
4063 }
4064 }
4065
4066 return result;
4067}
4068
4069template <bool tThreadSafe, bool tMatchPosition>
4070Indices32 Database::objectPointIds(const Vector3& referencePosition, Vectors3* objectPoints, const Scalar minimalPriority) const
4071{
4072 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
4073
4075
4076 if (objectPoints != nullptr)
4077 {
4078 ocean_assert(objectPoints->empty());
4079 objectPoints->clear();
4080
4081 for (ObjectPointMap::const_iterator iObjectPoint = objectPointMap_.cbegin(); iObjectPoint != objectPointMap_.cend(); ++iObjectPoint)
4082 {
4083 if (iObjectPoint->second.priority() >= minimalPriority && ((tMatchPosition && iObjectPoint->second.point() == referencePosition) || (!tMatchPosition && iObjectPoint->second.point() != referencePosition)))
4084 {
4085 objectPointIds.push_back(iObjectPoint->first);
4086 objectPoints->push_back(iObjectPoint->second.point());
4087 }
4088 }
4089 }
4090 else
4091 {
4092 for (ObjectPointMap::const_iterator iObjectPoint = objectPointMap_.cbegin(); iObjectPoint != objectPointMap_.cend(); ++iObjectPoint)
4093 {
4094 if (iObjectPoint->second.priority() >= minimalPriority && ((tMatchPosition && iObjectPoint->second.point() == referencePosition) || (!tMatchPosition && iObjectPoint->second.point() != referencePosition)))
4095 {
4096 objectPointIds.push_back(iObjectPoint->first);
4097 }
4098 }
4099 }
4100
4101 return objectPointIds;
4102}
4103
4104template <bool tThreadSafe, bool tMatchPosition>
4105Indices32 Database::objectPointIds(const IndexSet32& outlierObjectPointIds, const Vector3& referencePosition, Vectors3* objectPoints, const Scalar minimalPriority) const
4106{
4107 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
4108
4110
4111 if (objectPoints != nullptr)
4112 {
4113 ocean_assert(objectPoints->empty());
4114 objectPoints->clear();
4115
4116 for (ObjectPointMap::const_iterator iObjectPoint = objectPointMap_.cbegin(); iObjectPoint != objectPointMap_.cend(); ++iObjectPoint)
4117 {
4118 if (iObjectPoint->second.priority() >= minimalPriority && ((tMatchPosition && iObjectPoint->second.point() == referencePosition) || (!tMatchPosition && iObjectPoint->second.point() != referencePosition))
4119 && outlierObjectPointIds.find(iObjectPoint->first) == outlierObjectPointIds.end())
4120 {
4121 objectPointIds.push_back(iObjectPoint->first);
4122 objectPoints->push_back(iObjectPoint->second.point());
4123 }
4124 }
4125 }
4126 else
4127 {
4128 for (ObjectPointMap::const_iterator iObjectPoint = objectPointMap_.cbegin(); iObjectPoint != objectPointMap_.cend(); ++iObjectPoint)
4129 {
4130 if (iObjectPoint->second.priority() >= minimalPriority && ((tMatchPosition && iObjectPoint->second.point() == referencePosition) || (!tMatchPosition && iObjectPoint->second.point() != referencePosition))
4131 && outlierObjectPointIds.find(iObjectPoint->first) == outlierObjectPointIds.end())
4132 {
4133 objectPointIds.push_back(iObjectPoint->first);
4134 }
4135 }
4136 }
4137
4138 return objectPointIds;
4139}
4140
4141template <bool tThreadSafe, bool tMatchPosition>
4142inline IndexPairs32 Database::objectPointIdsWithNumberOfObservations(const Vector3& referencePosition, const Scalar minimalPriority, Worker* worker) const
4143{
4144 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
4145
4147 objectPointIds.reserve(objectPointMap_.size());
4148
4149 for (ObjectPointMap::const_iterator iObjectPoint = objectPointMap_.cbegin(); iObjectPoint != objectPointMap_.cend(); ++iObjectPoint)
4150 {
4151 objectPointIds.push_back(iObjectPoint->first);
4152 }
4153
4154 IndexPairs32 result;
4155 result.reserve(objectPointIds.size());
4156
4157 if (worker != nullptr)
4158 {
4159 Lock lock;
4160 worker->executeFunction(Worker::Function::create(*this, &Database::objectPointIdsWithNumberOfObservationsSubset<tMatchPosition>, (const Index32*)objectPointIds.data(), &referencePosition, minimalPriority, &result, &lock, 0u, 0u), 0u, (unsigned int)objectPointIds.size());
4161 }
4162 else
4163 {
4164 objectPointIdsWithNumberOfObservationsSubset<tMatchPosition>((const Index32*)objectPointIds.data(), &referencePosition, minimalPriority, &result, nullptr, 0u, (unsigned int)objectPointIds.size());
4165 }
4166
4167 return result;
4168}
4169
4170template <bool tThreadSafe>
4171Indices32 Database::objectPointIds(const Index32 poseId, Vectors3* objectPoints) const
4172{
4173 ocean_assert(poseId != invalidId);
4174 ocean_assert(objectPoints == nullptr || objectPoints->empty());
4175
4176 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
4177
4178 const PoseMap::const_iterator iPose = poseMap_.find(poseId);
4179 ocean_assert(iPose != poseMap_.end());
4180
4181 const IndexSet32& imagePointIds = iPose->second.imagePointIds();
4182
4183 Indices32 result;
4184 result.reserve(imagePointIds.size());
4185
4186 if (objectPoints != nullptr)
4187 {
4188 objectPoints->reserve(imagePointIds.size());
4189 }
4190
4191 for (const Index32 imagePointId : imagePointIds)
4192 {
4193 ocean_assert(imagePointId != invalidId);
4194
4195 const ImagePointMap::const_iterator iImagePoint = imagePointMap_.find(imagePointId);
4196 ocean_assert(iImagePoint != imagePointMap_.end());
4197
4198 const Index32 objectPointId = iImagePoint->second.objectPointId();
4199
4200 if (objectPointId != invalidId)
4201 {
4202 result.push_back(objectPointId);
4203
4204 if (objectPoints != nullptr)
4205 {
4206 const ObjectPointMap::const_iterator iObjectPoint = objectPointMap_.find(objectPointId);
4207 ocean_assert(iObjectPoint != objectPointMap_.cend());
4208
4209 objectPoints->push_back(iObjectPoint->second.point());
4210 }
4211 }
4212 }
4213
4214 ocean_assert(IndexSet32(result.begin(), result.end()).size() == result.size());
4215
4216 return result;
4217}
4218
4219template <bool tThreadSafe, bool tMatchPosition>
4220Indices32 Database::objectPointIds(const Index32 poseId, const Vector3& referencePosition, const Scalar minimalPriority, Vectors3* objectPoints) const
4221{
4222 ocean_assert(poseId != invalidId);
4223 ocean_assert(objectPoints == nullptr || objectPoints->empty());
4224
4225 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
4226
4227 const PoseMap::const_iterator iPose = poseMap_.find(poseId);
4228 ocean_assert(iPose != poseMap_.end());
4229
4230 const IndexSet32& imagePointIds = iPose->second.imagePointIds();
4231
4232 Indices32 result;
4233 result.reserve(imagePointIds.size());
4234
4235 if (objectPoints != nullptr)
4236 {
4237 objectPoints->reserve(imagePointIds.size());
4238 }
4239
4240 for (const Index32 imagePointId : imagePointIds)
4241 {
4242 ocean_assert(imagePointId != invalidId);
4243
4244 const ImagePointMap::const_iterator iImagePoint = imagePointMap_.find(imagePointId);
4245 ocean_assert(iImagePoint != imagePointMap_.end());
4246
4247 const Index32 objectPointId = iImagePoint->second.objectPointId();
4248
4249 if (objectPointId != invalidId)
4250 {
4251 const ObjectPointMap::const_iterator iObjectPoint = objectPointMap_.find(objectPointId);
4252 ocean_assert(iObjectPoint != objectPointMap_.end());
4253
4254 const Vector3& objectPoint = iObjectPoint->second.point();
4255
4256 if (iObjectPoint->second.priority() >= minimalPriority && ((tMatchPosition && objectPoint == referencePosition) || (!tMatchPosition && objectPoint != referencePosition)))
4257 {
4258 result.push_back(objectPointId);
4259
4260 if (objectPoints != nullptr)
4261 {
4262 objectPoints->push_back(objectPoint);
4263 }
4264 }
4265 }
4266 }
4267
4268 ocean_assert(IndexSet32(result.begin(), result.end()).size() == result.size());
4269
4270 return result;
4271}
4272
4273template <bool tThreadSafe>
4274Indices32 Database::objectPointIds(const Indices32 poseIds, Vectors3* objectPoints) const
4275{
4276 ocean_assert(!poseIds.empty());
4277 ocean_assert(objectPoints == nullptr || objectPoints->empty());
4278
4279 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
4280
4282
4283 for (const Index32 poseId : poseIds)
4284 {
4285 const PoseMap::const_iterator iPose = poseMap_.find(poseId);
4286 ocean_assert(iPose != poseMap_.end());
4287
4288 const IndexSet32& imagePointIds = iPose->second.imagePointIds();
4289
4290 for (IndexSet32::const_iterator iId = imagePointIds.cbegin(); iId != imagePointIds.cend(); ++iId)
4291 {
4292 ocean_assert(*iId != invalidId);
4293
4294 const ImagePointMap::const_iterator iImagePoint = imagePointMap_.find(*iId);
4295 ocean_assert(iImagePoint != imagePointMap_.end());
4296
4297 const Index32 objectPointId = iImagePoint->second.objectPointId();
4298
4299 if (objectPointId != invalidId)
4300 {
4301 objectPointIds.insert(objectPointId);
4302 }
4303 }
4304 }
4305
4306 Indices32 result;
4307
4308 if (objectPoints != nullptr)
4309 {
4310 result.reserve(objectPointIds.size());
4311 objectPoints->reserve(objectPointIds.size());
4312
4313 for (IndexSet32::const_iterator iId = objectPointIds.cbegin(); iId != objectPointIds.cend(); ++iId)
4314 {
4315 ocean_assert(objectPointMap_.find(*iId) != objectPointMap_.end());
4316
4317 result.push_back(*iId);
4318 objectPoints->push_back(objectPointMap_.find(*iId)->second.point());
4319 }
4320 }
4321 else
4322 {
4323 result = Indices32(objectPointIds.begin(), objectPointIds.end());
4324 }
4325
4326 return result;
4327}
4328
4329template <bool tThreadSafe, bool tMatchPosition, bool tVisibleInAllPoses>
4330Indices32 Database::objectPointIds(const Index32 lowerPoseId, const Index32 upperPoseId, const Vector3& referencePosition, const Scalar minimalPriority, Vectors3* objectPoints) const
4331{
4332 ocean_assert(lowerPoseId <= upperPoseId);
4333 ocean_assert(objectPoints == nullptr || objectPoints->empty());
4334
4335 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
4336
4337 if constexpr (tVisibleInAllPoses)
4338 {
4339 Indices32 result;
4340
4341 const PoseMap::const_iterator iPose = poseMap_.find(lowerPoseId);
4342
4343 // if the lower pose does not exist the object points cannot be visible in all poses anymore
4344 if (iPose == poseMap_.end())
4345 {
4346 return Indices32();
4347 }
4348
4349 const IndexSet32& imagePointIds = iPose->second.imagePointIds();
4350
4351 for (const Index32 imagePointId : imagePointIds)
4352 {
4353 ocean_assert(imagePointId != invalidId);
4354
4355 const ImagePointMap::const_iterator iImagePoint = imagePointMap_.find(imagePointId);
4356 ocean_assert(iImagePoint != imagePointMap_.end());
4357
4358 const Index32 objectPointId = iImagePoint->second.objectPointId();
4359
4360 if (objectPointId != invalidId)
4361 {
4362 const ObjectPointMap::const_iterator iObjectPoint = objectPointMap_.find(objectPointId);
4363 ocean_assert(iObjectPoint != objectPointMap_.end());
4364
4365 if (iObjectPoint->second.priority() >= minimalPriority && ((tMatchPosition && iObjectPoint->second.point() == referencePosition) || (!tMatchPosition && iObjectPoint->second.point() != referencePosition)))
4366 {
4367 bool visibleInAllPoses = true;
4368 for (unsigned int n = lowerPoseId + 1u; visibleInAllPoses && n <= upperPoseId; ++n)
4369 {
4370 visibleInAllPoses = poseObjectPointMap_.find(index64(n, objectPointId)) != poseObjectPointMap_.end();
4371 }
4372
4373 if (visibleInAllPoses)
4374 {
4375 result.push_back(objectPointId);
4376
4377 if (objectPoints != nullptr)
4378 {
4379 objectPoints->push_back(iObjectPoint->second.point());
4380 }
4381 }
4382 }
4383 }
4384 }
4385
4386 ocean_assert(IndexSet32(result.begin(), result.end()).size() == result.size());
4387 ocean_assert(objectPoints == nullptr || objectPoints->size() == result.size());
4388
4389 return result;
4390 }
4391 else
4392 {
4393 Indices32 result;
4395
4396 for (unsigned int n = lowerPoseId; n <= upperPoseId; ++n)
4397 {
4398 const PoseMap::const_iterator iPose = poseMap_.find(n);
4399
4400 if (iPose != poseMap_.end())
4401 {
4402 const IndexSet32& imagePointIds = iPose->second.imagePointIds();
4403
4404 for (const Index32 imagePointId : imagePointIds)
4405 {
4406 ocean_assert(imagePointId != invalidId);
4407
4408 const ImagePointMap::const_iterator iImagePoint = imagePointMap_.find(imagePointId);
4409 ocean_assert(iImagePoint != imagePointMap_.end());
4410
4411 const Index32 objectPointId = iImagePoint->second.objectPointId();
4412
4413 if (objectPointId != invalidId && objectPointIds.find(objectPointId) == objectPointIds.end())
4414 {
4415 objectPointIds.insert(objectPointId);
4416
4417 const ObjectPointMap::const_iterator iObjectPoint = objectPointMap_.find(objectPointId);
4418 ocean_assert(iObjectPoint != objectPointMap_.end());
4419
4420 if (iObjectPoint->second.priority() >= minimalPriority && ((tMatchPosition && iObjectPoint->second.point() == referencePosition) || (!tMatchPosition && iObjectPoint->second.point() != referencePosition)))
4421 {
4422 result.push_back(objectPointId);
4423
4424 if (objectPoints != nullptr)
4425 {
4426 objectPoints->push_back(iObjectPoint->second.point());
4427 }
4428 }
4429 }
4430 }
4431 }
4432 }
4433
4434 ocean_assert(IndexSet32(result.begin(), result.end()).size() == result.size());
4435 ocean_assert(objectPoints == nullptr || objectPoints->size() == result.size());
4436
4437 return result;
4438 }
4439}
4440
4441template <bool tThreadSafe, bool tMatchPosition, bool tVisibleInAllPoses>
4442Indices32 Database::objectPointIds(const Indices32& poseIds, const Vector3& referencePosition, const Scalar minimalPriority, Vectors3* objectPoints) const
4443{
4444 ocean_assert(Indices32(poseIds.begin(), poseIds.end()).size() == poseIds.size());
4445 ocean_assert(objectPoints == nullptr || objectPoints->empty());
4446
4447 if (poseIds.empty())
4448 {
4449 return Indices32();
4450 }
4451
4452 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
4453
4454 if constexpr (tVisibleInAllPoses)
4455 {
4456 Indices32 result;
4457
4458 const PoseMap::const_iterator iPose = poseMap_.find(poseIds.front());
4459
4460 // if the first pose does not exist the object points cannot be visible in all poses anymore
4461 if (iPose == poseMap_.end())
4462 {
4463 return Indices32();
4464 }
4465
4466 const IndexSet32& imagePointIds = iPose->second.imagePointIds();
4467
4468 for (const Index32 imagePointId : imagePointIds)
4469 {
4470 ocean_assert(imagePointId != invalidId);
4471
4472 const ImagePointMap::const_iterator iImagePoint = imagePointMap_.find(imagePointId);
4473 ocean_assert(iImagePoint != imagePointMap_.end());
4474
4475 const Index32 objectPointId = iImagePoint->second.objectPointId();
4476
4477 if (objectPointId != invalidId)
4478 {
4479 const ObjectPointMap::const_iterator iObjectPoint = objectPointMap_.find(objectPointId);
4480 ocean_assert(iObjectPoint != objectPointMap_.end());
4481
4482 if (iObjectPoint->second.priority() >= minimalPriority && ((tMatchPosition && iObjectPoint->second.point() == referencePosition) || (!tMatchPosition && iObjectPoint->second.point() != referencePosition)))
4483 {
4484 bool visibleInAllPoses = true;
4485 for (size_t n = 1; visibleInAllPoses && n < poseIds.size(); ++n)
4486 {
4487 visibleInAllPoses = poseObjectPointMap_.find(index64(poseIds[n], objectPointId)) != poseObjectPointMap_.end();
4488 }
4489
4490 if (visibleInAllPoses)
4491 {
4492 result.push_back(objectPointId);
4493
4494 if (objectPoints != nullptr)
4495 {
4496 objectPoints->push_back(iObjectPoint->second.point());
4497 }
4498 }
4499 }
4500 }
4501 }
4502
4503 ocean_assert(IndexSet32(result.begin(), result.end()).size() == result.size());
4504 ocean_assert(objectPoints == nullptr || objectPoints->size() == result.size());
4505
4506 return result;
4507 }
4508 else
4509 {
4510 Indices32 result;
4512
4513 for (size_t n = 0; n < poseIds.size(); ++n)
4514 {
4515 const PoseMap::const_iterator iPose = poseMap_.find(poseIds[n]);
4516
4517 if (iPose != poseMap_.end())
4518 {
4519 const IndexSet32& imagePointIds = iPose->second.imagePointIds();
4520
4521 for (const Index32 imagePointId : imagePointIds)
4522 {
4523 ocean_assert(imagePointId != invalidId);
4524
4525 const ImagePointMap::const_iterator iImagePoint = imagePointMap_.find(imagePointId);
4526 ocean_assert(iImagePoint != imagePointMap_.end());
4527
4528 const Index32 objectPointId = iImagePoint->second.objectPointId();
4529
4530 if (objectPointId != invalidId && objectPointIds.find(objectPointId) == objectPointIds.end())
4531 {
4532 objectPointIds.insert(objectPointId);
4533
4534 const ObjectPointMap::const_iterator iObjectPoint = objectPointMap_.find(objectPointId);
4535 ocean_assert(iObjectPoint != objectPointMap_.end());
4536
4537 if (iObjectPoint->second.priority() >= minimalPriority && ((tMatchPosition && iObjectPoint->second.point() == referencePosition) || (!tMatchPosition && iObjectPoint->second.point() != referencePosition)))
4538 {
4539 result.push_back(objectPointId);
4540
4541 if (objectPoints != nullptr)
4542 {
4543 objectPoints->push_back(iObjectPoint->second.point());
4544 }
4545 }
4546 }
4547 }
4548 }
4549 }
4550
4551 ocean_assert(IndexSet32(result.begin(), result.end()).size() == result.size());
4552 ocean_assert(objectPoints == nullptr || objectPoints->size() == result.size());
4553
4554 return result;
4555 }
4556}
4557
4558template <bool tThreadSafe>
4560{
4561 ocean_assert(poseId != invalidId);
4562
4563 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
4564
4565 const PoseMap::const_iterator iPose = poseMap_.find(poseId);
4566
4567 ocean_assert(iPose != poseMap_.end());
4568 if (iPose == poseMap_.end())
4569 {
4570 return Vectors2();
4571 }
4572
4573 const IndexSet32& imagePointIds = iPose->second.imagePointIds();
4574
4575 Vectors2 result;
4576 result.reserve(imagePointIds.size());
4577
4578 ocean_assert(objectPointIds.empty());
4579 objectPointIds.clear();
4580 objectPointIds.reserve(imagePointIds.size());
4581
4582 for (const Index32 imagePointId : imagePointIds)
4583 {
4584 ocean_assert(imagePointId != invalidId);
4585
4586 const ImagePointMap::const_iterator iImagePoint = imagePointMap_.find(imagePointId);
4587 ocean_assert(iImagePoint != imagePointMap_.end());
4588
4589 if (iImagePoint->second.objectPointId() != invalidId)
4590 {
4591 result.push_back(iImagePoint->second.point());
4592 objectPointIds.push_back(iImagePoint->second.objectPointId());
4593 }
4594 }
4595
4596 ocean_assert(result.size() == objectPointIds.size());
4597
4598 return result;
4599}
4600
4601template <bool tThreadSafe>
4602Vectors2 Database::imagePointsFromObjectPoints(const Index32 poseId, Indices32& objectPointIds, Indices32* imagePointIds) const
4603{
4604 ocean_assert(poseId != invalidId);
4605 ocean_assert(!objectPointIds.empty());
4606 ocean_assert(imagePointIds == nullptr || imagePointIds->empty());
4607
4608 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
4609
4610 Vectors2 points;
4611 points.reserve(objectPointIds.size());
4612
4613 Indices32 validObjectPointIds;
4614 validObjectPointIds.reserve(objectPointIds.size());
4615
4616 for (const Index32 objectPointId : objectPointIds)
4617 {
4618 const Index64To32Map::const_iterator iPoseObjectPoint = poseObjectPointMap_.find(index64(poseId, objectPointId));
4619
4620 if (iPoseObjectPoint != poseObjectPointMap_.end())
4621 {
4622 ocean_assert(iPoseObjectPoint->second != invalidId);
4623 const ImagePointMap::const_iterator iImagePoint = imagePointMap_.find(iPoseObjectPoint->second);
4624 ocean_assert(iImagePoint != imagePointMap_.end());
4625
4626 points.push_back(iImagePoint->second.point());
4627 validObjectPointIds.push_back(objectPointId);
4628
4629 if (imagePointIds != nullptr)
4630 {
4631 imagePointIds->push_back(iPoseObjectPoint->second);
4632 }
4633 }
4634 }
4635
4636 objectPointIds = std::move(validObjectPointIds);
4637 return points;
4638}
4639
4640template <bool tThreadSafe>
4641Vectors2 Database::imagePointsFromObjectPoints(const Index32 poseId, const Indices32& objectPointIds, Indices32& validIndices, Indices32* imagePointIds) const
4642{
4643 ocean_assert(poseId != invalidId);
4644 ocean_assert(!objectPointIds.empty());
4645 ocean_assert(imagePointIds == nullptr || imagePointIds->empty());
4646
4647 return imagePointsFromObjectPoints<tThreadSafe>(poseId, objectPointIds.data(), objectPointIds.size(), validIndices, imagePointIds);
4648}
4649
4650template <bool tThreadSafe>
4651Vectors2 Database::imagePointsFromObjectPoints(const Index32 poseId, const Index32* objectPointIds, const size_t numberObjectPointIds, Indices32& validIndices, Indices32* imagePointIds) const
4652{
4653 ocean_assert(poseId != invalidId);
4654 ocean_assert(objectPointIds && numberObjectPointIds != 0);
4655 ocean_assert(imagePointIds == nullptr || imagePointIds->empty());
4656
4657 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
4658
4659 Vectors2 points;
4660 points.reserve(numberObjectPointIds);
4661
4662 for (size_t n = 0; n < numberObjectPointIds; ++n)
4663 {
4664 const Index32 objectPointId = objectPointIds[n];
4665
4666 const Index64To32Map::const_iterator iPoseObjectPoint = poseObjectPointMap_.find(index64(poseId, objectPointId));
4667
4668 if (iPoseObjectPoint != poseObjectPointMap_.end())
4669 {
4670 ocean_assert(iPoseObjectPoint->second != invalidId);
4671 const ImagePointMap::const_iterator iImagePoint = imagePointMap_.find(iPoseObjectPoint->second);
4672 ocean_assert(iImagePoint != imagePointMap_.end());
4673
4674 points.push_back(iImagePoint->second.point());
4675 validIndices.push_back((unsigned int)n);
4676
4677 if (imagePointIds != nullptr)
4678 {
4679 imagePointIds->push_back(iPoseObjectPoint->second);
4680 }
4681 }
4682 }
4683
4684 return points;
4685}
4686
4687template <bool tThreadSafe>
4689{
4690 ocean_assert(!poseIds.empty());
4691 ocean_assert(IndexSet32(poseIds.begin(), poseIds.end()).size() == poseIds.size());
4692
4693 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
4694
4695 ImagePointsMap intermediate;
4696
4697 for (const Index32 poseId : poseIds)
4698 {
4699 ocean_assert(poseId != invalidId);
4700 ocean_assert(poseMap_.find(poseId) != poseMap_.end());
4701
4702 const PoseData& poseData = poseMap_.find(poseId)->second;
4703
4704 for (const Index32 imagePointId : poseData.imagePointIds())
4705 {
4706 const ImagePointMap::const_iterator iImagePoint = imagePointMap_.find(imagePointId);
4707 ocean_assert(iImagePoint != imagePointMap_.end());
4708
4709 if (iImagePoint->second.objectPointId() != invalidId)
4710 {
4711 intermediate[iImagePoint->second.objectPointId()].push_back(iImagePoint->second.point());
4712 }
4713 }
4714 }
4715
4716 ImagePointGroups result(poseIds.size());
4717
4718 for (ImagePointsMap::iterator iImagePoints = intermediate.begin(); iImagePoints != intermediate.end(); ++iImagePoints)
4719 {
4720 if (iImagePoints->second.size() == poseIds.size())
4721 {
4722 objectPointIds.push_back(iImagePoints->first);
4723
4724 for (size_t n = 0; n < poseIds.size(); ++n)
4725 {
4726 result[n].push_back(iImagePoints->second[n]);
4727 }
4728 }
4729 }
4730
4731 return result;
4732}
4733
4734template <bool tThreadSafe>
4735Database::IdIdPointPairsMap Database::imagePoints(const Index32 poseId, const bool previous, const size_t minimalObservations, const size_t maximalObservations) const
4736{
4737 ocean_assert(poseId != invalidId);
4738 ocean_assert(maximalObservations == 0 || minimalObservations <= maximalObservations);
4739
4740 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
4741
4742 IdIdPointPairsMap result;
4743
4744 const PoseMap::const_iterator iPose = poseMap_.find(poseId);
4745 ocean_assert(iPose != poseMap_.end());
4746
4747 const PoseData& poseData = iPose->second;
4748
4749 for (const Index32 imagePointId : poseData.imagePointIds())
4750 {
4751 const ImagePointMap::const_iterator iImagePoint = imagePointMap_.find(imagePointId);
4752 ocean_assert(iImagePoint != imagePointMap_.end());
4753
4754 const Index32 objectPointId = iImagePoint->second.objectPointId();
4755
4756 if (objectPointId != invalidId)
4757 {
4758 IdPointPairs imagePointPairs;
4759 imagePointPairs.emplace_back(imagePointId, iImagePoint->second.point());
4760
4761 // now find the consecutive image points
4762 Index32 pId = poseId;
4763
4764 while (((previous && pId-- != 0u) || (!previous && ++pId < poses_)) && (maximalObservations == 0 || imagePointPairs.size() < maximalObservations))
4765 {
4766 const Index64To32Map::const_iterator iPoseObjectPoint = poseObjectPointMap_.find(index64(pId, objectPointId));
4767
4768 if (iPoseObjectPoint == poseObjectPointMap_.end())
4769 {
4770 break;
4771 }
4772
4773 const ImagePointMap::const_iterator iOtherImagePoint = imagePointMap_.find(iPoseObjectPoint->second);
4774 ocean_assert(iOtherImagePoint != imagePointMap_.end());
4775
4776 imagePointPairs.emplace_back(iPoseObjectPoint->second, iOtherImagePoint->second.point());
4777 }
4778
4779 if (minimalObservations == 0 || imagePointPairs.size() >= minimalObservations)
4780 {
4781 result[objectPointId] = imagePointPairs;
4782 }
4783 }
4784 }
4785
4786 return result;
4787}
4788
4789template <bool tThreadSafe>
4790void Database::imagePoints(const Index32 pose0, const Index32 pose1, Vectors2& points0, Vectors2& points1, Indices32* objectPointIds) const
4791{
4792 ocean_assert(pose0 != invalidId && pose1 != invalidId);
4793 ocean_assert(pose0 != pose1);
4794
4795 ocean_assert(points0.size() == points1.size());
4796
4797 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
4798
4799 const PoseMap::const_iterator iPose0 = poseMap_.find(pose0);
4800 ocean_assert(iPose0 != poseMap_.end());
4801
4802 const PoseData& poseData0 = iPose0->second;
4803
4804 for (const Index32 imagePointId : poseData0.imagePointIds())
4805 {
4806 const ImagePointMap::const_iterator iImagePoint0 = imagePointMap_.find(imagePointId);
4807 ocean_assert(iImagePoint0 != imagePointMap_.end());
4808
4809 ocean_assert(iImagePoint0->second.poseId() == pose0);
4810 if (iImagePoint0->second.objectPointId() != invalidId)
4811 {
4812 const Index64To32Map::const_iterator iPoseObjectPoint = poseObjectPointMap_.find(index64(pose1, iImagePoint0->second.objectPointId()));
4813
4814 if (iPoseObjectPoint != poseObjectPointMap_.end())
4815 {
4816 const ImagePointMap::const_iterator iImagePoint1 = imagePointMap_.find(iPoseObjectPoint->second);
4817 ocean_assert(iImagePoint1 != imagePointMap_.end());
4818
4819 points0.push_back(iImagePoint0->second.point());
4820 points1.push_back(iImagePoint1->second.point());
4821
4822 if (objectPointIds != nullptr)
4823 {
4824 objectPointIds->push_back(iImagePoint0->second.objectPointId());
4825 }
4826 }
4827 }
4828 }
4829}
4830
4831template <bool tThreadSafe, bool tMatchPosition>
4832void Database::imagePointsObjectPoints(const Index32 poseId, Vectors2& imagePoints, Vectors3& objectPoints, const Vector3& referencePosition, const size_t minimalObservations, Indices32* imagePointIds, Indices32* objectPointIds) const
4833{
4834 ocean_assert(poseId != invalidId);
4835 ocean_assert(imagePoints.empty() && objectPoints.empty());
4836
4837 ocean_assert(imagePointIds == nullptr || imagePointIds->empty());
4838 ocean_assert(objectPointIds == nullptr || objectPointIds->empty());
4839
4840 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
4841
4842 const PoseMap::const_iterator iPose = poseMap_.find(poseId);
4843 ocean_assert(iPose != poseMap_.end());
4844
4845 const PoseData& poseData = iPose->second;
4846
4847 imagePoints.reserve(poseData.imagePointIds().size());
4848 objectPoints.reserve(poseData.imagePointIds().size());
4849
4850 if (imagePointIds != nullptr)
4851 {
4852 imagePointIds->reserve(poseData.imagePointIds().size());
4853 }
4854
4855 if (objectPointIds != nullptr)
4856 {
4857 objectPointIds->reserve(poseData.imagePointIds().size());
4858 }
4859
4860 for (const Index32& imagePointId : poseData.imagePointIds())
4861 {
4862 const ImagePointMap::const_iterator iImagePoint = imagePointMap_.find(imagePointId);
4863 ocean_assert(iImagePoint != imagePointMap_.end());
4864
4865 if (iImagePoint->second.objectPointId() != invalidId)
4866 {
4867 const ObjectPointMap::const_iterator iObjectPoint = objectPointMap_.find(iImagePoint->second.objectPointId());
4868 ocean_assert(iObjectPoint != objectPointMap_.end());
4869
4870 if (((tMatchPosition && iObjectPoint->second.point() == referencePosition) || (!tMatchPosition && iObjectPoint->second.point() != referencePosition)) && (minimalObservations == 0 || iObjectPoint->second.imagePointIds().size() >= minimalObservations))
4871 {
4872 imagePoints.push_back(iImagePoint->second.point());
4873 objectPoints.push_back(iObjectPoint->second.point());
4874
4875 if (imagePointIds != nullptr)
4876 {
4877 imagePointIds->push_back(iImagePoint->first);
4878 }
4879
4880 if (objectPointIds != nullptr)
4881 {
4882 objectPointIds->push_back(iImagePoint->second.objectPointId());
4883 }
4884 }
4885 }
4886 }
4887}
4888
4889template <bool tThreadSafe, bool tMatchPosition>
4890void Database::imagePointsObjectPoints(const Index32 poseId, const IndexSet32& priorityIds, Vectors2& priorityImagePoints, Vectors3& priorityObjectPoints, Vectors2& remainingImagePoints, Vectors3& remainingObjectPoints, const Vector3& referencePosition, const size_t minimalObservations, Indices32* priorityImagePointIds, Indices32* priorityObjectPointIds, Indices32* remainingImagePointIds, Indices32* remainingObjectPointIds) const
4891{
4892 ocean_assert(poseId != invalidId);
4893 ocean_assert(priorityImagePoints.empty() && priorityObjectPoints.empty());
4894 ocean_assert(remainingImagePoints.empty() && remainingObjectPoints.empty());
4895
4896 ocean_assert(priorityImagePointIds == nullptr || priorityImagePointIds->empty());
4897 ocean_assert(priorityObjectPointIds == nullptr || priorityObjectPointIds->empty());
4898 ocean_assert(remainingImagePointIds == nullptr || remainingImagePointIds->empty());
4899 ocean_assert(remainingObjectPointIds == nullptr || remainingObjectPointIds->empty());
4900
4901 ocean_assert(!priorityIds.empty());
4902
4903 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
4904
4905 const PoseMap::const_iterator iPose = poseMap_.find(poseId);
4906 ocean_assert(iPose != poseMap_.end());
4907
4908 const PoseData& poseData = iPose->second;
4909
4910 priorityImagePoints.reserve(poseData.imagePointIds().size());
4911 priorityObjectPoints.reserve(poseData.imagePointIds().size());
4912
4913 remainingImagePoints.reserve(poseData.imagePointIds().size());
4914 remainingObjectPoints.reserve(poseData.imagePointIds().size());
4915
4916 if (priorityImagePointIds != nullptr)
4917 {
4918 priorityImagePointIds->reserve(poseData.imagePointIds().size());
4919 }
4920
4921 if (priorityObjectPointIds != nullptr)
4922 {
4923 priorityObjectPointIds->reserve(poseData.imagePointIds().size());
4924 }
4925
4926 if (remainingImagePointIds != nullptr)
4927 {
4928 remainingImagePointIds->reserve(poseData.imagePointIds().size());
4929 }
4930
4931 if (remainingObjectPointIds != nullptr)
4932 {
4933 remainingObjectPointIds->reserve(poseData.imagePointIds().size());
4934 }
4935
4936 for (const Index32 imagePointId : poseData.imagePointIds())
4937 {
4938 const ImagePointMap::const_iterator iImagePoint = imagePointMap_.find(imagePointId);
4939 ocean_assert(iImagePoint != imagePointMap_.end());
4940
4941 if (iImagePoint->second.objectPointId() != invalidId)
4942 {
4943 const ObjectPointMap::const_iterator iObjectPoint = objectPointMap_.find(iImagePoint->second.objectPointId());
4944 ocean_assert(iObjectPoint != objectPointMap_.end());
4945
4946 if (((tMatchPosition && iObjectPoint->second.point() == referencePosition) || (!tMatchPosition && iObjectPoint->second.point() != referencePosition)) && (minimalObservations == 0 || iObjectPoint->second.imagePointIds().size() >= minimalObservations))
4947 {
4948 ocean_assert(iObjectPoint->first == iImagePoint->second.objectPointId());
4949
4950 if (priorityIds.find(iObjectPoint->first) != priorityIds.end())
4951 {
4952 priorityImagePoints.push_back(iImagePoint->second.point());
4953 priorityObjectPoints.push_back(iObjectPoint->second.point());
4954
4955 if (priorityImagePointIds != nullptr)
4956 {
4957 priorityImagePointIds->push_back(iImagePoint->first);
4958 }
4959
4960 if (priorityObjectPointIds != nullptr)
4961 {
4962 priorityObjectPointIds->push_back(iImagePoint->second.objectPointId());
4963 }
4964 }
4965 else
4966 {
4967 remainingImagePoints.push_back(iImagePoint->second.point());
4968 remainingObjectPoints.push_back(iObjectPoint->second.point());
4969
4970 if (remainingImagePointIds != nullptr)
4971 {
4972 remainingImagePointIds->push_back(iImagePoint->first);
4973 }
4974
4975 if (remainingObjectPointIds != nullptr)
4976 {
4977 remainingObjectPointIds->push_back(iImagePoint->second.objectPointId());
4978 }
4979 }
4980 }
4981 }
4982 }
4983}
4984
4985template <bool tThreadSafe, bool tMatchPose>
4986void Database::posesImagePoints(const Index32 objectPointId, HomogenousMatrices4& poses, Vectors2& imagePoints, const HomogenousMatrix4& referencePose, Indices32* poseIds, Indices32* imagePointIds, const Index32 lowerPoseId, const Index32 upperPoseId) const
4987{
4988 ocean_assert(objectPointId != invalidId);
4989 ocean_assert(poses.empty() && imagePoints.empty());
4990
4991 ocean_assert(poseIds == nullptr || poseIds->empty());
4992 ocean_assert(imagePointIds == nullptr || imagePointIds->empty());
4993
4994 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
4995
4996 const ObjectPointMap::const_iterator iObjectPoint = objectPointMap_.find(objectPointId);
4997 ocean_assert(iObjectPoint != objectPointMap_.end());
4998
4999 const IndexSet32& imagePointCandidateIds = iObjectPoint->second.imagePointIds();
5000
5001 poses.reserve(imagePointCandidateIds.size());
5002 imagePoints.reserve(imagePointCandidateIds.size());
5003
5004 if (poseIds != nullptr)
5005 {
5006 poseIds->reserve(imagePointCandidateIds.size());
5007 }
5008
5009 if (imagePointIds != nullptr)
5010 {
5011 imagePointIds->reserve(imagePointCandidateIds.size());
5012 }
5013
5014 for (const Index32 imagePointCandidateId : imagePointCandidateIds)
5015 {
5016 const ImagePointMap::const_iterator iImagePoint = imagePointMap_.find(imagePointCandidateId);
5017 ocean_assert(iImagePoint != imagePointMap_.end());
5018
5019 const Vector2& imagePoint = iImagePoint->second.point();
5020 const Index32 poseId = iImagePoint->second.poseId();
5021
5022 if (poseId == invalidId || (lowerPoseId != invalidId && poseId < lowerPoseId) || (upperPoseId != invalidId && poseId > upperPoseId))
5023 {
5024 continue;
5025 }
5026
5027 const PoseMap::const_iterator iPose = poseMap_.find(poseId);
5028 ocean_assert(iPose != poseMap_.end());
5029
5030 const HomogenousMatrix4& pose = iPose->second.pose();
5031
5032 if ((tMatchPose && pose == referencePose) || (!tMatchPose && pose != referencePose))
5033 {
5034 ocean_assert(pose.isValid());
5035
5036 imagePoints.push_back(imagePoint);
5037 poses.push_back(pose);
5038
5039 if (poseIds != nullptr)
5040 {
5041 poseIds->push_back(poseId);
5042 }
5043
5044 if (imagePointIds != nullptr)
5045 {
5046 imagePointIds->push_back(imagePointCandidateId);
5047 }
5048 }
5049 }
5050}
5051
5052template <bool tThreadSafe>
5054{
5055 ocean_assert(!poseIds.empty());
5056
5057 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
5058
5059 TopologyTriples result;
5060
5061 for (const Index32 poseId : poseIds)
5062 {
5063 const PoseMap::const_iterator iPose = poseMap_.find(poseId);
5064 ocean_assert(iPose != poseMap_.end());
5065
5066 const IndexSet32& poseImagePoints = iPose->second.imagePointIds();
5067
5068 for (IndexSet32::const_iterator iId = poseImagePoints.cbegin(); iId != poseImagePoints.cend(); ++iId)
5069 {
5070 const ImagePointMap::const_iterator iImagePoint = imagePointMap_.find(*iId);
5071 ocean_assert(iImagePoint != imagePointMap_.end());
5072
5073 const Index32 objectPointId = iImagePoint->second.objectPointId();
5074
5075 if (objectPointId != invalidId)
5076 {
5077 result.push_back(TopologyTriple(poseId, objectPointId, *iId));
5078 }
5079 }
5080 }
5081
5082 return result;
5083}
5084
5085template <bool tThreadSafe>
5086inline void Database::clear()
5087{
5088 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
5089
5090 poseMap_.clear();
5091 objectPointMap_.clear();
5092 imagePointMap_.clear();
5093 poseObjectPointMap_.clear();
5094
5095 poses_ = 0u;
5096
5099}
5100
5101template <bool tThreadSafe>
5102inline void Database::reset(const Vector3& referenceObjectPoint, const HomogenousMatrix4& referencePose)
5103{
5104 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
5105
5106 for (ObjectPointMap::iterator iObjectPoint = objectPointMap_.begin(); iObjectPoint != objectPointMap_.end(); ++iObjectPoint)
5107 {
5108 iObjectPoint->second.setPoint(referenceObjectPoint);
5109 }
5110
5111 for (PoseMap::iterator iPose = poseMap_.begin(); iPose != poseMap_.end(); ++iPose)
5112 {
5113 iPose->second.setPose(referencePose);
5114 }
5115}
5116
5117template <typename T, bool tThreadSafe>
5118void Database::reset(const size_t numberPoses, const Index32* poseIds, const HomogenousMatrixT4<T>* poses, const size_t numberObjectPoints, const Index32* objectPointIds, const VectorT3<T>* objectPoints, const T* objectPointPriorities, const size_t numberImagePoints, const Index32* imagePointIds, const VectorT2<T>* imagePoints, const Index32* topologyPoseIds, const Index32* topologyObjectPointIds)
5119{
5120 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
5121
5122 clear<false>();
5123
5124 poses_ = 0u;
5127
5128 for (size_t n = 0; n < numberPoses; ++n)
5129 {
5130 const Index32& poseId = poseIds[n];
5131 const HomogenousMatrixT4<T>& pose = poses[n];
5132
5133 ocean_assert(poseMap_.find(poseId) == poseMap_.cend());
5134 poseMap_.emplace(poseId, PoseData(HomogenousMatrix4(pose)));
5135
5136 ocean_assert(poseId != invalidId);
5137 poses_ = max(poses_, poseId + 1u);
5138 }
5139
5140 objectPointMap_.reserve(numberObjectPoints);
5141
5142 for (size_t n = 0; n < numberObjectPoints; ++n)
5143 {
5144 const Index32& objectPointId = objectPointIds[n];
5146 const T& objectPointPriority = objectPointPriorities[n];
5147
5148 ocean_assert(objectPointMap_.find(objectPointId) == objectPointMap_.cend());
5149
5151 {
5153 }
5154 else
5155 {
5157 }
5158
5159 ocean_assert(objectPointId != invalidId);
5160 objectPointIdCounter_ = max(objectPointIdCounter_, objectPointId);
5161 }
5162
5163 imagePointMap_.reserve(numberImagePoints);
5164 poseObjectPointMap_.reserve(numberImagePoints);
5165
5166 for (size_t n = 0; n < numberImagePoints; ++n)
5167 {
5168 const Index32& imagePointId = imagePointIds[n];
5170
5171 const Index32& topologyPoseId = topologyPoseIds[n];
5172 const Index32& topologyObjectPointId = topologyObjectPointIds[n];
5173
5174 ocean_assert(imagePointMap_.find(imagePointId) == imagePointMap_.cend());
5175 imagePointMap_.emplace(imagePointId, ImagePointData(Vector2(imagePoint), topologyPoseId, topologyObjectPointId));
5176
5177 ocean_assert((topologyPoseId == invalidId && topologyObjectPointId == invalidId) || (topologyPoseId != invalidId && topologyObjectPointId != invalidId));
5178
5179 if (topologyPoseId != invalidId)
5180 {
5181 poseObjectPointMap_.emplace(index64(topologyPoseId, topologyObjectPointId), imagePointId);
5182
5183 ocean_assert(poseMap_.find(topologyPoseId) != poseMap_.cend());
5184 poseMap_[topologyPoseId].registerImagePoint(imagePointId);
5185
5186 ocean_assert(objectPointMap_.find(topologyObjectPointId) != objectPointMap_.cend());
5187 objectPointMap_[topologyObjectPointId].registerImagePoint(imagePointId);
5188 }
5189
5190 ocean_assert(imagePointId != invalidId);
5191 imagePointIdCounter_ = max(imagePointIdCounter_, imagePointId);
5192 }
5193}
5194
5195inline Indices32 Database::filterTopologyTriplesPoses(const TopologyTriples& topologyTriples, const IndexSet32& poseIds)
5196{
5197 ocean_assert(!poseIds.empty());
5198
5199 Indices32 result;
5200 result.reserve(topologyTriples.size());
5201
5202 for (unsigned int n = 0u; n < topologyTriples.size(); ++n)
5203 {
5204 if (poseIds.find(topologyTriples[n].poseId()) != poseIds.end())
5205 {
5206 result.push_back(n);
5207 }
5208 }
5209
5210 return result;
5211}
5212
5213inline Indices32 Database::filterTopologyTriplesObjectPoints(const TopologyTriples& topologyTriples, const IndexSet32& objectPointIds)
5214{
5215 ocean_assert(!objectPointIds.empty());
5216
5217 Indices32 result;
5218 result.reserve(topologyTriples.size());
5219
5220 for (unsigned int n = 0u; n < topologyTriples.size(); ++n)
5221 {
5222 if (objectPointIds.find(topologyTriples[n].objectPointId()) != objectPointIds.end())
5223 {
5224 result.push_back(n);
5225 }
5226 }
5227
5228 return result;
5229}
5230
5231inline Indices32 Database::filterTopologyTriplesImagePoints(const TopologyTriples& topologyTriples, const IndexSet32& imagePointIds)
5232{
5233 ocean_assert(!imagePointIds.empty());
5234
5235 Indices32 result;
5236 result.reserve(topologyTriples.size());
5237
5238 for (unsigned int n = 0u; n < topologyTriples.size(); ++n)
5239 {
5240 if (imagePointIds.find(topologyTriples[n].imagePointId()) != imagePointIds.end())
5241 {
5242 result.push_back(n);
5243 }
5244 }
5245
5246 return result;
5247}
5248
5249inline Indices32 Database::reliableObjectPoints(const TopologyTriples& topologyTriples, const unsigned int minimalObservations)
5250{
5251 ocean_assert(!topologyTriples.empty());
5252
5253 Index32To32Map objectPointCounterMap;
5254 for (TopologyTriples::const_iterator iTopology = topologyTriples.cbegin(); iTopology != topologyTriples.cend(); ++iTopology)
5255 {
5256 ocean_assert(iTopology->objectPointId() != invalidId);
5257 objectPointCounterMap[iTopology->objectPointId()]++;
5258 }
5259
5261 objectPointIds.reserve(objectPointCounterMap.size());
5262
5263 for (Index32To32Map::const_iterator iCounter = objectPointCounterMap.cbegin(); iCounter != objectPointCounterMap.cend(); ++iCounter)
5264 {
5265 if (iCounter->second >= minimalObservations)
5266 {
5267 objectPointIds.push_back(iCounter->first);
5268 }
5269 }
5270
5271 return objectPointIds;
5272}
5273
5274inline Database& Database::operator=(const Database& database)
5275{
5276 if (this != &database)
5277 {
5278 poseMap_ = database.poseMap_;
5280 imagePointMap_ = database.imagePointMap_;
5282
5283 poses_ = database.poses_;
5286 }
5287
5288 return *this;
5289}
5290
5291inline Database& Database::operator=(Database&& database) noexcept
5292{
5293 if (this != &database)
5294 {
5295 poseMap_ = std::move(database.poseMap_);
5296 objectPointMap_ = std::move(database.objectPointMap_);
5297 imagePointMap_ = std::move(database.imagePointMap_);
5298 poseObjectPointMap_ = std::move(database.poseObjectPointMap_);
5299
5300 poses_ = database.poses_;
5301 objectPointIdCounter_ = database.objectPointIdCounter_;
5302 imagePointIdCounter_ = database.imagePointIdCounter_;
5303
5304 database.poses_ = 0u;
5305 database.objectPointIdCounter_ = invalidId;
5306 database.imagePointIdCounter_ = invalidId;
5307 }
5308
5309 return *this;
5310}
5311
5312inline Database::operator bool() const
5313{
5314 return !isEmpty<false>();
5315}
5316
5317template <bool tMatchPosition, bool tNeedValidPose>
5318inline void Database::numberCorrespondencesSubset(const Index32 lowerPoseId, const Vector3* referenceObjectPoint, const Scalar minimalPriority, unsigned int* correspondences, const unsigned int firstPose, const unsigned int numberPoses) const
5319{
5320 ocean_assert(numberPoses >= 1u);
5321 ocean_assert(referenceObjectPoint && correspondences);
5322
5323 for (unsigned int n = firstPose; n < firstPose + numberPoses; ++n)
5324 {
5325 correspondences[n] = numberCorrespondences<false, tMatchPosition, tNeedValidPose>(lowerPoseId + n, *referenceObjectPoint, minimalPriority);
5326 }
5327}
5328
5329template <bool tMatchPosition>
5330void Database::objectPointIdsWithNumberOfObservationsSubset(const Index32* objectPointIds, const Vector3* referencePosition, const Scalar minimalPriority, IndexPairs32* pairs, Lock* lock, const unsigned int firstObjectPoint, const unsigned int numberObjectPoints) const
5331{
5332 ocean_assert(objectPointIds && referencePosition && pairs);
5333
5334 IndexPairs32 localPairs;
5335 localPairs.reserve(numberObjectPoints);
5336
5337 for (unsigned int n = firstObjectPoint; n < firstObjectPoint + numberObjectPoints; ++n)
5338 {
5339 const ObjectPointMap::const_iterator iObjectPoint = objectPointMap_.find(objectPointIds[n]);
5340 if (iObjectPoint->second.priority() >= minimalPriority && ((tMatchPosition && iObjectPoint->second.point() == *referencePosition) || (!tMatchPosition && iObjectPoint->second.point() != *referencePosition)))
5341 {
5342 localPairs.emplace_back(iObjectPoint->first, numberValidPoses(iObjectPoint->first, iObjectPoint->second.imagePointIds()));
5343 }
5344 }
5345
5346 if (lock != nullptr)
5347 {
5348 const ScopedLock scopedLock(*lock);
5349 pairs->insert(pairs->end(), localPairs.begin(), localPairs.end());
5350 }
5351 else
5352 {
5353 *pairs = std::move(localPairs);
5354 }
5355}
5356
5357inline unsigned int Database::numberValidPoses(const Index32 objectPointId, const IndexSet32& imagePointIds) const
5358{
5359 ocean_assert_and_suppress_unused(objectPointId != invalidId, objectPointId);
5360
5361 ocean_assert(objectPointMap_.find(objectPointId) != objectPointMap_.end());
5362 ocean_assert(objectPointMap_.find(objectPointId)->second.imagePointIds() == imagePointIds);
5363
5364 unsigned int validPoses = 0u;
5365
5366 for (const Index32 imagePointId : imagePointIds)
5367 {
5368 const ImagePointMap::const_iterator iImagePoint = imagePointMap_.find(imagePointId);
5369 ocean_assert(iImagePoint != imagePointMap_.end());
5370
5371 const Index32 poseId = iImagePoint->second.poseId();
5372
5373 const PoseMap::const_iterator iPose = poseMap_.find(poseId);
5374 ocean_assert(iPose != poseMap_.end());
5375
5376 const HomogenousMatrix4& pose = iPose->second.pose();
5377
5378 if (pose.isValid())
5379 {
5380 validPoses++;
5381 }
5382 }
5383
5384 return validPoses;
5385}
5386
5388{
5389 return Index32(index & 0xFFFFFFFFull);
5390}
5391
5393{
5394 return Index32(index >> 32);
5395}
5396
5397inline Index64 Database::index64(const Index32 first, const Index32 second)
5398{
5399 return Index64(first) | (Index64(second) << 32);
5400}
5401
5402}
5403
5404}
5405
5406#endif // META_OCEAN_TRACKING_DATABASE_H
static Caller< void > create(CT &object, typename MemberFunctionPointerMaker< CT, void, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass >::Type function)
Creates a new caller container for a member function with no function parameter.
Definition Caller.h:3024
This class implements a base class for all indexed-based accessors allowing a constant reference acce...
Definition Accessor.h:241
SquareMatrixT3< T > rotationMatrix() const
Returns the rotation matrix of the transformation.
Definition HomogenousMatrix4.h:1487
VectorT3< T > translation() const
Returns the translation of the transformation.
Definition HomogenousMatrix4.h:1375
bool isValid() const
Returns whether this matrix is a valid homogeneous transformation.
Definition HomogenousMatrix4.h:1800
This class implements a recursive lock object.
Definition Lock.h:31
This class provides basic numeric functionalities.
Definition Numeric.h:57
static constexpr T minValue()
Returns the min scalar value.
Definition Numeric.h:3259
This class implements a scoped lock object for recursive lock objects.
Definition Lock.h:147
This class implements a vector with shifted elements.
Definition ShiftVector.h:27
std::ptrdiff_t Index
Definition of an element index.
Definition ShiftVector.h:38
bool isSingular() const
Returns whether this matrix is singular (and thus cannot be inverted).
Definition SquareMatrix3.h:1342
static bool hasIntersectingElement(const TIterator &firstA, const TIterator &endA, const TIterator &firstB, const TIterator &endB)
Determines whether two (ordered) sets have at least one intersecting element.
Definition Subset.h:1036
This class implements a recursive scoped lock object that is activated by a boolean template paramete...
Definition Lock.h:190
This class implements an accessor object for image points based on a set of image point ids.
Definition Database.h:263
const Database & database_
The reference to the database holding the individual image points.
Definition Database.h:290
ConstImagePointAccessorIds(const Database &database, const Indices32 &imagePointIds)
Creates a new accessor object by providing the references of the database and the image point ids.
Definition Database.h:1911
const Indices32 & imagePointIds_
The reference to the image point ids.
Definition Database.h:293
const Vector2 & operator[](const size_t &index) const override
Returns a specific image point identified by the index within from the specified image point ids.
Definition Database.h:1925
size_t size() const override
Returns the number of image points of this accessor.
Definition Database.h:1919
This class implements an accessor object for image points based on a topology between poses and image...
Definition Database.h:302
const PoseImagePointTopology & topology_
The topology between poses and image points.
Definition Database.h:332
const Database & database_
The reference to the database holding the individual image points.
Definition Database.h:329
size_t size() const override
Returns the number of image points of this accessor.
Definition Database.h:1940
ConstImagePointAccessorTopology(const Database &database, const PoseImagePointTopology &topology)
Creates a new accessor object by providing the references of the database and the topology.
Definition Database.h:1932
const Vector2 & operator[](const size_t &index) const override
Returns a specific image point identified by the index within from the specified topology.
Definition Database.h:1946
This class implements an accessor object for object points based on a set of object point ids.
Definition Database.h:341
ConstObjectPointAccessorIds(const Database &database, const Indices32 &objectPointIds)
Creates a new accessor object by providing the references of the database and the object point ids.
Definition Database.h:1953
const Indices32 & objectPointIds_
The reference to the object point ids.
Definition Database.h:371
size_t size() const override
Returns the number of object points of this accessor.
Definition Database.h:1961
const Vector3 & operator[](const size_t &index) const override
Returns a specific object point identified by the index within from the specified object point ids.
Definition Database.h:1967
const Database & database_
The reference to the database holding the individual object points.
Definition Database.h:368
This class implements an accessor object for poses based on a set of pose ids.
Definition Database.h:380
const Indices32 & poseIds_
The reference to the pose ids.
Definition Database.h:410
const Database & database_
The reference to the database holding the individual object points.
Definition Database.h:407
const HomogenousMatrix4 & operator[](const size_t &index) const override
Returns a specific pose identified by the index within from the specified pose ids.
Definition Database.h:1988
size_t size() const override
Returns the number of poses of this accessor.
Definition Database.h:1982
ConstPoseAccessorIds(const Database &database, const Indices32 &poseIds)
Creates a new accessor object by providing the references of the database and the pose ids.
Definition Database.h:1974
This class implements an accessor object for poses based on a topology between poses and image points...
Definition Database.h:419
const Database & database_
The reference to the database holding the individual image points.
Definition Database.h:446
ConstPoseAccessorTopology(const Database &database, const PoseImagePointTopology &topology)
Creates a new accessor object by providing the references of the database and the topology.
Definition Database.h:1995
size_t size() const override
Returns the number of poses of this accessor.
Definition Database.h:2003
const HomogenousMatrix4 & operator[](const size_t &index) const override
Returns a specific pose identified by the index within from the specified topology.
Definition Database.h:2009
const PoseImagePointTopology & topology_
The topology between poses and image points.
Definition Database.h:449
The base class for all data object storing a set of image point ids.
Definition Database.h:526
const IndexSet32 & imagePointIds() const
Returns the image point ids of this object.
Definition Database.h:2116
IndexSet32 imagePointIds_
The set of registered image point ids of this object.
Definition Database.h:550
void registerImagePoint(const Index32 imagePointId)
Registers (adds) a new image point id at this data object.
Definition Database.h:2121
void unregisterImagePoint(const Index32 imagePointId)
Unregisters (removes) an image point id from this data object.
Definition Database.h:2127
This class implements a data object storing the information connected with an id of an image point.
Definition Database.h:458
Index32 poseId() const
Returns the id of the pose which belongs to the image point of this object.
Definition Database.h:2091
ImagePointData()=default
Creates a default object.
void setPoint(const Vector2 &point)
Sets the location of the image point of this object.
Definition Database.h:2101
Index32 objectPointId() const
Returns the ids of the 3D object point which belongs to the image point of this object.
Definition Database.h:2096
void setPoseId(const Index32 poseId)
Sets the id of the pose belonging to this image point object.
Definition Database.h:2106
void setObjectPointId(const Index32 objectPointId)
Sets the id of the object point belonging to this image point object.
Definition Database.h:2111
const Vector2 & point() const
Returns the 2D location of the image point of this object.
Definition Database.h:2086
This class implements an object storing an id of an image point.
Definition Database.h:115
ImagePointObject(const Index32 imagePointId=invalidId)
Creates a new object.
Definition Database.h:2015
void setImagePointId(const Index32 imagePointId)
Sets or changes the id of the image point of this object.
Definition Database.h:2026
Index32 imagePointId() const
Returns the id of the image point of this object.
Definition Database.h:2021
The data object encapsulating a 3D object point.
Definition Database.h:604
void setPoint(const Vector3 &point)
Sets (changes) the 3D object point of this object.
Definition Database.h:2177
ObjectPointData(const Vector3 &point=invalidObjectPoint(), const Scalar priority=-1)
Creates an object with invalid object point.
Definition Database.h:2160
void setPriority(const Scalar priority)
Sets (changes) the priority value of this object.
Definition Database.h:2182
Scalar priority() const
Returns the priority value of this object.
Definition Database.h:2172
const Vector3 & point() const
Returns the 3D object point of this object.
Definition Database.h:2167
This class implements an object storing an id of an object point.
Definition Database.h:146
Index32 objectPointId() const
Returns the id of the object point of this object.
Definition Database.h:2037
ObjectPointObject(const Index32 objectPointId=invalidId)
Creates a new object.
Definition Database.h:2031
void setObjectPointId(const Index32 objectPointId)
Sets or changes the id of the object point of this object.
Definition Database.h:2042
The data object encapsulating a 6DOF camera pose.
Definition Database.h:557
PoseData(const HomogenousMatrix4 &world_T_camera=HomogenousMatrix4(false), const Scalar fov=-1)
Creates a new object with specified pose.
Definition Database.h:2133
void setPose(const HomogenousMatrix4 &world_T_camera)
Sets (changes) the pose of this object.
Definition Database.h:2150
const HomogenousMatrix4 & pose() const
Returns the pose of this object.
Definition Database.h:2140
void setFov(const Scalar fov)
Sets (changes) the field of view value of this object.
Definition Database.h:2155
Scalar fov() const
Returns the field of view value of this object.
Definition Database.h:2145
This class stores a pair of pose id and image point id.
Definition Database.h:231
PoseImagePointPair(const Index32 poseId=invalidId, const Index32 imagePointId=invalidId)
Creates a new pair object.
Definition Database.h:2071
This class implements an object storing an id of an pose object.
Definition Database.h:177
PoseObject(const Index32 poseId=invalidId)
Creates a new object.
Definition Database.h:2047
void setPoseId(const Index32 poseId)
Sets or changes the id of the camera pose of this object.
Definition Database.h:2058
Index32 poseId() const
Returns the id of the camera pose of this object.
Definition Database.h:2053
This class defines the topology between a camera pose id, an object point id and an image point id.
Definition Database.h:213
TopologyTriple(const Index32 poseId=invalidId, const Index32 objectPointId=invalidId, const Index32 imagePointId=invalidId)
Creates a new topology object.
Definition Database.h:2063
This class implements a database for 3D object points, 2D image points and 6DOF camera poses.
Definition Database.h:67
bool hasObjectPoint(const Index32 objectPointId, Vector3 *objectPoint=nullptr) const
Returns whether this database holds a specified object point.
Definition Database.h:3093
bool hasObservation(const Index32 poseId, const Index32 objectPointId, Vector2 *point=nullptr, Index32 *pointId=nullptr) const
Returns whether an object point is visible in a specified frame, and optional the location and id of ...
Definition Database.h:2300
unsigned int numberCorrespondences(const Index32 poseId, const Vector3 &referenceObjectPoint, const Scalar minimalPriority=Scalar(-1)) const
Counts the number of correspondences (e.g., valid or invalid) between image and object points for a s...
Definition Database.h:2969
void numberCorrespondencesSubset(const Index32 lowerPoseId, const Vector3 *referenceObjectPoint, const Scalar minimalPriority, unsigned int *correspondences, const unsigned int firstPose, const unsigned int numberPoses) const
Counts the number of valid correspondences between image and object points for a subset of several po...
Definition Database.h:5318
std::unordered_map< Index32, ImagePointData > ImagePointMap
Definition of an (unordered) map mapping image point ids to image point data objects.
Definition Database.h:660
void renameObjectPoint(const Index32 oldObjectPointId, const Index32 newObjectPointId)
Renames an object point, changes the id of the object point respectively.
Definition Database.h:3286
void setObjectPoint(const Index32 objectPointId, const Vector3 &objectPoint)
Sets (changes) an object point without modifying the priority value of the object point.
Definition Database.h:3724
void setObjectPoints(const Index32 *objectPointIds, const Vector3 *objectPoints, const size_t number)
Sets (changes) a set of object points without modifying the priority value of the object points.
Definition Database.h:3737
void removeObjectPoint(const Index32 objectPointId)
Removes an object point from this database.
Definition Database.h:3217
std::unordered_map< Index64, Index32 > Index64To32Map
Definition of an (unordered) map mapping 64 bit ids to 32 bit ids.
Definition Database.h:670
std::vector< Vectors2 > ImagePointGroups
Definition of a vector holding 2D vectors.
Definition Database.h:109
std::map< Index32, PoseData > PoseMap
Definition of an (ordered) map mapping pose ids to pose data objects, we use an ordered map as poses ...
Definition Database.h:650
Indices32 objectPointIds(Vectors3 *objectPoints=nullptr, Scalars *priorities=nullptr) const
Returns the ids of all object points that are part of this database.
Definition Database.h:3936
const IndexSet32 & imagePointIds(const Index32 poseId) const
Returns the ids of all image points visible in a specified camera pose (camera frame).
Definition Database.h:3864
void clear()
Clears the database including all camera poses, object points, image points and any topology.
Definition Database.h:5086
IndexPairs32 objectPointIdsWithNumberOfObservations(const Vector3 &referencePosition, const Scalar minimalPriority=Scalar(-1), Worker *worker=nullptr) const
Returns pairs of object point ids combined with counts of valid observations.
Definition Database.h:4142
void attachImagePointToPose(const Index32 imagePointId, const Index32 poseId)
Attaches an existing image point to an existing camera pose (defines the topology between an image po...
Definition Database.h:3655
Lock lock_
The lock for the entire database.
Definition Database.h:1902
void detachImagePointFromObjectPoint(const Index32 imagePointId)
Detaches an image point from an object point (withdraws the topology).
Definition Database.h:3626
Vectors2 imagePointsFromObjectPoints(const Index32 poseId, Indices32 &objectPointIds, Indices32 *imagePointIds=nullptr) const
Returns all image points which are located in a specified frame and which are projections of a set of...
Definition Database.h:4602
bool hasImagePoint(const Index32 imagePointId, Vector2 *imagePoint=nullptr) const
Returns whether this database holds a specified image point.
Definition Database.h:3032
ObjectPointMap objectPointMap_
The map mapping unique object point ids to object point data instances.
Definition Database.h:1884
std::vector< PoseImagePointPair > PoseImagePointTopology
Definition of a vector holding several pairs of pose and image point ids.
Definition Database.h:245
TopologyTriples topologyTriples(const Indices32 &poseIds) const
Returns topology triples with valid image points ids, object points ids and pose ids for a set of giv...
Definition Database.h:5053
const Vector2 & imagePoint(const Index32 imagePointId) const
Returns the location of an image point which is specified by the id of the image point.
Definition Database.h:2251
static Index64 index64(const Index32 first, const Index32 second)
Returns the 64 bit index composed of two 32 bit indices.
Definition Database.h:5397
std::map< Index32, Vectors2 > ImagePointsMap
Definition of a map mapping ids to 2D vectors.
Definition Database.h:104
size_t numberImagePointsFromObjectPoint(const Index32 objectPointId) const
Returns the number of image point observations which belong to a given object point.
Definition Database.h:3447
void setObjectPointPriority(const Index32 objectPointId, const Scalar priority)
Sets (changes) the priority value of an object point.
Definition Database.h:3794
HomogenousMatrices4 poses(const Index32 *poseIds, const size_t size) const
Returns the 6DOF pose values for all specified pose ids.
Definition Database.h:2455
void imagePointsObjectPoints(const Index32 poseId, Vectors2 &imagePoints, Vectors3 &objectPoints, const Vector3 &referencePosition=invalidObjectPoint(), const size_t minimalObservations=0, Indices32 *imagePointIds=nullptr, Indices32 *objectPointIds=nullptr) const
Returns corresponding object points and image points for a given camera pose.
Definition Database.h:4832
static Indices32 filterTopologyTriplesObjectPoints(const TopologyTriples &topologyTriples, const IndexSet32 &objectPointIds)
Filters a set of given topology triples due to a set of given object point ids.
Definition Database.h:5213
std::map< Index32, Vector2 > IdPointMap
Definition of a map mapping ids to 2D image point object.
Definition Database.h:84
const IndexSet32 & imagePointsFromPose(const Index32 poseId) const
Returns all image points which belong to a given camera pose.
Definition Database.h:3550
Indices32 poseIds(const HomogenousMatrix4 &referencePose, HomogenousMatrices4 *poses=nullptr) const
Returns the ids of specific 6DOF poses.
Definition Database.h:2562
std::vector< std::pair< Index32, PoseImagePointTopology > > PoseImagePointTopologyGroups
Definition of a vector holding several groups of pairs of pose and image point ids.
Definition Database.h:250
static const Index32 invalidId
Definition of an invalid id.
Definition Database.h:73
void removePose(const Index32 poseId)
Removes a pose from this database.
Definition Database.h:3409
void removeImagePoint(const Index32 imagePointId)
Removes an image point from this database.
Definition Database.h:3061
unsigned int numberObservations(const Index32 poseId, const Indices32 &objectPointIds) const
Counts the number of observations of a given set of object point ids for a specific camera frame.
Definition Database.h:2949
const HomogenousMatrix4 & pose(const Index32 poseId) const
Returns the 6DOF pose of a camera frame which is specified by the id of the pose.
Definition Database.h:2444
std::pair< Index32, Vector2 > IdPointPair
Definition of a pair of ids and 2D image points.
Definition Database.h:89
bool hasPose(const Index32 poseId, HomogenousMatrix4 *pose=nullptr) const
Returns whether this database holds a specified camera pose.
Definition Database.h:3369
void removeObjectPointAndAttachedImagePoints(const Index32 objectPointId)
Removes an object point from this database and also removes all image points attached to the object p...
Definition Database.h:3248
bool validPoseBorders(Index32 &rangeLowerPoseId, Index32 &rangeUpperPoseId) const
Returns the smallest id (the id of the lower frame border) and the largest id (the id of the upper fr...
Definition Database.h:2616
static Index32 secondIndex(const Index64 index)
Returns the second 32 bit index of a 64 bit index.
Definition Database.h:5392
bool largestValidPoseRange(const Index32 lowerPoseId, const Index32 upperPoseId, Index32 &rangeLowerPoseId, Index32 &rangeUpperPoseId) const
Determines the largest pose id range for which the database holds valid poses.
Definition Database.h:2700
void observationsFromObjectPoint(const Index32 objectPointId, Indices32 &poseIds, Indices32 &imagePointIds, Vectors2 *imagePoints=nullptr) const
Returns all observations (combination of poses and image points) which belong to a given object point...
Definition Database.h:3462
void attachImagePointToObjectPoint(const Index32 imagePointId, const Index32 objectPointId)
Attaches an existing image point to an existing object points (defines the topology between an image ...
Definition Database.h:3599
Database & operator=(const Database &database)
Assign operator copying a second database to this database object.
Definition Database.h:5274
size_t imagePointNumber() const
Returns the number of image point ids in this database.
Definition Database.h:2243
std::map< Index32, IdPointPairs > IdIdPointPairsMap
Definition of a map mapping ids to 2D image point id pairs.
Definition Database.h:99
SquareMatrices3 rotationalPoses(const Index32 *poseIds, const size_t size) const
Returns the 3DOF rotational part of the 6DOF pose values for all specified pose ids.
Definition Database.h:2474
Index32 addObjectPoint(const Vector3 &objectPoint, const Scalar priority=Scalar(-1))
Adds a new 3D object point to this database.
Definition Database.h:3113
const Vector3 & objectPoint(const Index32 objectPointId) const
Returns the location of an object point which is specified by the id of the object point.
Definition Database.h:2335
void reset(const Vector3 &referenceObjectPoint=invalidObjectPoint(), const HomogenousMatrix4 &referencePose=HomogenousMatrix4(false))
Resets the geometric information of this database for 3D object points and 6DOF camera poses.
Definition Database.h:5102
void setImagePoint(const Index32 imagePointId, const Vector2 &imagePoint)
Sets (changes) an image point.
Definition Database.h:3711
std::unordered_map< Index32, Index32 > Index32To32Map
Definition of an (unordered) map mapping 32 bit ids to 32 bit ids.
Definition Database.h:665
std::unordered_map< Index32, ObjectPointData > ObjectPointMap
Definition of an (unordered) map mapping object point ids to object point data objects.
Definition Database.h:655
const IndexSet32 & imagePointsFromObjectPoint(const Index32 objectPointId) const
Returns all image points which belong to a given object point.
Definition Database.h:3563
Vectors3 objectPoints() const
Returns the positions of all 3D object points.
Definition Database.h:2371
Index32 addImagePoint(const Vector2 &imagePoint)
Adds a new 2D image point to this database.
Definition Database.h:3052
ImagePointMap imagePointMap_
The map mapping unique image points ids to image point data instances.
Definition Database.h:1887
unsigned int numberValidPoses(const Index32 objectPointId, const IndexSet32 &imagePointIds) const
Counts the number of valid poses of a given object point.
Definition Database.h:5357
bool poseWithLeastCorrespondences(const Index32 lowerPoseId, const Index32 upperPoseId, Index32 *poseId=nullptr, unsigned int *correspondences=nullptr, const Vector3 &referenceObjectPoint=invalidObjectPoint()) const
Determines the pose id for which the database holds the least number of point correspondences (betwee...
Definition Database.h:2805
bool addPose(const Index32 poseId, const HomogenousMatrix4 &pose=HomogenousMatrix4(false))
Adds a new camera pose by specifying the unique id of the new pose.
Definition Database.h:3390
unsigned int poses_
The number of poses.
Definition Database.h:1893
void setPoses(const Index32 *poseIds, const HomogenousMatrix4 *poses, const size_t number)
Sets (changes) a set of poses.
Definition Database.h:3820
Index32 imagePointIdCounter_
The counter for unique image point ids.
Definition Database.h:1899
Index32 objectPointFromImagePoint(const Index32 imagePointId) const
Returns the object point which belongs to a given image point.
Definition Database.h:3537
bool isEmpty() const
Returns whether this database holds at least one image point, one object point or one camera pose.
Definition Database.h:2219
IndexSet32 posesFromObjectPoint(const Index32 objectPointId) const
Returns all poses which belong to a given object point.
Definition Database.h:3576
PoseMap poseMap_
The map mapping unique pose ids to pose data instances.
Definition Database.h:1881
Index32 objectPointIdCounter_
The counter for unique object point ids.
Definition Database.h:1896
std::vector< IdPointPair > IdPointPairs
Definition of a vector holding pairs of ids and 2D image points.
Definition Database.h:94
void objectPointIdsWithNumberOfObservationsSubset(const Index32 *objectPointIds, const Vector3 *referencePosition, const Scalar minimalPriority, IndexPairs32 *pairs, Lock *lock, const unsigned int firstObjectPoint, const unsigned int numberObjectPoints) const
Returns pairs of object point ids combined with counts of valid observations.
Definition Database.h:5330
bool poseWithMostObservations(const IndexSet32 &poseCandidates, const IndexSet32 &majorObjectPointIds, const IndexSet32 &minorObjectPointIds, Index32 &poseId, Indices32 *visibleMajorObjectPointIds=nullptr, Indices32 *visibleMinorObjectPointIds=nullptr) const
Determines the pose id from a set of given pose id candidates for which the database holds the most o...
Definition Database.h:2846
size_t poseNumber() const
Returns the number of poses of this database.
Definition Database.h:2227
Database()=default
Creates a new empty database object.
void setPose(const Index32 poseId, const HomogenousMatrix4 &pose)
Sets (changes) a pose.
Definition Database.h:3807
std::vector< TopologyTriple > TopologyTriples
Definition of a vector holding object of topology triple.
Definition Database.h:255
Index64To32Map poseObjectPointMap_
The map mapping a pair of pose id and object point id to image point ids.
Definition Database.h:1890
Lock & lock()
Returns a reference to the lock object of this database object.
Definition Database.h:2213
void posesImagePoints(const Index32 objectPointId, HomogenousMatrices4 &poses, Vectors2 &imagePoints, const HomogenousMatrix4 &referencePose=HomogenousMatrix4(false), Indices32 *poseIds=nullptr, Indices32 *imagePointIds=nullptr, const Index32 lowerPoseId=invalidId, const Index32 upperPoseId=invalidId) const
Returns corresponding poses and image points for a given object point from the entire range of possib...
Definition Database.h:4986
bool poseWithMostCorrespondences(const Index32 lowerPoseId, const Index32 upperPoseId, Index32 *poseId=nullptr, unsigned int *correspondences=nullptr, const Vector3 &referenceObjectPoint=invalidObjectPoint()) const
Determines the pose id for which the database holds the most number of point correspondences (between...
Definition Database.h:2771
static Index32 firstIndex(const Index64 index)
Returns the first 32 bit index of a 64 bit index.
Definition Database.h:5387
static Indices32 reliableObjectPoints(const TopologyTriples &topologyTriples, const unsigned int minimalObservations)
Determines reliable object points from a set of given topology triples (by determining all object poi...
Definition Database.h:5249
Scalar objectPointPriority(const Index32 objectPointId) const
Returns the priority of an object point which is specified by the id of the object point.
Definition Database.h:2360
bool poseBorders(Index32 &lowerPoseId, Index32 &upperPoseId) const
Returns the smallest id (the id of the lower frame border) and the largest id (the id of the upper fr...
Definition Database.h:2600
static Vector3 invalidObjectPoint()
Returns an invalid object point.
Definition Database.h:1905
size_t objectPointNumber() const
Returns the number of object point ids in this database.
Definition Database.h:2235
void detachImagePointFromPose(const Index32 imagePointId)
Detaches an image point from a camera pose (withdraws the topology).
Definition Database.h:3682
Index32 poseFromImagePoint(const Index32 imagePointId) const
Determines the camera pose (camera frame) in which a specified image point is visible (to which the i...
Definition Database.h:3434
static PoseImagePointTopologyGroups objectPointTopology(const TopologyTriples &topologyTriples, const Indices32 *indices=nullptr)
Converts the set of topology triples into a representation which is forced/oriented by object points ...
bool validPoseRange(const Index32 lowerPoseId, const Index32 startPoseId, const Index32 upperPoseId, Index32 &rangeLowerPoseId, Index32 &rangeUpperPoseId) const
Determines the pose id range (around a specified start frame) for which the database holds valid pose...
Definition Database.h:2656
Index32 addObjectPointFromDatabase(const Database &secondDatabase, const Index32 secondDatabaseObjectPointId, const SquareMatrix3 &imagePointTransformation=SquareMatrix3(true), const Index32 newObjectPointId=invalidId, const Index32 secondDatabaseLowerPoseId=invalidId, const Index32 secondDatabaseUpperPoseId=invalidId, const bool forExistingPosesOnly=false)
Adds an object point from another database, adds all connected image points, registers unknown poses,...
Definition Database.h:3134
ImagePointGroups imagePointGroups(const Indices32 poseIds, Indices32 &objectPointIds) const
Determines the groups of image points matching to unique object points in individual camera poses.
Definition Database.h:4688
Vectors2 imagePoints(const Indices32 &imagePointIds) const
Returns the positions of 2D image points specified by the ids of the image points.
Definition Database.h:2262
static Indices32 filterTopologyTriplesPoses(const TopologyTriples &topologyTriples, const IndexSet32 &poseIds)
Filters a set of given topology triples due to a set of given pose ids.
Definition Database.h:5195
void mergeObjectPoints(const Index32 remainingObjectPointId, const Index32 removingObjectPointId, const Vector3 &newPoint, const Scalar newPriority)
Merges two object points together, afterwards one object point will be removed.
Definition Database.h:3326
Vectors2 imagePointsWithObjectPoints(const Index32 poseId, Indices32 &objectPointIds) const
Returns all image points which are located in a specified frame and are projections of object points.
Definition Database.h:4559
static Indices32 filterTopologyTriplesImagePoints(const TopologyTriples &topologyTriples, const IndexSet32 &imagePointIds)
Filters a set of given topology triples due to a set of given image point ids.
Definition Database.h:5231
bool isNull() const
Returns whether this vector is a null vector up to a small epsilon.
Definition Vector3.h:858
const T * data() const noexcept
Returns an pointer to the vector elements.
Definition Vector3.h:846
This class implements a worker able to distribute function calls over different threads.
Definition Worker.h:33
bool executeFunction(const Function &function, const unsigned int first, const unsigned int size, const unsigned int firstIndex=(unsigned int)(-1), const unsigned int sizeIndex=(unsigned int)(-1), const unsigned int minimalIterations=1u, const unsigned int threadIndex=(unsigned int)(-1))
Executes a callback function separable by two function parameters.
std::vector< IndexPair32 > IndexPairs32
Definition of a vector holding 32 bit index pairs.
Definition Base.h:144
std::vector< Index32 > Indices32
Definition of a vector holding 32 bit index values.
Definition Base.h:96
uint32_t Index32
Definition of a 32 bit index value.
Definition Base.h:84
uint64_t Index64
Definition of a 64 bit index value.
Definition Base.h:90
std::set< Index32 > IndexSet32
Definition of a set holding 32 bit indices.
Definition Base.h:114
std::vector< Vector2 > Vectors2
Definition of a vector holding Vector2 objects.
Definition Vector2.h:64
float Scalar
Definition of a scalar type.
Definition Math.h:129
std::vector< HomogenousMatrix4 > HomogenousMatrices4
Definition of a vector holding HomogenousMatrix4 objects.
Definition HomogenousMatrix4.h:73
std::vector< SquareMatrix3 > SquareMatrices3
Definition of a vector holding SquareMatrix3 objects.
Definition SquareMatrix3.h:72
std::vector< Vector3 > Vectors3
Definition of a vector holding Vector3 objects.
Definition Vector3.h:65
std::vector< Scalar > Scalars
Definition of a vector holding Scalar objects.
Definition Math.h:145
VectorT3< Scalar > Vector3
Definition of a 3D vector.
Definition Vector3.h:29
VectorT2< Scalar > Vector2
Definition of a 2D vector.
Definition Vector2.h:28
HomogenousMatrixT4< Scalar > HomogenousMatrix4
Definition of the HomogenousMatrix4 object, depending on the OCEAN_MATH_USE_SINGLE_PRECISION flag eit...
Definition HomogenousMatrix4.h:44
The namespace covering the entire Ocean framework.
Definition Accessor.h:15