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 typedef std::map<Index32, Vector2> IdPointMap;
85
86 /**
87 * Definition of a pair of ids and 2D image points.
88 */
89 typedef std::pair<Index32, Vector2> IdPointPair;
90
91 /**
92 * Definition of a vector holding pairs of ids and 2D image points.
93 */
94 typedef std::vector<IdPointPair> IdPointPairs;
95
96 /**
97 * Definition of a map mapping ids to 2D image point id pairs.
98 */
99 typedef std::map<Index32, IdPointPairs> IdIdPointPairsMap;
100
101 /**
102 * Definition of a map mapping ids to 2D vectors.
103 */
104 typedef std::map<Index32, Vectors2> ImagePointsMap;
105
106 /**
107 * Definition of a vector holding 2D vectors.
108 */
109 typedef std::vector<Vectors2> ImagePointGroups;
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.
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.
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.
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 typedef std::vector<PoseImagePointPair> PoseImagePointTopology;
246
247 /**
248 * Definition of a vector holding several groups of pairs of pose and image point ids.
249 */
250 typedef std::vector< std::pair<Index32, PoseImagePointTopology> > PoseImagePointTopologyGroups;
251
252 /**
253 * Definition of a vector holding object of topology triple.
254 */
255 typedef std::vector<TopologyTriple> TopologyTriples;
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 virtual size_t size() const;
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 virtual const Vector2& operator[](const size_t& index) const;
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 virtual size_t size() const;
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 virtual const Vector2& operator[](const size_t& index) const;
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 virtual size_t size() const;
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 virtual const Vector3& operator[](const size_t& index) const;
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 virtual size_t size() const;
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 virtual const HomogenousMatrix4& operator[](const size_t& index) const;
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 virtual size_t size() const;
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 virtual const HomogenousMatrix4& operator[](const size_t& index) const;
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 inline ImagePointData();
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.
514
515 /// The id of the pose which belongs to this object.
517
518 /// The id of the object point which belongs to this object.
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.
595
596 /// The field of view value of this object.
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.
642
643 /// The priority value of this object.
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 typedef std::map<Index32, PoseData> PoseMap;
651
652 /**
653 * Definition of an (unordered) map mapping object point ids to object point data objects.
654 */
655 typedef std::unordered_map<Index32, ObjectPointData> ObjectPointMap;
656
657 /**
658 * Definition of an (unordered) map mapping image point ids to image point data objects.
659 */
660 typedef std::unordered_map<Index32, ImagePointData> ImagePointMap;
661
662 /**
663 * Definition of an (unordered) map mapping 32 bit ids to 32 bit ids.
664 */
665 typedef std::unordered_map<Index32, Index32> Index32To32Map;
666
667 /**
668 * Definition of an (unordered) map mapping 64 bit ids to 32 bit ids.
669 */
670 typedef std::unordered_map<Index64, Index32> Index64To32Map;
671
672 public:
673
674 /**
675 * Creates a new empty database object.
676 */
677 inline Database();
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 databasePoses;
1894
1895 /// The counter for unique object point ids.
1897
1898 /// The counter for unique image point ids.
1900
1901 /// The lock for the entire database.
1903};
1904
1909
1910template <bool tThreadSafe>
1912 accessorDatabase(database),
1913 accessorImagePointIds(imagePointIds)
1914{
1915 // nothing to do here
1916}
1917
1918template <bool tThreadSafe>
1920{
1921 return accessorImagePointIds.size();
1922}
1923
1924template <bool tThreadSafe>
1926{
1927 ocean_assert(index < accessorImagePointIds.size());
1928 return accessorDatabase.imagePoint<tThreadSafe>(accessorImagePointIds[index]);
1929}
1930
1931template <bool tThreadSafe>
1933 accessorDatabase(database),
1934 accessorTopology(topology)
1935{
1936 // nothing to do here
1937}
1938
1939template <bool tThreadSafe>
1941{
1942 return accessorTopology.size();
1943}
1944
1945template <bool tThreadSafe>
1947{
1948 ocean_assert(index < accessorTopology.size());
1949 return accessorDatabase.imagePoint<tThreadSafe>(accessorTopology[index].imagePointId());
1950}
1951
1952template <bool tThreadSafe>
1954 accessorDatabase(database),
1955 accessorObjectPointIds(objectPointIds)
1956{
1957 // nothing to do here
1958}
1959
1960template <bool tThreadSafe>
1962{
1963 return accessorObjectPointIds.size();
1964}
1965
1966template <bool tThreadSafe>
1968{
1969 ocean_assert(index < accessorObjectPointIds.size());
1970 return accessorDatabase.objectPoint<tThreadSafe>(accessorObjectPointIds[index]);
1971}
1972
1973template <bool tThreadSafe>
1975 accessorDatabase(database),
1976 accessorPoseIds(poseIds)
1977{
1978 // nothing to do here
1979}
1980
1981template <bool tThreadSafe>
1983{
1984 return accessorPoseIds.size();
1985}
1986
1987template <bool tThreadSafe>
1989{
1990 ocean_assert(index < accessorPoseIds.size());
1991 return accessorDatabase.pose<tThreadSafe>(accessorPoseIds[index]);
1992}
1993
1994template <bool tThreadSafe>
1996 accessorDatabase(database),
1997 accessorTopology(topology)
1998{
1999 // nothing to do here
2000}
2001
2002template <bool tThreadSafe>
2004{
2005 return accessorTopology.size();
2006}
2007
2008template <bool tThreadSafe>
2010{
2011 ocean_assert(index < accessorTopology.size());
2012 return accessorDatabase.pose<tThreadSafe>(accessorTopology[index].poseId());
2013}
2014
2016 objectImagePointId(imagePointId)
2017{
2018 // nothing to do here
2019}
2020
2022{
2023 return objectImagePointId;
2024}
2025
2027{
2028 objectImagePointId = imagePointId;
2029}
2030
2032 objectObjectPointId(objectPointId)
2033{
2034 // nothing to do here
2035}
2036
2038{
2039 return objectObjectPointId;
2040}
2041
2043{
2044 objectObjectPointId = objectPointId;
2045}
2046
2048 objectPoseId(poseId)
2049{
2050 // nothing to do here
2051}
2052
2054{
2055 return objectPoseId;
2056}
2057
2059{
2060 objectPoseId = 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
2079 dataPoint(Numeric::minValue(), Numeric::minValue()),
2080 dataPoseId(invalidId),
2081 dataObjectPointId(invalidId)
2082{
2083 // nothing to do here
2084}
2085
2086inline Database::ImagePointData::ImagePointData(const Vector2& point, const Index32 poseId, const Index32 objectPointId) :
2087 dataPoint(point),
2088 dataPoseId(poseId),
2089 dataObjectPointId(objectPointId)
2090{
2091 // nothing to do here
2092}
2093
2095{
2096 return dataPoint;
2097}
2098
2100{
2101 return dataPoseId;
2102}
2103
2105{
2106 return dataObjectPointId;
2107}
2108
2110{
2111 dataPoint = point;
2112}
2113
2115{
2116 dataPoseId = poseId;
2117}
2118
2120{
2121 dataObjectPointId = objectPointId;
2122}
2123
2125{
2126 return dataImagePointIds;
2127}
2128
2129inline void Database::Data::registerImagePoint(const Index32 imagePointId)
2130{
2131 ocean_assert(dataImagePointIds.find(imagePointId) == dataImagePointIds.end());
2132 dataImagePointIds.insert(imagePointId);
2133}
2134
2135inline void Database::Data::unregisterImagePoint(const Index32 imagePointId)
2136{
2137 ocean_assert(dataImagePointIds.find(imagePointId) != dataImagePointIds.end());
2138 dataImagePointIds.erase(imagePointId);
2139}
2140
2141inline Database::PoseData::PoseData(const HomogenousMatrix4& world_T_camera, const Scalar fov) :
2142 world_T_camera_(world_T_camera),
2143 dataFov(fov)
2144{
2145 // nothing to do here
2146}
2147
2149{
2150 return world_T_camera_;
2151}
2152
2154{
2155 return dataFov;
2156}
2157
2158inline void Database::PoseData::setPose(const HomogenousMatrix4& world_T_camera)
2159{
2160 world_T_camera_ = world_T_camera;
2161}
2162
2164{
2165 dataFov = fov;
2166}
2167
2168inline Database::ObjectPointData::ObjectPointData(const Vector3& point, const Scalar priority) :
2169 dataPoint(point),
2170 dataPriority(priority)
2171{
2172 // nothing to do here
2173}
2174
2176{
2177 return dataPoint;
2178}
2179
2181{
2182 return dataPriority;
2183}
2184
2186{
2187 dataPoint = point;
2188}
2189
2191{
2192 dataPriority = priority;
2193}
2194
2196 databasePoses(0u),
2199{
2200 // nothing to do here
2201}
2202
2203inline Database::Database(const Database& database) :
2204 databasePoseMap(database.databasePoseMap),
2205 databaseObjectPointMap(database.databaseObjectPointMap),
2206 databaseImagePointMap(database.databaseImagePointMap),
2207 databasePoseObjectPointMap(database.databasePoseObjectPointMap),
2208 databasePoses(database.databasePoses),
2209 databaseObjectPointIdCounter(database.databaseObjectPointIdCounter),
2210 databaseImagePointIdCounter(database.databaseImagePointIdCounter)
2211{
2212 // nothing to do here
2213}
2214
2215inline Database::Database(Database&& database) noexcept :
2216 databasePoseMap(std::move(database.databasePoseMap)),
2217 databaseObjectPointMap(std::move(database.databaseObjectPointMap)),
2218 databaseImagePointMap(std::move(database.databaseImagePointMap)),
2219 databasePoseObjectPointMap(std::move(database.databasePoseObjectPointMap)),
2220 databasePoses(database.databasePoses),
2221 databaseObjectPointIdCounter(database.databaseObjectPointIdCounter),
2222 databaseImagePointIdCounter(database.databaseImagePointIdCounter)
2223{
2224 database.databasePoses = 0u;
2225 database.databaseObjectPointIdCounter = invalidId;
2226 database.databaseImagePointIdCounter = invalidId;
2227}
2228
2230{
2231 return databaseLock;
2232}
2233
2234template <bool tThreadSafe>
2235inline bool Database::isEmpty() const
2236{
2238
2239 return databasePoseMap.empty() && databaseObjectPointMap.empty() && databaseImagePointMap.empty();
2240}
2241
2242template <bool tThreadSafe>
2243inline size_t Database::poseNumber() const
2244{
2246
2247 return databasePoseMap.size();
2248}
2249
2250template <bool tThreadSafe>
2251inline size_t Database::objectPointNumber() const
2252{
2254
2255 return databaseObjectPointMap.size();
2256}
2257
2258template <bool tThreadSafe>
2259inline size_t Database::imagePointNumber() const
2260{
2262
2263 return databaseImagePointMap.size();
2264}
2265
2266template <bool tThreadSafe>
2267inline const Vector2& Database::imagePoint(const Index32 imagePointId) const
2268{
2269 ocean_assert(imagePointId != invalidId);
2270
2272
2273 ocean_assert(databaseImagePointMap.find(imagePointId) != databaseImagePointMap.end());
2274 return databaseImagePointMap.find(imagePointId)->second.point();
2275}
2276
2277template <bool tThreadSafe>
2278inline Vectors2 Database::imagePoints(const Indices32& imagePointIds) const
2279{
2281
2283 imagePoints.reserve(imagePointIds.size());
2284
2285 for (Indices32::const_iterator i = imagePointIds.begin(); i != imagePointIds.end(); ++i)
2286 {
2287 ocean_assert(*i != invalidId);
2288 ocean_assert(databaseImagePointMap.find(*i) != databaseImagePointMap.end());
2289
2290 imagePoints.push_back(databaseImagePointMap.find(*i)->second.point());
2291 }
2292
2293 return imagePoints;
2294}
2295
2296template <bool tThreadSafe>
2297inline Vectors2 Database::imagePoints(const IndexSet32& imagePointIds) const
2298{
2300
2302 imagePoints.reserve(imagePointIds.size());
2303
2304 for (IndexSet32::const_iterator i = imagePointIds.begin(); i != imagePointIds.end(); ++i)
2305 {
2306 ocean_assert(*i != invalidId);
2307 ocean_assert(databaseImagePointMap.find(*i) != databaseImagePointMap.end());
2308
2309 imagePoints.push_back(databaseImagePointMap.find(*i)->second.point());
2310 }
2311
2312 return imagePoints;
2313}
2314
2315template <bool tThreadSafe>
2316inline bool Database::hasObservation(const Index32 poseId, const Index32 objectPointId, Vector2* point, Index32* pointId) const
2317{
2318 ocean_assert(objectPointId != invalidId && poseId != invalidId);
2319
2321
2322 const Index64To32Map::const_iterator i = databasePoseObjectPointMap.find(index64(poseId, objectPointId));
2323
2324 if (i == databasePoseObjectPointMap.end())
2325 return false;
2326
2327 if (!point && !pointId)
2328 return true;
2329
2330 const ImagePointMap::const_iterator iI = databaseImagePointMap.find(i->second);
2331 ocean_assert(iI != databaseImagePointMap.end());
2332
2333 if (point)
2334 *point = iI->second.point();
2335
2336 if (pointId)
2337 *pointId = iI->first;
2338
2339 return true;
2340}
2341
2342template <bool tThreadSafe>
2343inline const Vector3& Database::objectPoint(const Index32 objectPointId) const
2344{
2345 ocean_assert(objectPointId != invalidId);
2346
2348
2349 ocean_assert(databaseObjectPointMap.find(objectPointId) != databaseObjectPointMap.end());
2350 return databaseObjectPointMap.find(objectPointId)->second.point();
2351}
2352
2353template <bool tThreadSafe>
2354inline const Vector3& Database::objectPoint(const Index32 objectPointId, Scalar& objectPointPriority) const
2355{
2356 ocean_assert(objectPointId != invalidId);
2357
2359
2360 const ObjectPointMap::const_iterator i = databaseObjectPointMap.find(objectPointId);
2361 ocean_assert(i != databaseObjectPointMap.end());
2362
2363 objectPointPriority = i->second.priority();
2364 return i->second.point();
2365}
2366
2367template <bool tThreadSafe>
2368inline Scalar Database::objectPointPriority(const Index32 objectPointId) const
2369{
2370 ocean_assert(objectPointId != invalidId);
2371
2373
2374 ocean_assert(databaseObjectPointMap.find(objectPointId) != databaseObjectPointMap.end());
2375 return databaseObjectPointMap.find(objectPointId)->second.priority();
2376}
2377
2378template <bool tThreadSafe>
2380{
2382
2384 objectPoints.reserve(databaseObjectPointMap.size());
2385
2386 for (ObjectPointMap::const_iterator i = databaseObjectPointMap.begin(); i != databaseObjectPointMap.end(); ++i)
2387 objectPoints.push_back(i->second.point());
2388
2389 return objectPoints;
2390}
2391
2392template <bool tThreadSafe, bool tMatchPosition>
2393inline Vectors3 Database::objectPoints(const Vector3& referencePosition, Indices32* objectPointIds, const Scalar minimalPriority) const
2394{
2395 ocean_assert(!objectPointIds || objectPointIds->empty());
2396
2398
2400 objectPoints.reserve(databaseObjectPointMap.size());
2401
2402 if (objectPointIds)
2403 {
2404 objectPointIds->clear();
2405 objectPointIds->reserve(databaseObjectPointMap.size());
2406
2407 for (ObjectPointMap::const_iterator i = databaseObjectPointMap.begin(); i != databaseObjectPointMap.end(); ++i)
2408 if (i->second.priority() >= minimalPriority && ((tMatchPosition && i->second.point() == referencePosition) || (!tMatchPosition && i->second.point() != referencePosition)))
2409 {
2410 objectPoints.push_back(i->second.point());
2411 objectPointIds->push_back(i->first);
2412 }
2413 }
2414 else
2415 {
2416 for (ObjectPointMap::const_iterator i = databaseObjectPointMap.begin(); i != databaseObjectPointMap.end(); ++i)
2417 if (i->second.priority() >= minimalPriority && ((tMatchPosition && i->second.point() == referencePosition) || (!tMatchPosition && i->second.point() != referencePosition)))
2418 objectPoints.push_back(i->second.point());
2419 }
2420
2421 return objectPoints;
2422}
2423
2424template <bool tThreadSafe>
2425inline Vectors3 Database::objectPoints(const Indices32& objectPointIds) const
2426{
2428
2430 objectPoints.reserve(objectPointIds.size());
2431
2432 for (Indices32::const_iterator i = objectPointIds.begin(); i != objectPointIds.end(); ++i)
2433 {
2434 ocean_assert(*i != invalidId);
2435 ocean_assert(databaseObjectPointMap.find(*i) != databaseObjectPointMap.end());
2436
2437 objectPoints.push_back(databaseObjectPointMap.find(*i)->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
2449
2450 ocean_assert(databasePoseMap.find(poseId) != databasePoseMap.end());
2451 return databasePoseMap.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
2460
2461 HomogenousMatrices4 result;
2462 result.reserve(size);
2463
2464 for (size_t n = 0; n < size; ++n)
2465 {
2466 ocean_assert(databasePoseMap.find(poseIds[n]) != databasePoseMap.end());
2467 result.push_back(databasePoseMap.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
2479
2480 SquareMatrices3 result;
2481 result.reserve(size);
2482
2483 for (size_t n = 0; n < size; ++n)
2484 {
2485 ocean_assert(databasePoseMap.find(poseIds[n]) != databasePoseMap.end());
2486
2487 const HomogenousMatrix4& pose = databasePoseMap.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
2502
2504 poses.reserve(databasePoseMap.size());
2505
2506 if (poseIds)
2507 {
2508 poseIds->clear();
2509 poseIds->reserve(databasePoseMap.size());
2510
2511 for (PoseMap::const_iterator i = databasePoseMap.begin(); i != databasePoseMap.end(); ++i)
2512 if ((tMatchPose && i->second.pose() == referencePose) || (!tMatchPose && i->second.pose() != referencePose))
2513 {
2514 poses.push_back(i->second.pose());
2515 poseIds->push_back(i->first);
2516 }
2517 }
2518 else
2519 {
2520 for (PoseMap::const_iterator i = databasePoseMap.begin(); i != databasePoseMap.end(); ++i)
2521 if ((tMatchPose && i->second.pose() == referencePose) || (!tMatchPose && i->second.pose() != referencePose))
2522 poses.push_back(i->second.pose());
2523 }
2524
2525 return poses;
2526}
2527
2528template <bool tThreadSafe>
2529inline HomogenousMatrices4 Database::poses(const Index32 lowerPoseId, const Index32 upperPoseId) const
2530{
2531 ocean_assert(lowerPoseId <= upperPoseId);
2532
2534
2536 poses.reserve(upperPoseId - lowerPoseId + 1u);
2537
2538 for (unsigned int n = lowerPoseId; n <= upperPoseId; ++n)
2539 {
2540 // **TODO** the performance can be improved if we iterate through the map
2541 PoseMap::const_iterator i = databasePoseMap.find(n);
2542 if (i != databasePoseMap.end())
2543 poses.push_back(i->second.pose());
2544 else
2545 poses.push_back(HomogenousMatrix4(false));
2546 }
2547
2548 return poses;
2549}
2550
2551template <bool tThreadSafe, bool tMatchPose>
2552inline Indices32 Database::poseIds(const HomogenousMatrix4& referencePose, HomogenousMatrices4* poses) const
2553{
2554 ocean_assert(!poses || poses->empty());
2555
2557
2559 poseIds.reserve(databasePoseMap.size());
2560
2561 if (poses)
2562 {
2563 poses->clear();
2564 poses->reserve(databasePoseMap.size());
2565
2566 for (PoseMap::const_iterator i = databasePoseMap.begin(); i != databasePoseMap.end(); ++i)
2567 if ((tMatchPose && i->second.pose() == referencePose) || (!tMatchPose && i->second.pose() != referencePose))
2568 {
2569 poseIds.push_back(i->first);
2570 poses->push_back(i->second.pose());
2571 }
2572 }
2573 else
2574 {
2575 for (PoseMap::const_iterator i = databasePoseMap.begin(); i != databasePoseMap.end(); ++i)
2576 if ((tMatchPose && i->second.pose() == referencePose) || (!tMatchPose && i->second.pose() != referencePose))
2577 poseIds.push_back(i->first);
2578 }
2579
2580 return poseIds;
2581}
2582
2583template <bool tThreadSafe>
2584inline bool Database::poseBorders(Index32& lowerPoseId, Index32& upperPoseId) const
2585{
2587
2588 if (databasePoseMap.empty())
2589 return false;
2590
2591 lowerPoseId = databasePoseMap.begin()->first;
2592 upperPoseId = databasePoseMap.rbegin()->first;
2593
2594 return true;
2595}
2596
2597template <bool tThreadSafe>
2598inline bool Database::validPoseBorders(Index32& rangeLowerPoseId, Index32& rangeUpperPoseId) const
2599{
2601
2602 if (databasePoseMap.empty())
2603 return false;
2604
2605 rangeLowerPoseId = invalidId;
2606 rangeUpperPoseId = invalidId;
2607
2608 for (PoseMap::const_iterator i = databasePoseMap.begin(); i != databasePoseMap.end(); ++i)
2609 if (i->second.pose().isValid())
2610 {
2611 rangeLowerPoseId = i->first;
2612 break;
2613 }
2614
2615 if (rangeLowerPoseId == invalidId)
2616 return false;
2617
2618 for (PoseMap::const_reverse_iterator i = databasePoseMap.rbegin(); i != databasePoseMap.rend(); ++i)
2619 if (i->second.pose().isValid())
2620 {
2621 rangeUpperPoseId = i->first;
2622 break;
2623 }
2624
2625 ocean_assert(rangeLowerPoseId <= rangeUpperPoseId);
2626 return true;
2627}
2628
2629template <bool tThreadSafe>
2630inline bool Database::validPoseRange(const Index32 lowerPoseId, const Index32 startPoseId, const Index32 upperPoseId, Index32& rangeLowerPoseId, Index32& rangeUpperPoseId) const
2631{
2632 ocean_assert(startPoseId != invalidId);
2633 ocean_assert_and_suppress_unused(lowerPoseId <= startPoseId && startPoseId <= upperPoseId, lowerPoseId);
2634
2636
2637 PoseMap::const_iterator i = databasePoseMap.find(startPoseId);
2638 if (i == databasePoseMap.end() || !(i->second.pose().isValid()))
2639 return false;
2640
2641 rangeLowerPoseId = startPoseId;
2642 rangeUpperPoseId = startPoseId;
2643
2644 for (unsigned int id = startPoseId - 1; id != (unsigned int)(-1); --id)
2645 {
2646 i = databasePoseMap.find(id);
2647
2648 if (i == databasePoseMap.end() || !(i->second.pose().isValid()))
2649 break;
2650
2651 rangeLowerPoseId = id;
2652 }
2653
2654 for (unsigned int id = startPoseId + 1u; id <= upperPoseId; ++id)
2655 {
2656 i = databasePoseMap.find(id);
2657
2658 if (i == databasePoseMap.end() || !(i->second.pose().isValid()))
2659 break;
2660
2661 rangeUpperPoseId = id;
2662 }
2663
2664 return true;
2665}
2666
2667template <bool tThreadSafe>
2668inline bool Database::largestValidPoseRange(const Index32 lowerPoseId, const Index32 upperPoseId, Index32& rangeLowerPoseId, Index32& rangeUpperPoseId) const
2669{
2670 ocean_assert(lowerPoseId <= upperPoseId);
2671
2672 if (lowerPoseId > upperPoseId)
2673 return false;
2674
2676
2677 const HomogenousMatrices4 rangePoses(poses<false>(lowerPoseId, upperPoseId));
2678
2679 unsigned int bestRangeSize = 0u;
2680 unsigned int firstIndex = (unsigned int)(-1);
2681
2682 for (unsigned int n = 0u; n < rangePoses.size(); ++n)
2683 if (firstIndex == (unsigned int)(-1))
2684 {
2685 if (rangePoses[n].isValid())
2686 firstIndex = n;
2687 }
2688 else if (!rangePoses[n].isValid())
2689 {
2690 const unsigned int lastIndex = n - 1u;
2691 ocean_assert(firstIndex >= 0u && lastIndex < (unsigned int)rangePoses.size());
2692
2693 const unsigned int rangeSize = lastIndex - firstIndex + 1u;
2694
2695 if (rangeSize > bestRangeSize)
2696 {
2697 bestRangeSize = rangeSize;
2698 rangeLowerPoseId = firstIndex + lowerPoseId;
2699 rangeUpperPoseId = lastIndex + lowerPoseId;
2700
2701 // check whether the remaining part is too small to be larger than the currently best range
2702 if (rangePoses.size() - n < bestRangeSize)
2703 return true;
2704 }
2705
2706 firstIndex = (unsigned int)(-1);
2707 }
2708
2709 if (firstIndex == (unsigned int)(-1))
2710 return bestRangeSize != 0u;
2711
2712 const unsigned int lastIndex = (unsigned int)rangePoses.size() - 1u;
2713 ocean_assert(firstIndex >= 0u && lastIndex < (unsigned int)rangePoses.size());
2714
2715 const unsigned int rangeSize = lastIndex - firstIndex + 1u;
2716 if (rangeSize > bestRangeSize)
2717 {
2718 rangeLowerPoseId = firstIndex + lowerPoseId;
2719 rangeUpperPoseId = lastIndex + lowerPoseId;
2720
2721 bestRangeSize = rangeSize;
2722 }
2723
2724 ocean_assert(bestRangeSize != 0u);
2725 return true;
2726}
2727
2728template <bool tThreadSafe, bool tMatchPosition, bool tNeedValidPose>
2729inline bool Database::poseWithMostCorrespondences(const Index32 lowerPoseId, const Index32 upperPoseId, Index32* poseId, unsigned int* correspondences, const Vector3& referenceObjectPoint) const
2730{
2731 ocean_assert(lowerPoseId != invalidId && upperPoseId != invalidId);
2732 ocean_assert(lowerPoseId <= upperPoseId);
2733
2735
2736 Index32 bestPoseId = invalidId;
2737 unsigned int bestCorrespondences = 0u;
2738
2739 for (unsigned int id = lowerPoseId; id <= upperPoseId; ++id)
2740 {
2741 const unsigned int value = numberCorrespondences<false, tMatchPosition, tNeedValidPose>(id, referenceObjectPoint);
2742 if (value > bestCorrespondences)
2743 {
2744 bestCorrespondences = value;
2745 bestPoseId = id;
2746 }
2747 }
2748
2749 if (poseId)
2750 *poseId = bestPoseId;
2751
2752 if (correspondences)
2753 *correspondences = bestCorrespondences;
2754
2755 return bestCorrespondences != 0u;
2756}
2757
2758template <bool tThreadSafe, bool tMatchPosition, bool tNeedValidPose>
2759inline bool Database::poseWithLeastCorrespondences(const Index32 lowerPoseId, const Index32 upperPoseId, Index32* poseId, unsigned int* correspondences, const Vector3& referenceObjectPoint) const
2760{
2761 ocean_assert(lowerPoseId != invalidId && upperPoseId != invalidId);
2762 ocean_assert(lowerPoseId <= upperPoseId);
2763
2765
2766 Index32 worstPoseId = invalidId;
2767 unsigned int worstCorrespondences = (unsigned int)(-1);
2768
2770
2771 for (unsigned int id = lowerPoseId; id <= upperPoseId; ++id)
2772 {
2773 if (tNeedValidPose && (!hasPose<false>(id, &pose) || !pose.isValid()))
2774 continue;
2775
2776 const unsigned int value = numberCorrespondences<false, tMatchPosition, false>(id, referenceObjectPoint);
2777 if (value < worstCorrespondences)
2778 {
2779 worstCorrespondences = value;
2780 worstPoseId = id;
2781 }
2782 }
2783
2784 if (poseId)
2785 *poseId = worstPoseId;
2786
2787 if (correspondences)
2788 *correspondences = worstCorrespondences;
2789
2790 return worstCorrespondences != (unsigned int)(-1);
2791}
2792
2793template <bool tThreadSafe>
2794inline bool Database::poseWithMostObservations(const IndexSet32& poseCandidates, const IndexSet32& majorObjectPointIds, const IndexSet32& minorObjectPointIds, Index32& pose, Indices32* visibleMajorObjectPointIds, Indices32* visibleMinorObjectPointIds) const
2795{
2796 ocean_assert(!poseCandidates.empty());
2797 ocean_assert(!majorObjectPointIds.empty());
2798
2799 if (majorObjectPointIds.empty())
2800 return false;
2801
2803
2804 unsigned int bestMajorCount = 0u;
2805 unsigned int bestMinorCount = 0u;
2806
2807 Index32 bestPoseId = invalidId;
2808
2809 for (IndexSet32::const_iterator iP = poseCandidates.begin(); iP != poseCandidates.end(); ++iP)
2810 {
2811 const Index32 poseId = *iP;
2812
2813 unsigned int majorCount = 0u;
2814 unsigned int remaining = (unsigned int)majorObjectPointIds.size();
2815
2816 for (IndexSet32::const_iterator i = majorObjectPointIds.begin(); majorCount + remaining >= bestMajorCount && i != majorObjectPointIds.end(); ++i)
2817 {
2818 if (databasePoseObjectPointMap.find(index64(poseId, *i)) != databasePoseObjectPointMap.end())
2819 majorCount++;
2820
2821 remaining--;
2822 }
2823
2824 if (majorCount >= bestMajorCount)
2825 {
2826 unsigned int minorCount = 0u;
2827 remaining = (unsigned int)minorObjectPointIds.size();
2828
2829 for (IndexSet32::const_iterator i = minorObjectPointIds.begin(); minorCount + remaining >= bestMinorCount && i != minorObjectPointIds.end(); ++i)
2830 {
2831 if (databasePoseObjectPointMap.find(index64(poseId, *i)) != databasePoseObjectPointMap.end())
2832 minorCount++;
2833
2834 remaining--;
2835 }
2836
2837 if (majorCount > bestMajorCount || minorCount > bestMinorCount)
2838 {
2839 bestPoseId = poseId;
2840 bestMajorCount = majorCount;
2841 bestMinorCount = minorCount;
2842 }
2843 }
2844 }
2845
2846 if (bestPoseId == invalidId)
2847 return false;
2848
2849 pose = bestPoseId;
2850
2851 if (visibleMajorObjectPointIds)
2852 {
2853 ocean_assert(visibleMajorObjectPointIds->empty());
2854 visibleMajorObjectPointIds->clear();
2855 visibleMajorObjectPointIds->reserve(bestMajorCount);
2856
2857 for (IndexSet32::const_iterator i = majorObjectPointIds.begin(); i != majorObjectPointIds.end(); ++i)
2858 if (databasePoseObjectPointMap.find(index64(bestPoseId, *i)) != databasePoseObjectPointMap.end())
2859 visibleMajorObjectPointIds->push_back(*i);
2860
2861 ocean_assert(bestMajorCount == visibleMajorObjectPointIds->size());
2862 }
2863
2864 if (visibleMinorObjectPointIds)
2865 {
2866 ocean_assert(visibleMinorObjectPointIds->empty());
2867 visibleMinorObjectPointIds->clear();
2868 visibleMinorObjectPointIds->reserve(minorObjectPointIds.size());
2869
2870 for (IndexSet32::const_iterator i = minorObjectPointIds.begin(); i != minorObjectPointIds.end(); ++i)
2871 if (databasePoseObjectPointMap.find(index64(bestPoseId, *i)) != databasePoseObjectPointMap.end())
2872 visibleMinorObjectPointIds->push_back(*i);
2873
2874 ocean_assert(bestMinorCount == visibleMinorObjectPointIds->size());
2875 }
2876
2877 return true;
2878}
2879
2880template <bool tThreadSafe>
2881inline unsigned int Database::numberObservations(const Index32 poseId, const Indices32& objectPointIds) const
2882{
2883 ocean_assert(poseId != invalidId);
2884
2886
2887 unsigned int number = 0u;
2888
2889 for (Indices32::const_iterator i = objectPointIds.begin(); i != objectPointIds.end(); ++i)
2890 if (databasePoseObjectPointMap.find(index64(poseId, *i)) != databasePoseObjectPointMap.end())
2891 number++;
2892
2893 return number;
2894}
2895
2896template <bool tThreadSafe, bool tMatchPosition, bool tNeedValidPose>
2897inline unsigned int Database::numberCorrespondences(const Index32 poseId, const Vector3& referenceObjectPoint, const Scalar minimalPriority) const
2898{
2899 ocean_assert(poseId != invalidId);
2900
2902
2903 const PoseMap::const_iterator iP = databasePoseMap.find(poseId);
2904 if (iP == databasePoseMap.end() || (tNeedValidPose && !(iP->second.pose().isValid())))
2905 return 0u;
2906
2907 unsigned int count = 0u;
2908
2909 const IndexSet32& imagePointIds = iP->second.imagePointIds();
2910 for (IndexSet32::const_iterator iI = imagePointIds.begin(); iI != imagePointIds.end(); ++iI)
2911 {
2912 const ImagePointMap::const_iterator i = databaseImagePointMap.find(*iI);
2913 ocean_assert(i != databaseImagePointMap.end());
2914
2915 const ObjectPointMap::const_iterator iO = databaseObjectPointMap.find(i->second.objectPointId());
2916 ocean_assert(iO != databaseObjectPointMap.end());
2917
2918 if (iO->second.priority() >= minimalPriority && ((tMatchPosition && iO->second.point() == referenceObjectPoint) || (!tMatchPosition && iO->second.point() != referenceObjectPoint)))
2919 count++;
2920 }
2921
2922 return count;
2923}
2924
2925template <bool tThreadSafe, bool tMatchPosition, bool tNeedValidPose>
2926inline Indices32 Database::numberCorrespondences(const Index32 lowerPoseId, const Index32 upperPoseId, const Vector3& referenceObjectPoint, const Scalar minimalPriority, Worker* worker) const
2927{
2928 ocean_assert(lowerPoseId <= upperPoseId);
2929
2930 const unsigned int frames = upperPoseId - lowerPoseId + 1u;
2931
2933
2934 Indices32 result;
2935
2936 if (worker && frames >= 20u)
2937 {
2938 result.resize(frames);
2939
2940 worker->executeFunction(Worker::Function::create(*this, &Database::numberCorrespondencesSubset<tMatchPosition, tNeedValidPose>, lowerPoseId, &referenceObjectPoint, minimalPriority, result.data(), 0u, 0u), 0u, frames);
2941 }
2942 else
2943 {
2944 result.reserve(frames);
2945
2946 for (unsigned int n = lowerPoseId; n <= upperPoseId; ++n)
2947 result.push_back(numberCorrespondences<false, tMatchPosition, tNeedValidPose>(n, referenceObjectPoint, minimalPriority));
2948 }
2949
2950 return result;
2951}
2952
2953template <bool tThreadSafe>
2954inline bool Database::hasImagePoint(const Index32 imagePointId, Vector2* imagePoint) const
2955{
2957
2958 const ImagePointMap::const_iterator i = databaseImagePointMap.find(imagePointId);
2959
2960 if (i == databaseImagePointMap.end())
2961 return false;
2962
2963 if (imagePoint)
2964 *imagePoint = i->second.point();
2965
2966 return true;
2967}
2968
2969template <bool tThreadSafe>
2970inline Index32 Database::addImagePoint(const Vector2& imagePoint)
2971{
2973
2976}
2977
2978template <bool tThreadSafe>
2979inline void Database::removeImagePoint(const Index32 imagePointId)
2980{
2981 ocean_assert(imagePointId != invalidId);
2982
2984
2985 const ImagePointMap::iterator i = databaseImagePointMap.find(imagePointId);
2986 ocean_assert(i != databaseImagePointMap.end());
2987
2988 // we need to remove all connections of the specified image point
2989 const ImagePointData& data = i->second;
2990
2991 if (data.poseId() != invalidId)
2992 {
2993 PoseMap::iterator iP = databasePoseMap.find(data.poseId());
2994 ocean_assert(iP != databasePoseMap.end());
2995
2996 iP->second.unregisterImagePoint(imagePointId);
2997 }
2998
2999 if (data.objectPointId() != invalidId)
3000 {
3001 ObjectPointMap::iterator iO = databaseObjectPointMap.find(data.objectPointId());
3002 ocean_assert(iO != databaseObjectPointMap.end());
3003
3004 iO->second.unregisterImagePoint(imagePointId);
3005 }
3006
3007 databaseImagePointMap.erase(i);
3008}
3009
3010template <bool tThreadSafe>
3011inline bool Database::hasObjectPoint(const Index32 objectPointId, Vector3* objectPoint) const
3012{
3014
3015 const ObjectPointMap::const_iterator i = databaseObjectPointMap.find(objectPointId);
3016
3017 if (i == databaseObjectPointMap.end())
3018 return false;
3019
3020 if (objectPoint)
3021 *objectPoint = i->second.point();
3022
3023 return true;
3024}
3025
3026template <bool tThreadSafe>
3027inline Index32 Database::addObjectPoint(const Vector3& objectPoint, const Scalar priority)
3028{
3030
3031 ocean_assert(databaseObjectPointMap.find(databaseObjectPointIdCounter + 1u) == databaseObjectPointMap.end() && "You mixed calls with the add-objectPoint-function using external object point ids!");
3032
3035}
3036
3037template <bool tThreadSafe>
3038inline void Database::addObjectPoint(const Index32 objectPointId, const Vector3& objectPoint, const Scalar priority)
3039{
3041
3042 ocean_assert(databaseObjectPointMap.find(objectPointId) == databaseObjectPointMap.end());
3043 ocean_assert((databaseObjectPointIdCounter == invalidId || objectPointId + 1u <= databaseObjectPointIdCounter) && "You mixed calls with the add-objectPoint-function using external object point ids!");
3044
3045 databaseObjectPointMap[objectPointId] = ObjectPointData(objectPoint, priority);
3046}
3047
3048inline Index32 Database::addObjectPointFromDatabase(const Database& secondDatabase, const Index32 secondDatabaseObjectPointId, const SquareMatrix3& imagePointTransformation, const Index32 newObjectPointId, const Index32 secondDatabaseLowerPoseId, const Index32 secondDatabaseUpperPoseId, const bool forExistingPosesOnly)
3049{
3050 ocean_assert(secondDatabase.hasObjectPoint<false>(secondDatabaseObjectPointId));
3051 ocean_assert(!imagePointTransformation.isSingular());
3052 ocean_assert(secondDatabaseLowerPoseId == invalidId || secondDatabaseUpperPoseId == invalidId || secondDatabaseLowerPoseId <= secondDatabaseUpperPoseId);
3053
3054 // first we copy the location of the 3D object point
3055
3057 const Vector3& objectPoint = secondDatabase.objectPoint<false>(secondDatabaseObjectPointId, objectPointPriority);
3058
3059 Index32 thisDatabaseObjectPointId = invalidId;
3060
3061 // we want to ensure that an explicit id of the new object point does not exist in this database
3062 ocean_assert(newObjectPointId == invalidId || hasObjectPoint<false>(newObjectPointId) == false);
3063 if (newObjectPointId != invalidId)
3064 {
3065 if (hasObjectPoint<false>(newObjectPointId))
3066 {
3067 return invalidId;
3068 }
3069
3070 addObjectPoint<false>(newObjectPointId, objectPoint, objectPointPriority);
3071 thisDatabaseObjectPointId = newObjectPointId;
3072 }
3073 else
3074 {
3075 thisDatabaseObjectPointId = addObjectPoint<false>(objectPoint, objectPointPriority);
3076 }
3077
3078 // now we have add the corresponding image points (and ensure that a pose exists in this database)
3079
3080 const IndexSet32& secondDatabaseImagePointIds = secondDatabase.imagePointsFromObjectPoint<false>(secondDatabaseObjectPointId);
3081
3082 for (IndexSet32::const_iterator i = secondDatabaseImagePointIds.cbegin(); i != secondDatabaseImagePointIds.cend(); ++i)
3083 {
3084 const Index32& secondDatabaseImagePointId = *i;
3085
3086 const Index32 poseId = secondDatabase.poseFromImagePoint<false>(secondDatabaseImagePointId);
3087
3088 // the pose id in the second database is identical to the pose id in this database
3089
3090 // we check whether the user had specified a pose range
3091
3092 if ((secondDatabaseLowerPoseId != invalidId && poseId < secondDatabaseLowerPoseId)
3093 || (secondDatabaseUpperPoseId != invalidId && poseId > secondDatabaseUpperPoseId))
3094 {
3095 // the pose id is outside the specified pose range, so we skip this image point (this observation)
3096 continue;
3097 }
3098
3099 if (!hasPose<false>(poseId))
3100 {
3101 if (forExistingPosesOnly)
3102 {
3103 // the user does not want us to create a new pose, so we simply skip this image point (this observation)
3104 continue;
3105 }
3106
3107 // we need to create a pose in this database
3108
3109 const HomogenousMatrix4& pose = secondDatabase.pose<false>(poseId);
3110
3111 const bool addPoseResult = addPose<false>(poseId, pose);
3112 ocean_assert_and_suppress_unused(addPoseResult, addPoseResult);
3113 }
3114
3115 // now, as we know that the pose exists in this database, we simply add the image point and register/connect it with the pose
3116
3117 const Vector2& imagePoint = secondDatabase.imagePoint<false>(secondDatabaseImagePointId);
3118
3119 // we apply the provided transformation before adding the image point to this database
3120
3121 const Index32 thisDatabaseImagePointId = addImagePoint<false>(imagePointTransformation * imagePoint);
3122
3123 attachImagePointToObjectPoint<false>(thisDatabaseImagePointId, thisDatabaseObjectPointId);
3124 attachImagePointToPose<false>(thisDatabaseImagePointId, poseId);
3125 }
3126
3127 return thisDatabaseObjectPointId;
3128}
3129
3130template <bool tThreadSafe>
3131inline void Database::removeObjectPoint(const Index32 objectPointId)
3132{
3133 ocean_assert(objectPointId != invalidId);
3134
3136
3137 const ObjectPointMap::iterator i = databaseObjectPointMap.find(objectPointId);
3138 ocean_assert(i != databaseObjectPointMap.end());
3139
3140 // we need to remove all connections of the specified object point
3141
3142 const ObjectPointData& data = i->second;
3143
3144 for (IndexSet32::const_iterator iI = data.imagePointIds().begin(); iI != data.imagePointIds().end(); ++iI)
3145 {
3146 ImagePointMap::iterator iP = databaseImagePointMap.find(*iI);
3147 ocean_assert(iP != databaseImagePointMap.end());
3148
3149 if (iP->second.poseId() != invalidId)
3150 {
3151 ocean_assert(databasePoseObjectPointMap.find(index64(iP->second.poseId(), objectPointId)) != databasePoseObjectPointMap.end());
3152 databasePoseObjectPointMap.erase(index64(iP->second.poseId(), objectPointId));
3153 }
3154
3155 iP->second.setObjectPointId(invalidId);
3156 }
3157
3158 databaseObjectPointMap.erase(i);
3159}
3160
3161template <bool tThreadSafe>
3163{
3164 ocean_assert(objectPointId != invalidId);
3165
3167
3168 const ObjectPointMap::iterator iObjectPoint = databaseObjectPointMap.find(objectPointId);
3169 ocean_assert(iObjectPoint != databaseObjectPointMap.cend());
3170
3171 // we need to remove all connections of the specified object point
3172
3173 const ObjectPointData& objectPointData = iObjectPoint->second;
3174
3175 for (const Index32& imagePointId : objectPointData.imagePointIds())
3176 {
3177 const ImagePointMap::iterator iImagePoint = databaseImagePointMap.find(imagePointId);
3178 ocean_assert(iImagePoint != databaseImagePointMap.cend());
3179
3180 if (iImagePoint->second.poseId() != invalidId)
3181 {
3182 ocean_assert(databasePoseObjectPointMap.find(index64(iImagePoint->second.poseId(), objectPointId)) != databasePoseObjectPointMap.cend());
3183 databasePoseObjectPointMap.erase(index64(iImagePoint->second.poseId(), objectPointId));
3184 }
3185
3186 const Index32 poseId = iImagePoint->second.poseId();
3187
3188 PoseMap::iterator iPose = databasePoseMap.find(poseId);
3189 ocean_assert(iPose != databasePoseMap.cend());
3190
3191 iPose->second.unregisterImagePoint(imagePointId);
3192
3193 databaseImagePointMap.erase(iImagePoint);
3194 }
3195
3196 databaseObjectPointMap.erase(iObjectPoint);
3197}
3198
3199template <bool tThreadSafe>
3200inline void Database::renameObjectPoint(const Index32 oldObjectPointId, const Index32 newObjectPointId)
3201{
3202 ocean_assert(oldObjectPointId != invalidId && newObjectPointId != invalidId);
3203
3205
3206 ocean_assert(databaseObjectPointMap.find(newObjectPointId) == databaseObjectPointMap.end());
3207
3208 ObjectPointMap::iterator iOld = databaseObjectPointMap.find(oldObjectPointId);
3209 ocean_assert(iOld != databaseObjectPointMap.end());
3210
3211 const IndexSet32& imagePointIds = iOld->second.imagePointIds();
3212
3213 for (IndexSet32::const_iterator iI = imagePointIds.begin(); iI != imagePointIds.end(); ++iI)
3214 {
3215 ImagePointMap::iterator iIData = databaseImagePointMap.find(*iI);
3216 ocean_assert(iIData != databaseImagePointMap.end());
3217
3218 ocean_assert(iIData->second.objectPointId() == oldObjectPointId);
3219 iIData->second.setObjectPointId(newObjectPointId);
3220
3221 ocean_assert(databasePoseObjectPointMap.find(index64(iIData->second.poseId(), oldObjectPointId)) != databasePoseObjectPointMap.end());
3222 databasePoseObjectPointMap.erase(index64(iIData->second.poseId(), oldObjectPointId));
3223
3224 ocean_assert(databasePoseObjectPointMap.find(index64(iIData->second.poseId(), newObjectPointId)) == databasePoseObjectPointMap.end());
3225 databasePoseObjectPointMap.insert(std::make_pair(index64(iIData->second.poseId(), newObjectPointId), newObjectPointId));
3226 }
3227
3228 databaseObjectPointMap.insert(std::make_pair(newObjectPointId, std::move(iOld->second)));
3229 databaseObjectPointMap.erase(iOld);
3230}
3231
3232template <bool tThreadSafe>
3233inline void Database::mergeObjectPoints(const Index32 remainingObjectPointId, const Index32 removingObjectPointId, const Vector3& newPoint, const Scalar newPriority)
3234{
3235 ocean_assert(remainingObjectPointId != invalidId && removingObjectPointId != invalidId && remainingObjectPointId != removingObjectPointId);
3236
3238
3239 ObjectPointMap::iterator iObjectPointRemaining = databaseObjectPointMap.find(remainingObjectPointId);
3240 ocean_assert(iObjectPointRemaining != databaseObjectPointMap.cend());
3241
3242 ObjectPointMap::const_iterator iObjectPointRemoving = databaseObjectPointMap.find(removingObjectPointId);
3243 ocean_assert(iObjectPointRemoving != databaseObjectPointMap.cend());
3244
3245#ifdef OCEAN_DEBUG
3246 const IndexSet32 debugPoseIdsRemaining = posesFromObjectPoint<false>(remainingObjectPointId);
3247 const IndexSet32 debugPoseIdsRemoving = posesFromObjectPoint<false>(removingObjectPointId);
3248 ocean_assert(!Subset::hasIntersectingElement(debugPoseIdsRemaining, debugPoseIdsRemoving));
3249#endif
3250
3251 for (const Index32& imagePointIdRemoving : iObjectPointRemoving->second.imagePointIds())
3252 {
3253 iObjectPointRemaining->second.registerImagePoint(imagePointIdRemoving);
3254
3255 ImagePointMap::iterator iImagePointRemoving = databaseImagePointMap.find(imagePointIdRemoving);
3256 ocean_assert(iImagePointRemoving != databaseImagePointMap.cend());
3257
3258 const Index32 poseIdRemoving = iImagePointRemoving->second.poseId();
3259
3260 ocean_assert(databasePoseObjectPointMap.find(index64(poseIdRemoving, removingObjectPointId)) != databasePoseObjectPointMap.cend());
3261 databasePoseObjectPointMap.erase(index64(poseIdRemoving, removingObjectPointId));
3262
3263 ocean_assert(databasePoseObjectPointMap.find(index64(poseIdRemoving, remainingObjectPointId)) == databasePoseObjectPointMap.cend());
3264 databasePoseObjectPointMap.emplace(index64(poseIdRemoving, remainingObjectPointId), imagePointIdRemoving);
3265
3266 iImagePointRemoving->second.setObjectPointId(remainingObjectPointId);
3267 }
3268
3269 iObjectPointRemaining->second.setPoint(newPoint);
3270 iObjectPointRemaining->second.setPriority(newPriority);
3271
3272 databaseObjectPointMap.erase(iObjectPointRemoving);
3273}
3274
3275template <bool tThreadSafe>
3276inline bool Database::hasPose(const Index32 poseId, HomogenousMatrix4* pose) const
3277{
3278 ocean_assert(poseId != invalidId);
3279
3281
3282 const PoseMap::const_iterator i = databasePoseMap.find(poseId);
3283 if (i == databasePoseMap.end())
3284 return false;
3285
3286 if (pose)
3287 *pose = i->second.pose();
3288
3289 return true;
3290}
3291
3292template <bool tThreadSafe>
3293inline bool Database::addPose(const Index32 poseId, const HomogenousMatrix4& pose)
3294{
3296
3297 const PoseMap::const_iterator i = databasePoseMap.find(poseId);
3298 if (i != databasePoseMap.end())
3299 {
3300 ocean_assert(false && "Invalid pose id!");
3301 return false;
3302 }
3303
3304 databasePoseMap.insert(std::make_pair(poseId, PoseData(pose)));
3305
3306 databasePoses = max(databasePoses, poseId + 1u);
3307
3308 return true;
3309}
3310
3311template <bool tThreadSafe>
3312inline void Database::removePose(const Index32 poseId)
3313{
3314 ocean_assert(poseId != invalidId);
3315
3317
3318 const PoseMap::iterator i = databasePoseMap.find(poseId);
3319 ocean_assert(i != databasePoseMap.end());
3320
3321 // we need to remove all connections of the specified pose
3322
3323 const PoseData& data = i->second;
3324
3325 for (IndexSet32::const_iterator iI = data.imagePointIds().begin(); iI != data.imagePointIds().end(); ++iI)
3326 {
3327 ImagePointMap::iterator iP = databaseImagePointMap.find(*iI);
3328 ocean_assert(iP != databaseImagePointMap.end());
3329
3330 iP->second.setPoseId(invalidId);
3331 }
3332
3333 databasePoseMap.erase(i);
3334}
3335
3336template <bool tThreadSafe>
3337inline Index32 Database::poseFromImagePoint(const Index32 imagePointId) const
3338{
3339 ocean_assert(imagePointId != invalidId);
3340
3342
3343 const ImagePointMap::const_iterator i = databaseImagePointMap.find(imagePointId);
3344 ocean_assert(i != databaseImagePointMap.end());
3345
3346 return i->second.poseId();
3347}
3348
3349template <bool tThreadSafe>
3350inline size_t Database::numberImagePointsFromObjectPoint(const Index32 objectPointId) const
3351{
3352 ocean_assert(objectPointId != invalidId);
3353
3355
3356 const ObjectPointMap::const_iterator iO = databaseObjectPointMap.find(objectPointId);
3357 ocean_assert(iO != databaseObjectPointMap.end());
3358
3359 const IndexSet32& ids = iO->second.imagePointIds();
3360
3361 return ids.size();
3362}
3363
3364template <bool tThreadSafe>
3365inline void Database::observationsFromObjectPoint(const Index32 objectPointId, Indices32& poseIds, Indices32& imagePointIds, Vectors2* imagePoints) const
3366{
3367 ocean_assert(objectPointId != invalidId);
3368 ocean_assert(poseIds.empty() && imagePointIds.empty());
3369 ocean_assert(imagePoints == nullptr || imagePoints->empty());
3370
3372
3373 const ObjectPointMap::const_iterator iO = databaseObjectPointMap.find(objectPointId);
3374 ocean_assert(iO != databaseObjectPointMap.end());
3375
3376 const IndexSet32& ids = iO->second.imagePointIds();
3377
3378 poseIds.reserve(ids.size());
3379 imagePointIds.reserve(ids.size());
3380
3381 if (imagePoints)
3382 imagePoints->reserve(ids.size());
3383
3384 for (IndexSet32::const_iterator i = ids.begin(); i != ids.end(); ++i)
3385 {
3386 const ImagePointMap::const_iterator iI = databaseImagePointMap.find(*i);
3387 ocean_assert(iI != databaseImagePointMap.end());
3388
3389 if (iI->second.poseId() != invalidId)
3390 {
3391 poseIds.push_back(iI->second.poseId());
3392 imagePointIds.push_back(*i);
3393
3394 if (imagePoints)
3395 imagePoints->push_back(iI->second.point());
3396 }
3397 }
3398}
3399
3400template <bool tThreadSafe>
3401inline void Database::observationsFromObjectPoint(const Index32 objectPointId, const Indices32& poseIdCandidates, Indices32& validPoseIndices, Indices32* imagePointIds, Vectors2* imagePoints) const
3402{
3403 ocean_assert(objectPointId != invalidId);
3404 ocean_assert(!poseIdCandidates.empty() && validPoseIndices.empty());
3405
3406 ocean_assert(imagePointIds == nullptr || imagePointIds->empty());
3407 ocean_assert(imagePoints == nullptr || imagePoints->empty());
3408
3410
3411 for (size_t n = 0; n < poseIdCandidates.size(); ++n)
3412 {
3413 const Index32 poseId = poseIdCandidates[n];
3414
3415 const Index64To32Map::const_iterator i = databasePoseObjectPointMap.find(index64(poseId, objectPointId));
3416
3417 if (i != databasePoseObjectPointMap.end())
3418 {
3419 validPoseIndices.push_back((unsigned int)n);
3420
3421 if (imagePointIds)
3422 imagePointIds->push_back(i->second);
3423
3424 if (imagePoints)
3425 {
3426 ocean_assert(databaseImagePointMap.find(i->second) != databaseImagePointMap.end());
3427 imagePoints->push_back(databaseImagePointMap.find(i->second)->second.point());
3428 }
3429 }
3430 }
3431}
3432
3433template <bool tThreadSafe>
3435{
3436 ocean_assert(imagePointId != invalidId);
3437
3439
3440 const ImagePointMap::const_iterator i = databaseImagePointMap.find(imagePointId);
3441 ocean_assert(i != databaseImagePointMap.end());
3442
3443 return i->second.objectPointId();
3444}
3445
3446template <bool tThreadSafe>
3447inline const IndexSet32& Database::imagePointsFromPose(const Index32 poseId) const
3448{
3449 ocean_assert(poseId != invalidId);
3450
3452
3453 const PoseMap::const_iterator i = databasePoseMap.find(poseId);
3454 ocean_assert(i != databasePoseMap.end());
3455
3456 return i->second.imagePointIds();
3457}
3458
3459template <bool tThreadSafe>
3460inline const IndexSet32& Database::imagePointsFromObjectPoint(const Index32 objectPointId) const
3461{
3462 ocean_assert(objectPointId != invalidId);
3463
3465
3466 const ObjectPointMap::const_iterator i = databaseObjectPointMap.find(objectPointId);
3467 ocean_assert(i != databaseObjectPointMap.cend());
3468
3469 return i->second.imagePointIds();
3470}
3471
3472template <bool tThreadSafe>
3473inline IndexSet32 Database::posesFromObjectPoint(const Index32 objectPointId) const
3474{
3475 ocean_assert(objectPointId != invalidId);
3476
3478
3479 const ObjectPointMap::const_iterator iObjectPoint = databaseObjectPointMap.find(objectPointId);
3480 ocean_assert(iObjectPoint != databaseObjectPointMap.cend());
3481
3482 IndexSet32 result;
3483
3484 for (const Index32& imagePointId : iObjectPoint->second.imagePointIds())
3485 {
3486 const ImagePointMap::const_iterator iImagePoint = databaseImagePointMap.find(imagePointId);
3487 ocean_assert(iImagePoint != databaseImagePointMap.cend());
3488
3489 result.emplace(iImagePoint->second.poseId());
3490 }
3491
3492 return result;
3493}
3494
3495template <bool tThreadSafe>
3496inline void Database::attachImagePointToObjectPoint(const Index32 imagePointId, const Index32 objectPointId)
3497{
3498 ocean_assert(imagePointId != invalidId && objectPointId != invalidId);
3499
3501
3502 ImagePointMap::iterator iI = databaseImagePointMap.find(imagePointId);
3503 ocean_assert(iI != databaseImagePointMap.end());
3504 ocean_assert(iI->second.objectPointId() == invalidId);
3505
3506 iI->second.setObjectPointId(objectPointId);
3507
3508 ObjectPointMap::iterator iO = databaseObjectPointMap.find(objectPointId);
3509 ocean_assert(iO != databaseObjectPointMap.end());
3510
3511 iO->second.registerImagePoint(imagePointId);
3512
3513 if (iI->second.poseId() != invalidId)
3514 {
3515 const Index64 poseObjectPointId(index64(iI->second.poseId(), objectPointId));
3516
3517 ocean_assert(databasePoseObjectPointMap.find(poseObjectPointId) == databasePoseObjectPointMap.end());
3518 databasePoseObjectPointMap.insert(std::make_pair(poseObjectPointId, imagePointId));
3519 }
3520}
3521
3522template <bool tThreadSafe>
3524{
3525 ocean_assert(imagePointId != invalidId);
3526
3528
3529 ImagePointMap::iterator iI = databaseImagePointMap.find(imagePointId);
3530 ocean_assert(iI != databaseImagePointMap.end());
3531
3532 const Index32 objectPointId = iI->second.objectPointId();
3533 ocean_assert(objectPointId != invalidId);
3534
3535 iI->second.setObjectPointId(invalidId);
3536
3537 ObjectPointMap::iterator iO = databaseObjectPointMap.find(objectPointId);
3538 ocean_assert(iO != databaseObjectPointMap.end());
3539
3540 iO->second.unregisterImagePoint(imagePointId);
3541
3542 if (iI->second.poseId() != invalidId)
3543 {
3544 const Index64 poseObjectPointId(index64(iI->second.poseId(), objectPointId));
3545
3546 ocean_assert(databasePoseObjectPointMap.find(poseObjectPointId) != databasePoseObjectPointMap.end());
3547 databasePoseObjectPointMap.erase(poseObjectPointId);
3548 }
3549}
3550
3551template <bool tThreadSafe>
3552inline void Database::attachImagePointToPose(const Index32 imagePointId, const Index32 poseId)
3553{
3554 ocean_assert(imagePointId != invalidId && poseId != invalidId);
3555
3557
3558 ImagePointMap::iterator iI = databaseImagePointMap.find(imagePointId);
3559 ocean_assert(iI != databaseImagePointMap.end());
3560 ocean_assert(iI->second.poseId() == invalidId);
3561
3562 iI->second.setPoseId(poseId);
3563
3564 PoseMap::iterator iP = databasePoseMap.find(poseId);
3565 ocean_assert(iP != databasePoseMap.end());
3566
3567 iP->second.registerImagePoint(imagePointId);
3568
3569 if (iI->second.objectPointId() != invalidId)
3570 {
3571 const Index64 poseObjectPointId(index64(poseId, iI->second.objectPointId()));
3572
3573 ocean_assert(databasePoseObjectPointMap.find(poseObjectPointId) == databasePoseObjectPointMap.end());
3574 databasePoseObjectPointMap.insert(std::make_pair(poseObjectPointId, imagePointId));
3575 }
3576}
3577
3578template <bool tThreadSafe>
3579inline void Database::detachImagePointFromPose(const Index32 imagePointId)
3580{
3581 ocean_assert(imagePointId != invalidId);
3582
3584
3585 ImagePointMap::iterator iI = databaseImagePointMap.find(imagePointId);
3586 ocean_assert(iI != databaseImagePointMap.end());
3587
3588 const Index32 poseId = iI->second.poseId();
3589 ocean_assert(poseId != invalidId);
3590
3591 iI->second.setPoseId(invalidId);
3592
3593 PoseMap::iterator iP = databasePoseMap.find(poseId);
3594 ocean_assert(iP != databasePoseMap.end());
3595
3596 iP->second.unregisterImagePoint(imagePointId);
3597
3598 if (iI->second.objectPointId() != invalidId)
3599 {
3600 const Index64 poseObjectPointId(index64(poseId, iI->second.objectPointId()));
3601
3602 ocean_assert(databasePoseObjectPointMap.find(poseObjectPointId) != databasePoseObjectPointMap.end());
3603 databasePoseObjectPointMap.erase(poseObjectPointId);
3604 }
3605}
3606
3607template <bool tThreadSafe>
3608inline void Database::setImagePoint(const Index32 imagePointId, const Vector2& imagePoint)
3609{
3610 ocean_assert(imagePointId != invalidId);
3611
3613
3614 const ImagePointMap::iterator i = databaseImagePointMap.find(imagePointId);
3615 ocean_assert(i != databaseImagePointMap.end());
3616
3617 i->second.setPoint(imagePoint);
3618}
3619
3620template <bool tThreadSafe>
3621inline void Database::setObjectPoint(const Index32 objectPointId, const Vector3& objectPoint)
3622{
3623 ocean_assert(objectPointId != invalidId);
3624
3626
3627 const ObjectPointMap::iterator i = databaseObjectPointMap.find(objectPointId);
3628 ocean_assert(i != databaseObjectPointMap.end());
3629
3630 i->second.setPoint(objectPoint);
3631}
3632
3633template <bool tThreadSafe>
3634inline void Database::setObjectPoints(const Index32* objectPointIds, const Vector3* objectPoints, const size_t number)
3635{
3636 ocean_assert(objectPointIds && objectPoints);
3637
3639
3640 for (size_t n = 0; n < number; ++ n)
3641 {
3642 const ObjectPointMap::iterator i = databaseObjectPointMap.find(objectPointIds[n]);
3643 ocean_assert(i != databaseObjectPointMap.end());
3644
3645 i->second.setPoint(objectPoints[n]);
3646 }
3647}
3648
3649template <bool tThreadSafe>
3650inline void Database::setObjectPoints(const Index32* objectPointIds, const size_t number, const Vector3& referenceObjectPoint)
3651{
3652 ocean_assert(objectPointIds);
3653
3655
3656 for (size_t n = 0; n < number; ++ n)
3657 {
3658 const ObjectPointMap::iterator i = databaseObjectPointMap.find(objectPointIds[n]);
3659 ocean_assert(i != databaseObjectPointMap.end());
3660
3661 i->second.setPoint(referenceObjectPoint);
3662 }
3663}
3664
3665template <bool tThreadSafe>
3666inline void Database::setObjectPoints(const Vector3& objectPoint)
3667{
3669
3670 for (ObjectPointMap::iterator i = databaseObjectPointMap.begin(); i != databaseObjectPointMap.end(); ++i)
3671 i->second.setPoint(objectPoint);
3672}
3673
3674template <bool tThreadSafe>
3675inline void Database::setObjectPoint(const Index32 objectPointId, const Vector3& objectPoint, const Scalar priority)
3676{
3677 ocean_assert(objectPointId != invalidId);
3678
3680
3681 const ObjectPointMap::iterator i = databaseObjectPointMap.find(objectPointId);
3682 ocean_assert(i != databaseObjectPointMap.end());
3683
3684 i->second.setPoint(objectPoint);
3685 i->second.setPriority(priority);
3686}
3687
3688template <bool tThreadSafe>
3689inline void Database::setObjectPointPriority(const Index32 objectPointId, const Scalar priority)
3690{
3691 ocean_assert(objectPointId != invalidId);
3692
3694
3695 const ObjectPointMap::iterator i = databaseObjectPointMap.find(objectPointId);
3696 ocean_assert(i != databaseObjectPointMap.end());
3697
3698 i->second.setPriority(priority);
3699}
3700
3701template <bool tThreadSafe>
3702inline void Database::setPose(const Index32 poseId, const HomogenousMatrix4& pose)
3703{
3704 ocean_assert(poseId != invalidId);
3705
3707
3708 const PoseMap::iterator i = databasePoseMap.find(poseId);
3709 ocean_assert(i != databasePoseMap.end());
3710
3711 i->second.setPose(pose);
3712}
3713
3714template <bool tThreadSafe>
3715inline void Database::setPoses(const Index32* poseIds, const HomogenousMatrix4* poses, const size_t number)
3716{
3717 ocean_assert(poseIds && poses);
3718
3720
3721 for (size_t n = 0; n < number; ++n)
3722 {
3723 const PoseMap::iterator i = databasePoseMap.find(poseIds[n]);
3724 ocean_assert(i != databasePoseMap.end());
3725
3726 i->second.setPose(poses[n]);
3727 }
3728}
3729
3730template <bool tThreadSafe>
3732{
3734
3735 for (ShiftVector<HomogenousMatrix4>::Index n = poses.firstIndex(); n < poses.endIndex(); ++n)
3736 {
3737 ocean_assert(n >= 0);
3738 const unsigned int poseId = (unsigned int)n;
3739
3740 const PoseMap::iterator i = databasePoseMap.find(poseId);
3741 ocean_assert(i != databasePoseMap.end());
3742
3743 i->second.setPose(poses[n]);
3744 }
3745}
3746
3747template <bool tThreadSafe>
3749{
3751
3752 for (PoseMap::iterator i = databasePoseMap.begin(); i != databasePoseMap.end(); ++i)
3753 i->second.setPose(pose);
3754}
3755
3756template <bool tThreadSafe>
3758{
3759 ocean_assert(poseId != invalidId);
3760
3762
3763 const PoseMap::const_iterator i = databasePoseMap.find(poseId);
3764 ocean_assert(i != databasePoseMap.end());
3765
3766 return i->second.imagePointIds();
3767}
3768
3769template <bool tThreadSafe>
3770inline Indices32 Database::imagePointIds(const Index32 poseId, Indices32& objectPointIds) const
3771{
3772 ocean_assert(poseId != invalidId);
3773 ocean_assert(!objectPointIds.empty());
3774
3776
3777 Indices32 ids;
3778 ids.reserve(objectPointIds.size());
3779
3780 Indices32 validObjectPointIds;
3781 validObjectPointIds.reserve(objectPointIds.size());
3782
3783 for (Indices32::const_iterator i = objectPointIds.begin(); i != objectPointIds.end(); ++i)
3784 {
3785 const Index64To32Map::const_iterator iPO = databasePoseObjectPointMap.find(index64(poseId, *i));
3786
3787 if (iPO != databasePoseObjectPointMap.end())
3788 {
3789 ocean_assert(databaseImagePointMap.find(iPO->second) != databaseImagePointMap.end());
3790
3791 ids.push_back(iPO->second);
3792 validObjectPointIds.push_back(*i);
3793 }
3794 }
3795
3796 objectPointIds = std::move(validObjectPointIds);
3797 return ids;
3798}
3799
3800template <bool tThreadSafe>
3802{
3804
3805 Indices32 result;
3806 result.reserve(databaseImagePointMap.size());
3807
3808 if (imagePoints != nullptr)
3809 {
3810 for (ImagePointMap::const_iterator i = databaseImagePointMap.cbegin(); i != databaseImagePointMap.cend(); ++i)
3811 {
3812 result.emplace_back(i->first);
3813
3814 imagePoints->emplace_back(i->second.point());
3815 }
3816 }
3817 else
3818 {
3819 for (ImagePointMap::const_iterator i = databaseImagePointMap.cbegin(); i != databaseImagePointMap.cend(); ++i)
3820 {
3821 result.emplace_back(i->first);
3822 }
3823 }
3824
3825 return result;
3826}
3827
3828template <bool tThreadSafe>
3829Indices32 Database::objectPointIds(Vectors3* objectPoints, Scalars* priorities) const
3830{
3832
3833 Indices32 result;
3834 result.reserve(databaseObjectPointMap.size());
3835
3836 if (objectPoints != nullptr)
3837 {
3838 objectPoints->clear();
3839 objectPoints->reserve(databaseObjectPointMap.size());
3840
3841 for (ObjectPointMap::const_iterator i = databaseObjectPointMap.cbegin(); i != databaseObjectPointMap.cend(); ++i)
3842 {
3843 result.emplace_back(i->first);
3844
3845 objectPoints->emplace_back(i->second.point());
3846 }
3847 }
3848 else
3849 {
3850 for (ObjectPointMap::const_iterator i = databaseObjectPointMap.cbegin(); i != databaseObjectPointMap.cend(); ++i)
3851 {
3852 result.emplace_back(i->first);
3853 }
3854 }
3855
3856 if (priorities != nullptr)
3857 {
3858 priorities->clear();
3859 priorities->reserve(databaseObjectPointMap.size());
3860
3861 for (ObjectPointMap::const_iterator i = databaseObjectPointMap.cbegin(); i != databaseObjectPointMap.cend(); ++i)
3862 {
3863 priorities->emplace_back(i->second.priority());
3864 }
3865 }
3866
3867 return result;
3868}
3869
3870template <bool tThreadSafe>
3871Indices32 Database::objectPointIds(const IndexSet32& outlierObjectPointIds) const
3872{
3873 if (outlierObjectPointIds.empty())
3874 return objectPointIds<tThreadSafe>();
3875
3877
3878 Indices32 result;
3879 result.reserve(databaseObjectPointMap.size());
3880
3881 for (ObjectPointMap::const_iterator i = databaseObjectPointMap.begin(); i != databaseObjectPointMap.end(); ++i)
3882 if (outlierObjectPointIds.find(i->first) == outlierObjectPointIds.end())
3883 result.push_back(i->first);
3884
3885 return result;
3886}
3887
3888template <bool tThreadSafe>
3890{
3892
3893 Indices32 result;
3894 result.reserve(databasePoseMap.size());
3895
3896 if (world_T_cameras != nullptr)
3897 {
3898 world_T_cameras->clear();
3899 world_T_cameras->reserve(databasePoseMap.size());
3900
3901 for (PoseMap::const_iterator i = databasePoseMap.cbegin(); i != databasePoseMap.cend(); ++i)
3902 {
3903 result.emplace_back(i->first);
3904
3905 world_T_cameras->emplace_back(i->second.pose());
3906 }
3907 }
3908 else
3909 {
3910 for (PoseMap::const_iterator i = databasePoseMap.cbegin(); i != databasePoseMap.cend(); ++i)
3911 {
3912 result.emplace_back(i->first);
3913 }
3914 }
3915
3916 return result;
3917}
3918
3919template <bool tThreadSafe>
3920Vectors2 Database::imagePoints(const Index32 poseId, Indices32* imagePointIds) const
3921{
3922 ocean_assert(poseId != invalidId);
3923 ocean_assert(imagePointIds == nullptr || imagePointIds->empty());
3924
3926
3927 const PoseMap::const_iterator iP = databasePoseMap.find(poseId);
3928 ocean_assert(iP != databasePoseMap.end());
3929
3930 Vectors2 result;
3931 result.reserve(iP->second.imagePointIds().size());
3932
3933 if (imagePointIds)
3934 imagePointIds->reserve(iP->second.imagePointIds().size());
3935
3936 for (IndexSet32::const_iterator i = iP->second.imagePointIds().begin(); i != iP->second.imagePointIds().end(); ++i)
3937 {
3938 ocean_assert(*i != invalidId);
3939
3940 const ImagePointMap::const_iterator iI = databaseImagePointMap.find(*i);
3941 ocean_assert(iI != databaseImagePointMap.end());
3942
3943 result.push_back(iI->second.point());
3944
3945 if (imagePointIds)
3946 imagePointIds->push_back(*i);
3947 }
3948
3949 return result;
3950}
3951
3952template <bool tThreadSafe, bool tMatchPosition>
3953Indices32 Database::objectPointIds(const Vector3& referencePosition, Vectors3* objectPoints, const Scalar minimalPriority) const
3954{
3956
3958
3959 if (objectPoints)
3960 {
3961 ocean_assert(objectPoints->empty());
3962 objectPoints->clear();
3963
3964 for (ObjectPointMap::const_iterator i = databaseObjectPointMap.begin(); i != databaseObjectPointMap.end(); ++i)
3965 if (i->second.priority() >= minimalPriority && ((tMatchPosition && i->second.point() == referencePosition) || (!tMatchPosition && i->second.point() != referencePosition)))
3966 {
3967 objectPointIds.push_back(i->first);
3968 objectPoints->push_back(i->second.point());
3969 }
3970 }
3971 else
3972 {
3973 for (ObjectPointMap::const_iterator i = databaseObjectPointMap.begin(); i != databaseObjectPointMap.end(); ++i)
3974 if (i->second.priority() >= minimalPriority && ((tMatchPosition && i->second.point() == referencePosition) || (!tMatchPosition && i->second.point() != referencePosition)))
3975 objectPointIds.push_back(i->first);
3976 }
3977
3978 return objectPointIds;
3979}
3980
3981template <bool tThreadSafe, bool tMatchPosition>
3982Indices32 Database::objectPointIds(const IndexSet32& outlierObjectPointIds, const Vector3& referencePosition, Vectors3* objectPoints, const Scalar minimalPriority) const
3983{
3985
3987
3988 if (objectPoints)
3989 {
3990 ocean_assert(objectPoints->empty());
3991 objectPoints->clear();
3992
3993 for (ObjectPointMap::const_iterator i = databaseObjectPointMap.begin(); i != databaseObjectPointMap.end(); ++i)
3994 if (i->second.priority() >= minimalPriority && ((tMatchPosition && i->second.point() == referencePosition) || (!tMatchPosition && i->second.point() != referencePosition))
3995 && outlierObjectPointIds.find(i->first) == outlierObjectPointIds.end())
3996 {
3997 objectPointIds.push_back(i->first);
3998 objectPoints->push_back(i->second.point());
3999 }
4000 }
4001 else
4002 {
4003 for (ObjectPointMap::const_iterator i = databaseObjectPointMap.begin(); i != databaseObjectPointMap.end(); ++i)
4004 if (i->second.priority() >= minimalPriority && ((tMatchPosition && i->second.point() == referencePosition) || (!tMatchPosition && i->second.point() != referencePosition))
4005 && outlierObjectPointIds.find(i->first) == outlierObjectPointIds.end())
4006 objectPointIds.push_back(i->first);
4007 }
4008
4009 return objectPointIds;
4010}
4011
4012template <bool tThreadSafe, bool tMatchPosition>
4013inline IndexPairs32 Database::objectPointIdsWithNumberOfObservations(const Vector3& referencePosition, const Scalar minimalPriority, Worker* worker) const
4014{
4016
4018 objectPointIds.reserve(databaseObjectPointMap.size());
4019
4020 for (ObjectPointMap::const_iterator i = databaseObjectPointMap.begin(); i != databaseObjectPointMap.end(); ++i)
4021 objectPointIds.push_back(i->first);
4022
4023 IndexPairs32 result;
4024 result.reserve(objectPointIds.size());
4025
4026 if (worker)
4027 {
4028 Lock lock;
4029 worker->executeFunction(Worker::Function::create(*this, &Database::objectPointIdsWithNumberOfObservationsSubset<tMatchPosition>, (const Index32*)objectPointIds.data(), &referencePosition, minimalPriority, &result, &lock, 0u, 0u), 0u, (unsigned int)objectPointIds.size());
4030 }
4031 else
4032 objectPointIdsWithNumberOfObservationsSubset<tMatchPosition>((const Index32*)objectPointIds.data(), &referencePosition, minimalPriority, &result, nullptr, 0u, (unsigned int)objectPointIds.size());
4033
4034 return result;
4035}
4036
4037template <bool tThreadSafe>
4038Indices32 Database::objectPointIds(const Index32 poseId, Vectors3* objectPoints) const
4039{
4040 ocean_assert(poseId != invalidId);
4041 ocean_assert(objectPoints == nullptr || objectPoints->empty());
4042
4044
4045 const PoseMap::const_iterator iP = databasePoseMap.find(poseId);
4046 ocean_assert(iP != databasePoseMap.end());
4047
4048 const IndexSet32& imagePointIds = iP->second.imagePointIds();
4049
4050 Indices32 result;
4051 result.reserve(imagePointIds.size());
4052
4053 if (objectPoints)
4054 objectPoints->reserve(imagePointIds.size());
4055
4056 for (IndexSet32::const_iterator i = imagePointIds.begin(); i != imagePointIds.end(); ++i)
4057 {
4058 ocean_assert(*i != invalidId);
4059
4060 const ImagePointMap::const_iterator iI = databaseImagePointMap.find(*i);
4061 ocean_assert(iI != databaseImagePointMap.end());
4062
4063 const Index32 objectPointId = iI->second.objectPointId();
4064
4065 if (objectPointId != invalidId)
4066 {
4067 result.push_back(objectPointId);
4068
4069 if (objectPoints)
4070 {
4071 ocean_assert(databaseObjectPointMap.find(*i) != databaseObjectPointMap.end());
4072 objectPoints->push_back(databaseObjectPointMap.find(*i)->second.point());
4073 }
4074 }
4075 }
4076
4077 ocean_assert(IndexSet32(result.begin(), result.end()).size() == result.size());
4078
4079 return result;
4080}
4081
4082template <bool tThreadSafe, bool tMatchPosition>
4083Indices32 Database::objectPointIds(const Index32 poseId, const Vector3& referencePosition, const Scalar minimalPriority, Vectors3* objectPoints) const
4084{
4085 ocean_assert(poseId != invalidId);
4086 ocean_assert(objectPoints == nullptr || objectPoints->empty());
4087
4089
4090 const PoseMap::const_iterator iP = databasePoseMap.find(poseId);
4091 ocean_assert(iP != databasePoseMap.end());
4092
4093 const IndexSet32& imagePointIds = iP->second.imagePointIds();
4094
4095 Indices32 result;
4096 result.reserve(imagePointIds.size());
4097
4098 if (objectPoints)
4099 objectPoints->reserve(imagePointIds.size());
4100
4101 for (IndexSet32::const_iterator i = imagePointIds.begin(); i != imagePointIds.end(); ++i)
4102 {
4103 ocean_assert(*i != invalidId);
4104
4105 const ImagePointMap::const_iterator iI = databaseImagePointMap.find(*i);
4106 ocean_assert(iI != databaseImagePointMap.end());
4107
4108 const Index32 objectPointId = iI->second.objectPointId();
4109
4110 if (objectPointId != invalidId)
4111 {
4112 const ObjectPointMap::const_iterator iO = databaseObjectPointMap.find(objectPointId);
4113 ocean_assert(iO != databaseObjectPointMap.end());
4114
4115 const Vector3& objectPoint = iO->second.point();
4116
4117 if (iO->second.priority() >= minimalPriority && ((tMatchPosition && objectPoint == referencePosition) || (!tMatchPosition && objectPoint != referencePosition)))
4118 {
4119 result.push_back(objectPointId);
4120
4121 if (objectPoints)
4122 objectPoints->push_back(objectPoint);
4123 }
4124 }
4125 }
4126
4127 ocean_assert(IndexSet32(result.begin(), result.end()).size() == result.size());
4128
4129 return result;
4130}
4131
4132template <bool tThreadSafe>
4133Indices32 Database::objectPointIds(const Indices32 poseIds, Vectors3* objectPoints) const
4134{
4135 ocean_assert(!poseIds.empty());
4136 ocean_assert(objectPoints == nullptr || objectPoints->empty());
4137
4139
4141
4142 for (Indices32::const_iterator iP = poseIds.begin(); iP != poseIds.end(); ++iP)
4143 {
4144 const PoseMap::const_iterator iPM = databasePoseMap.find(*iP);
4145 ocean_assert(iPM != databasePoseMap.end());
4146
4147 const IndexSet32& imagePointIds = iPM->second.imagePointIds();
4148
4149 for (IndexSet32::const_iterator i = imagePointIds.begin(); i != imagePointIds.end(); ++i)
4150 {
4151 ocean_assert(*i != invalidId);
4152
4153 const ImagePointMap::const_iterator iI = databaseImagePointMap.find(*i);
4154 ocean_assert(iI != databaseImagePointMap.end());
4155
4156 const Index32 objectPointId = iI->second.objectPointId();
4157
4158 if (objectPointId != invalidId)
4159 objectPointIds.insert(objectPointId);
4160 }
4161 }
4162
4163 Indices32 result;
4164
4165 if (objectPoints)
4166 {
4167 result.reserve(objectPointIds.size());
4168 objectPoints->reserve(objectPointIds.size());
4169
4170 for (IndexSet32::const_iterator i = objectPointIds.begin(); i != objectPointIds.end(); ++i)
4171 {
4172 ocean_assert(databaseObjectPointMap.find(*i) != databaseObjectPointMap.end());
4173
4174 result.push_back(*i);
4175 objectPoints->push_back(databaseObjectPointMap.find(*i)->second.point());
4176 }
4177 }
4178 else
4179 result = Indices32(objectPointIds.begin(), objectPointIds.end());
4180
4181 return result;
4182}
4183
4184template <bool tThreadSafe, bool tMatchPosition, bool tVisibleInAllPoses>
4185Indices32 Database::objectPointIds(const Index32 lowerPoseId, const Index32 upperPoseId, const Vector3& referencePosition, const Scalar minimalPriority, Vectors3* objectPoints) const
4186{
4187 ocean_assert(lowerPoseId <= upperPoseId);
4188 ocean_assert(objectPoints == nullptr || objectPoints->empty());
4189
4191
4192 if constexpr (tVisibleInAllPoses)
4193 {
4194 Indices32 result;
4195
4196 const PoseMap::const_iterator iPM = databasePoseMap.find(lowerPoseId);
4197
4198 // if the lower pose does not exist the object points cannot be visible in all poses anymore
4199 if (iPM == databasePoseMap.end())
4200 return Indices32();
4201
4202 const IndexSet32& imagePointIds = iPM->second.imagePointIds();
4203
4204 for (IndexSet32::const_iterator i = imagePointIds.begin(); i != imagePointIds.end(); ++i)
4205 {
4206 ocean_assert(*i != invalidId);
4207
4208 const ImagePointMap::const_iterator iI = databaseImagePointMap.find(*i);
4209 ocean_assert(iI != databaseImagePointMap.end());
4210
4211 const Index32 objectPointId = iI->second.objectPointId();
4212
4213 if (objectPointId != invalidId)
4214 {
4215 const ObjectPointMap::const_iterator iO = databaseObjectPointMap.find(objectPointId);
4216 ocean_assert(iO != databaseObjectPointMap.end());
4217
4218 if (iO->second.priority() >= minimalPriority && ((tMatchPosition && iO->second.point() == referencePosition) || (!tMatchPosition && iO->second.point() != referencePosition)))
4219 {
4220 bool visibleInAllPoses = true;
4221 for (unsigned int n = lowerPoseId + 1u; visibleInAllPoses && n <= upperPoseId; ++n)
4222 visibleInAllPoses = databasePoseObjectPointMap.find(index64(n, objectPointId)) != databasePoseObjectPointMap.end();
4223
4224 if (visibleInAllPoses)
4225 {
4226 result.push_back(objectPointId);
4227
4228 if (objectPoints)
4229 objectPoints->push_back(iO->second.point());
4230 }
4231 }
4232 }
4233 }
4234
4235 ocean_assert(IndexSet32(result.begin(), result.end()).size() == result.size());
4236 ocean_assert(objectPoints == nullptr || objectPoints->size() == result.size());
4237
4238 return result;
4239 }
4240 else
4241 {
4242 Indices32 result;
4244
4245 for (unsigned int n = lowerPoseId; n <= upperPoseId; ++n)
4246 {
4247 const PoseMap::const_iterator iPM = databasePoseMap.find(n);
4248
4249 if (iPM != databasePoseMap.end())
4250 {
4251 const IndexSet32& imagePointIds = iPM->second.imagePointIds();
4252
4253 for (IndexSet32::const_iterator i = imagePointIds.begin(); i != imagePointIds.end(); ++i)
4254 {
4255 ocean_assert(*i != invalidId);
4256
4257 const ImagePointMap::const_iterator iI = databaseImagePointMap.find(*i);
4258 ocean_assert(iI != databaseImagePointMap.end());
4259
4260 const Index32 objectPointId = iI->second.objectPointId();
4261
4262 if (objectPointId != invalidId && objectPointIds.find(objectPointId) == objectPointIds.end())
4263 {
4264 objectPointIds.insert(objectPointId);
4265
4266 const ObjectPointMap::const_iterator iO = databaseObjectPointMap.find(objectPointId);
4267 ocean_assert(iO != databaseObjectPointMap.end());
4268
4269 if (iO->second.priority() >= minimalPriority && ((tMatchPosition && iO->second.point() == referencePosition) || (!tMatchPosition && iO->second.point() != referencePosition)))
4270 {
4271 result.push_back(objectPointId);
4272
4273 if (objectPoints)
4274 objectPoints->push_back(iO->second.point());
4275 }
4276 }
4277 }
4278 }
4279 }
4280
4281 ocean_assert(IndexSet32(result.begin(), result.end()).size() == result.size());
4282 ocean_assert(objectPoints == nullptr || objectPoints->size() == result.size());
4283
4284 return result;
4285 }
4286}
4287
4288template <bool tThreadSafe, bool tMatchPosition, bool tVisibleInAllPoses>
4289Indices32 Database::objectPointIds(const Indices32& poseIds, const Vector3& referencePosition, const Scalar minimalPriority, Vectors3* objectPoints) const
4290{
4291 ocean_assert(Indices32(poseIds.begin(), poseIds.end()).size() == poseIds.size());
4292 ocean_assert(objectPoints == nullptr || objectPoints->empty());
4293
4294 if (poseIds.empty())
4295 return Indices32();
4296
4298
4299 if constexpr (tVisibleInAllPoses)
4300 {
4301 Indices32 result;
4302
4303 const PoseMap::const_iterator iPM = databasePoseMap.find(poseIds.front());
4304
4305 // if the first pose does not exist the object points cannot be visible in all poses anymore
4306 if (iPM == databasePoseMap.end())
4307 return Indices32();
4308
4309 const IndexSet32& imagePointIds = iPM->second.imagePointIds();
4310
4311 for (IndexSet32::const_iterator i = imagePointIds.begin(); i != imagePointIds.end(); ++i)
4312 {
4313 ocean_assert(*i != invalidId);
4314
4315 const ImagePointMap::const_iterator iI = databaseImagePointMap.find(*i);
4316 ocean_assert(iI != databaseImagePointMap.end());
4317
4318 const Index32 objectPointId = iI->second.objectPointId();
4319
4320 if (objectPointId != invalidId)
4321 {
4322 const ObjectPointMap::const_iterator iO = databaseObjectPointMap.find(objectPointId);
4323 ocean_assert(iO != databaseObjectPointMap.end());
4324
4325 if (iO->second.priority() >= minimalPriority && ((tMatchPosition && iO->second.point() == referencePosition) || (!tMatchPosition && iO->second.point() != referencePosition)))
4326 {
4327 bool visibleInAllPoses = true;
4328 for (size_t n = 1; n < poseIds.size(); ++n)
4329 visibleInAllPoses = databasePoseObjectPointMap.find(index64(poseIds[n], objectPointId)) != databasePoseObjectPointMap.end();
4330
4331 if (visibleInAllPoses)
4332 {
4333 result.push_back(objectPointId);
4334
4335 if (objectPoints)
4336 objectPoints->push_back(iO->second.point());
4337 }
4338 }
4339 }
4340 }
4341
4342 ocean_assert(IndexSet32(result.begin(), result.end()).size() == result.size());
4343 ocean_assert(objectPoints == nullptr || objectPoints->size() == result.size());
4344
4345 return result;
4346 }
4347 else
4348 {
4349 Indices32 result;
4351
4352 for (size_t n = 0; n < poseIds.size(); ++n)
4353 {
4354 const PoseMap::const_iterator iPM = databasePoseMap.find(poseIds[n]);
4355
4356 if (iPM != databasePoseMap.end())
4357 {
4358 const IndexSet32& imagePointIds = iPM->second.imagePointIds();
4359
4360 for (IndexSet32::const_iterator i = imagePointIds.begin(); i != imagePointIds.end(); ++i)
4361 {
4362 ocean_assert(*i != invalidId);
4363
4364 const ImagePointMap::const_iterator iI = databaseImagePointMap.find(*i);
4365 ocean_assert(iI != databaseImagePointMap.end());
4366
4367 const Index32 objectPointId = iI->second.objectPointId();
4368
4369 if (objectPointId != invalidId && objectPointIds.find(objectPointId) == objectPointIds.end())
4370 {
4371 objectPointIds.insert(objectPointId);
4372
4373 const ObjectPointMap::const_iterator iO = databaseObjectPointMap.find(objectPointId);
4374 ocean_assert(iO != databaseObjectPointMap.end());
4375
4376 if (iO->second.priority() >= minimalPriority && ((tMatchPosition && iO->second.point() == referencePosition) || (!tMatchPosition && iO->second.point() != referencePosition)))
4377 {
4378 result.push_back(objectPointId);
4379
4380 if (objectPoints)
4381 objectPoints->push_back(iO->second.point());
4382 }
4383 }
4384 }
4385 }
4386 }
4387
4388 ocean_assert(IndexSet32(result.begin(), result.end()).size() == result.size());
4389 ocean_assert(objectPoints == nullptr || objectPoints->size() == result.size());
4390
4391 return result;
4392 }
4393}
4394
4395template <bool tThreadSafe>
4397{
4398 ocean_assert(poseId != invalidId);
4399
4401
4402 const PoseMap::const_iterator iP = databasePoseMap.find(poseId);
4403
4404 ocean_assert(iP != databasePoseMap.end());
4405 if (iP == databasePoseMap.end())
4406 return Vectors2();
4407
4408 const IndexSet32& imagePointIds = iP->second.imagePointIds();
4409
4410 Vectors2 result;
4411 result.reserve(imagePointIds.size());
4412
4413 ocean_assert(objectPointIds.empty());
4414 objectPointIds.clear();
4415 objectPointIds.reserve(imagePointIds.size());
4416
4417 for (IndexSet32::const_iterator i = imagePointIds.cbegin(); i != imagePointIds.cend(); ++i)
4418 {
4419 ocean_assert(*i != invalidId);
4420
4421 const ImagePointMap::const_iterator iI = databaseImagePointMap.find(*i);
4422 ocean_assert(iI != databaseImagePointMap.end());
4423
4424 if (iI->second.objectPointId() != invalidId)
4425 {
4426 result.push_back(iI->second.point());
4427 objectPointIds.push_back(iI->second.objectPointId());
4428 }
4429 }
4430
4431 ocean_assert(result.size() == objectPointIds.size());
4432
4433 return result;
4434}
4435
4436template <bool tThreadSafe>
4437Vectors2 Database::imagePointsFromObjectPoints(const Index32 poseId, Indices32& objectPointIds, Indices32* imagePointIds) const
4438{
4439 ocean_assert(poseId != invalidId);
4440 ocean_assert(!objectPointIds.empty());
4441 ocean_assert(imagePointIds == nullptr || imagePointIds->empty());
4442
4444
4445 Vectors2 points;
4446 points.reserve(objectPointIds.size());
4447
4448 Indices32 validObjectPointIds;
4449 validObjectPointIds.reserve(objectPointIds.size());
4450
4451 for (Indices32::const_iterator i = objectPointIds.begin(); i != objectPointIds.end(); ++i)
4452 {
4453 const Index64To32Map::const_iterator iPO = databasePoseObjectPointMap.find(index64(poseId, *i));
4454
4455 if (iPO != databasePoseObjectPointMap.end())
4456 {
4457 ocean_assert(iPO->second != invalidId);
4458 const ImagePointMap::const_iterator iI = databaseImagePointMap.find(iPO->second);
4459 ocean_assert(iI != databaseImagePointMap.end());
4460
4461 points.push_back(iI->second.point());
4462 validObjectPointIds.push_back(*i);
4463
4464 if (imagePointIds)
4465 imagePointIds->push_back(iPO->second);
4466 }
4467 }
4468
4469 objectPointIds = std::move(validObjectPointIds);
4470 return points;
4471}
4472
4473template <bool tThreadSafe>
4474Vectors2 Database::imagePointsFromObjectPoints(const Index32 poseId, const Indices32& objectPointIds, Indices32& validIndices, Indices32* imagePointIds) const
4475{
4476 ocean_assert(poseId != invalidId);
4477 ocean_assert(!objectPointIds.empty());
4478 ocean_assert(imagePointIds == nullptr || imagePointIds->empty());
4479
4480 return imagePointsFromObjectPoints<tThreadSafe>(poseId, objectPointIds.data(), objectPointIds.size(), validIndices, imagePointIds);
4481}
4482
4483template <bool tThreadSafe>
4484Vectors2 Database::imagePointsFromObjectPoints(const Index32 poseId, const Index32* objectPointIds, const size_t numberObjectPointIds, Indices32& validIndices, Indices32* imagePointIds) const
4485{
4486 ocean_assert(poseId != invalidId);
4487 ocean_assert(objectPointIds && numberObjectPointIds != 0);
4488 ocean_assert(imagePointIds == nullptr || imagePointIds->empty());
4489
4491
4492 Vectors2 points;
4493 points.reserve(numberObjectPointIds);
4494
4495 for (size_t n = 0; n < numberObjectPointIds; ++n)
4496 {
4497 const Index32 objectPointId = objectPointIds[n];
4498
4499 const Index64To32Map::const_iterator iPO = databasePoseObjectPointMap.find(index64(poseId, objectPointId));
4500
4501 if (iPO != databasePoseObjectPointMap.end())
4502 {
4503 ocean_assert(iPO->second != invalidId);
4504 const ImagePointMap::const_iterator iI = databaseImagePointMap.find(iPO->second);
4505 ocean_assert(iI != databaseImagePointMap.end());
4506
4507 points.push_back(iI->second.point());
4508 validIndices.push_back((unsigned int)n);
4509
4510 if (imagePointIds)
4511 imagePointIds->push_back(iPO->second);
4512 }
4513 }
4514
4515 return points;
4516}
4517
4518template <bool tThreadSafe>
4520{
4521 ocean_assert(!poseIds.empty());
4522 ocean_assert(IndexSet32(poseIds.begin(), poseIds.end()).size() == poseIds.size());
4523
4525
4526 ImagePointsMap intermediate;
4527
4528 for (Indices32::const_iterator iP = poseIds.begin(); iP != poseIds.end(); ++iP)
4529 {
4530 ocean_assert(*iP != invalidId);
4531 ocean_assert(databasePoseMap.find(*iP) != databasePoseMap.end());
4532
4533 const PoseData& poseData = databasePoseMap.find(*iP)->second;
4534
4535 for (IndexSet32::const_iterator iI = poseData.imagePointIds().begin(); iI != poseData.imagePointIds().end(); ++iI)
4536 {
4537 const ImagePointMap::const_iterator i = databaseImagePointMap.find(*iI);
4538 ocean_assert(i != databaseImagePointMap.end());
4539
4540 if (i->second.objectPointId() != invalidId)
4541 intermediate[i->second.objectPointId()].push_back(i->second.point());
4542 }
4543 }
4544
4545 ImagePointGroups result(poseIds.size());
4546
4547 for (ImagePointsMap::iterator i = intermediate.begin(); i != intermediate.end(); ++i)
4548 if (i->second.size() == poseIds.size())
4549 {
4550 objectPointIds.push_back(i->first);
4551
4552 for (size_t n = 0; n < poseIds.size(); ++n)
4553 result[n].push_back(i->second[n]);
4554 }
4555
4556 return result;
4557}
4558
4559template <bool tThreadSafe>
4560Database::IdIdPointPairsMap Database::imagePoints(const Index32 poseId, const bool previous, const size_t minimalObservations, const size_t maximalObservations) const
4561{
4562 ocean_assert(poseId != invalidId);
4563 ocean_assert(maximalObservations == 0 || minimalObservations <= maximalObservations);
4564
4566
4567 IdIdPointPairsMap result;
4568
4569 const PoseMap::const_iterator iP = databasePoseMap.find(poseId);
4570 ocean_assert(iP != databasePoseMap.end());
4571
4572 const PoseData& poseData = iP->second;
4573
4574 for (IndexSet32::const_iterator iI = poseData.imagePointIds().begin(); iI != poseData.imagePointIds().end(); ++iI)
4575 {
4576 const ImagePointMap::const_iterator i = databaseImagePointMap.find(*iI);
4577 ocean_assert(i != databaseImagePointMap.end());
4578
4579 const Index32 objectPointId = i->second.objectPointId();
4580
4581 if (objectPointId != invalidId)
4582 {
4583 IdPointPairs imagePointPairs;
4584 imagePointPairs.push_back(std::make_pair(*iI, i->second.point()));
4585
4586 // now find the consecutive image points
4587 Index32 pId = poseId;
4588
4589 while (((previous && pId-- != 0u) || (!previous && ++pId < databasePoses)) && (maximalObservations == 0 || imagePointPairs.size() < maximalObservations))
4590 {
4591 const Index64To32Map::const_iterator iPO = databasePoseObjectPointMap.find(index64(pId, objectPointId));
4592
4593 if (iPO == databasePoseObjectPointMap.end())
4594 break;
4595
4596 const ImagePointMap::const_iterator otherPO = databaseImagePointMap.find(iPO->second);
4597 ocean_assert(otherPO != databaseImagePointMap.end());
4598
4599 imagePointPairs.push_back(std::make_pair(iPO->second, otherPO->second.point()));
4600 }
4601
4602 if (minimalObservations == 0 || imagePointPairs.size() >= minimalObservations)
4603 result[objectPointId] = imagePointPairs;
4604 }
4605 }
4606
4607 return result;
4608}
4609
4610template <bool tThreadSafe>
4611void Database::imagePoints(const Index32 pose0, const Index32 pose1, Vectors2& points0, Vectors2& points1, Indices32* objectPointIds) const
4612{
4613 ocean_assert(pose0 != invalidId && pose1 != invalidId);
4614 ocean_assert(pose0 != pose1);
4615
4616 ocean_assert(points0.size() == points1.size());
4617
4619
4620 const PoseMap::const_iterator iP0 = databasePoseMap.find(pose0);
4621 ocean_assert(iP0 != databasePoseMap.end());
4622
4623 const PoseData& poseData0 = iP0->second;
4624
4625 for (IndexSet32::const_iterator i = poseData0.imagePointIds().begin(); i != poseData0.imagePointIds().end(); ++i)
4626 {
4627 const ImagePointMap::const_iterator iI0 = databaseImagePointMap.find(*i);
4628 ocean_assert(iI0 != databaseImagePointMap.end());
4629
4630 ocean_assert(iI0->second.poseId() == pose0);
4631 if (iI0->second.objectPointId() != invalidId)
4632 {
4633 const Index64To32Map::const_iterator iPO = databasePoseObjectPointMap.find(index64(pose1, iI0->second.objectPointId()));
4634
4635 if (iPO != databasePoseObjectPointMap.end())
4636 {
4637 const ImagePointMap::const_iterator iI1 = databaseImagePointMap.find(iPO->second);
4638 ocean_assert(iI1 != databaseImagePointMap.end());
4639
4640 points0.push_back(iI0->second.point());
4641 points1.push_back(iI1->second.point());
4642
4643 if (objectPointIds)
4644 objectPointIds->push_back(iI0->second.objectPointId());
4645 }
4646 }
4647 }
4648}
4649
4650template <bool tThreadSafe, bool tMatchPosition>
4651void Database::imagePointsObjectPoints(const Index32 poseId, Vectors2& imagePoints, Vectors3& objectPoints, const Vector3& referencePosition, const size_t minimalObservations, Indices32* imagePointIds, Indices32* objectPointIds) const
4652{
4653 ocean_assert(poseId != invalidId);
4654 ocean_assert(imagePoints.empty() && objectPoints.empty());
4655
4656 ocean_assert(imagePointIds == nullptr || imagePointIds->empty());
4657 ocean_assert(objectPointIds == nullptr || objectPointIds->empty());
4658
4660
4661 const PoseMap::const_iterator iPose = databasePoseMap.find(poseId);
4662 ocean_assert(iPose != databasePoseMap.end());
4663
4664 const PoseData& poseData = iPose->second;
4665
4666 imagePoints.reserve(poseData.imagePointIds().size());
4667 objectPoints.reserve(poseData.imagePointIds().size());
4668
4669 if (imagePointIds)
4670 {
4671 imagePointIds->reserve(poseData.imagePointIds().size());
4672 }
4673
4674 if (objectPointIds)
4675 {
4676 objectPointIds->reserve(poseData.imagePointIds().size());
4677 }
4678
4679 for (const Index32& imagePointId : poseData.imagePointIds())
4680 {
4681 const ImagePointMap::const_iterator iImagePoint = databaseImagePointMap.find(imagePointId);
4682 ocean_assert(iImagePoint != databaseImagePointMap.end());
4683
4684 if (iImagePoint->second.objectPointId() != invalidId)
4685 {
4686 const ObjectPointMap::const_iterator iObjectPoint = databaseObjectPointMap.find(iImagePoint->second.objectPointId());
4687 ocean_assert(iObjectPoint != databaseObjectPointMap.end());
4688
4689 if (((tMatchPosition && iObjectPoint->second.point() == referencePosition) || (!tMatchPosition && iObjectPoint->second.point() != referencePosition)) && (minimalObservations == 0 || iObjectPoint->second.imagePointIds().size() >= minimalObservations))
4690 {
4691 imagePoints.push_back(iImagePoint->second.point());
4692 objectPoints.push_back(iObjectPoint->second.point());
4693
4694 if (imagePointIds)
4695 {
4696 imagePointIds->push_back(iImagePoint->first);
4697 }
4698
4699 if (objectPointIds)
4700 {
4701 objectPointIds->push_back(iImagePoint->second.objectPointId());
4702 }
4703 }
4704 }
4705 }
4706}
4707
4708template <bool tThreadSafe, bool tMatchPosition>
4709void 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
4710{
4711 ocean_assert(poseId != invalidId);
4712 ocean_assert(priorityImagePoints.empty() && priorityObjectPoints.empty());
4713 ocean_assert(remainingImagePoints.empty() && remainingObjectPoints.empty());
4714
4715 ocean_assert(priorityImagePointIds == nullptr || priorityImagePointIds->empty());
4716 ocean_assert(priorityObjectPointIds == nullptr || priorityObjectPointIds->empty());
4717 ocean_assert(remainingImagePointIds == nullptr || remainingImagePointIds->empty());
4718 ocean_assert(remainingObjectPointIds == nullptr || remainingObjectPointIds->empty());
4719
4720 ocean_assert(!priorityIds.empty());
4721
4723
4724 const PoseMap::const_iterator iP = databasePoseMap.find(poseId);
4725 ocean_assert(iP != databasePoseMap.end());
4726
4727 const PoseData& poseData = iP->second;
4728
4729 priorityImagePoints.reserve(poseData.imagePointIds().size());
4730 priorityObjectPoints.reserve(poseData.imagePointIds().size());
4731
4732 remainingImagePoints.reserve(poseData.imagePointIds().size());
4733 remainingObjectPoints.reserve(poseData.imagePointIds().size());
4734
4735 if (priorityImagePointIds)
4736 priorityImagePointIds->reserve(poseData.imagePointIds().size());
4737
4738 if (priorityObjectPointIds)
4739 priorityObjectPointIds->reserve(poseData.imagePointIds().size());
4740
4741 if (remainingImagePointIds)
4742 remainingImagePointIds->reserve(poseData.imagePointIds().size());
4743
4744 if (remainingObjectPointIds)
4745 remainingObjectPointIds->reserve(poseData.imagePointIds().size());
4746
4747 for (IndexSet32::const_iterator i = poseData.imagePointIds().begin(); i != poseData.imagePointIds().end(); ++i)
4748 {
4749 const ImagePointMap::const_iterator iI = databaseImagePointMap.find(*i);
4750 ocean_assert(iI != databaseImagePointMap.end());
4751
4752 if (iI->second.objectPointId() != invalidId)
4753 {
4754 const ObjectPointMap::const_iterator iO = databaseObjectPointMap.find(iI->second.objectPointId());
4755 ocean_assert(iO != databaseObjectPointMap.end());
4756
4757 if (((tMatchPosition && iO->second.point() == referencePosition) || (!tMatchPosition && iO->second.point() != referencePosition)) && (minimalObservations == 0 || iO->second.imagePointIds().size() >= minimalObservations))
4758 {
4759 ocean_assert(iO->first == iI->second.objectPointId());
4760
4761 if (priorityIds.find(iO->first) != priorityIds.end())
4762 {
4763 priorityImagePoints.push_back(iI->second.point());
4764 priorityObjectPoints.push_back(iO->second.point());
4765
4766 if (priorityImagePointIds)
4767 priorityImagePointIds->push_back(iI->first);
4768
4769 if (priorityObjectPointIds)
4770 priorityObjectPointIds->push_back(iI->second.objectPointId());
4771 }
4772 else
4773 {
4774 remainingImagePoints.push_back(iI->second.point());
4775 remainingObjectPoints.push_back(iO->second.point());
4776
4777 if (remainingImagePointIds)
4778 remainingImagePointIds->push_back(iI->first);
4779
4780 if (remainingObjectPointIds)
4781 remainingObjectPointIds->push_back(iI->second.objectPointId());
4782 }
4783 }
4784 }
4785 }
4786}
4787
4788template <bool tThreadSafe, bool tMatchPose>
4789void Database::posesImagePoints(const Index32 objectPointId, HomogenousMatrices4& poses, Vectors2& imagePoints, const HomogenousMatrix4& referencePose, Indices32* poseIds, Indices32* imagePointIds, const Index32 lowerPoseId, const Index32 upperPoseId) const
4790{
4791 ocean_assert(objectPointId != invalidId);
4792 ocean_assert(poses.empty() && imagePoints.empty());
4793
4794 ocean_assert(poseIds == nullptr || poseIds->empty());
4795 ocean_assert(imagePointIds == nullptr || imagePointIds->empty());
4796
4798
4799 const ObjectPointMap::const_iterator iO = databaseObjectPointMap.find(objectPointId);
4800 ocean_assert(iO != databaseObjectPointMap.end());
4801
4802 const IndexSet32& imagePointCandidateIds = iO->second.imagePointIds();
4803
4804 poses.reserve(imagePointCandidateIds.size());
4805 imagePoints.reserve(imagePointCandidateIds.size());
4806
4807 if (poseIds)
4808 poseIds->reserve(imagePointCandidateIds.size());
4809
4810 if (imagePointIds)
4811 imagePointIds->reserve(imagePointCandidateIds.size());
4812
4813 for (IndexSet32::const_iterator i = imagePointCandidateIds.begin(); i != imagePointCandidateIds.end(); ++i)
4814 {
4815 const ImagePointMap::const_iterator iI = databaseImagePointMap.find(*i);
4816 ocean_assert(iI != databaseImagePointMap.end());
4817
4818 const Vector2& imagePoint = iI->second.point();
4819 const Index32 poseId = iI->second.poseId();
4820
4821 if (poseId == invalidId || (lowerPoseId != invalidId && poseId < lowerPoseId) || (upperPoseId != invalidId && poseId > upperPoseId))
4822 continue;
4823
4824 const PoseMap::const_iterator iP = databasePoseMap.find(poseId);
4825 ocean_assert(iP != databasePoseMap.end());
4826
4827 const HomogenousMatrix4& pose = iP->second.pose();
4828
4829 if ((tMatchPose && pose == referencePose) || (!tMatchPose && pose != referencePose))
4830 {
4831 ocean_assert(pose.isValid());
4832
4833 imagePoints.push_back(imagePoint);
4834 poses.push_back(pose);
4835
4836 if (poseIds)
4837 poseIds->push_back(poseId);
4838
4839 if (imagePointIds)
4840 imagePointIds->push_back(*i);
4841 }
4842 }
4843}
4844
4845template <bool tThreadSafe>
4847{
4848 ocean_assert(!poseIds.empty());
4849
4851
4852 TopologyTriples result;
4853
4854 for (Indices32::const_iterator iiP = poseIds.begin(); iiP != poseIds.end(); ++iiP)
4855 {
4856 const PoseMap::const_iterator iP = databasePoseMap.find(*iiP);
4857 ocean_assert(iP != databasePoseMap.end());
4858
4859 const IndexSet32& poseImagePoints = iP->second.imagePointIds();
4860
4861 for (IndexSet32::const_iterator iI = poseImagePoints.begin(); iI != poseImagePoints.end(); ++iI)
4862 {
4863 const ImagePointMap::const_iterator i = databaseImagePointMap.find(*iI);
4864 ocean_assert(i != databaseImagePointMap.end());
4865
4866 const Index32 objectPointId = i->second.objectPointId();
4867
4868 if (objectPointId != invalidId)
4869 result.push_back(TopologyTriple(*iiP, objectPointId, *iI));
4870 }
4871 }
4872
4873 return result;
4874}
4875
4876template <bool tThreadSafe>
4877inline void Database::clear()
4878{
4880
4881 databasePoseMap.clear();
4882 databaseObjectPointMap.clear();
4883 databaseImagePointMap.clear();
4885
4886 databasePoses = 0u;
4887
4890}
4891
4892template <bool tThreadSafe>
4893inline void Database::reset(const Vector3& referenceObjectPoint, const HomogenousMatrix4& referencePose)
4894{
4896
4897 for (ObjectPointMap::iterator i = databaseObjectPointMap.begin(); i != databaseObjectPointMap.end(); ++i)
4898 {
4899 i->second.setPoint(referenceObjectPoint);
4900 }
4901
4902 for (PoseMap::iterator i = databasePoseMap.begin(); i != databasePoseMap.end(); ++i)
4903 {
4904 i->second.setPose(referencePose);
4905 }
4906}
4907
4908template <typename T, bool tThreadSafe>
4909void 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)
4910{
4912
4913 clear<false>();
4914
4915 databasePoses = 0u;
4918
4919 for (size_t n = 0; n < numberPoses; ++n)
4920 {
4921 const Index32& poseId = poseIds[n];
4922 const HomogenousMatrixT4<T>& pose = poses[n];
4923
4924 ocean_assert(databasePoseMap.find(poseId) == databasePoseMap.cend());
4926
4927 ocean_assert(poseId != invalidId);
4928 databasePoses = max(databasePoses, poseId + 1u);
4929 }
4930
4931 databaseObjectPointMap.reserve(numberObjectPoints);
4932
4933 for (size_t n = 0; n < numberObjectPoints; ++n)
4934 {
4935 const Index32& objectPointId = objectPointIds[n];
4937 const T& objectPointPriority = objectPointPriorities[n];
4938
4939 ocean_assert(databaseObjectPointMap.find(objectPointId) == databaseObjectPointMap.cend());
4940
4942 {
4944 }
4945 else
4946 {
4948 }
4949
4950 ocean_assert(objectPointId != invalidId);
4952 }
4953
4954 databaseImagePointMap.reserve(numberImagePoints);
4955 databasePoseObjectPointMap.reserve(numberImagePoints);
4956
4957 for (size_t n = 0; n < numberImagePoints; ++n)
4958 {
4959 const Index32& imagePointId = imagePointIds[n];
4961
4962 const Index32& topologyPoseId = topologyPoseIds[n];
4963 const Index32& topologyObjectPointId = topologyObjectPointIds[n];
4964
4965 ocean_assert(databaseImagePointMap.find(imagePointId) == databaseImagePointMap.cend());
4966 databaseImagePointMap.emplace(imagePointId, ImagePointData(Vector2(imagePoint), topologyPoseId, topologyObjectPointId));
4967
4968 ocean_assert((topologyPoseId == invalidId && topologyObjectPointId == invalidId) || (topologyPoseId != invalidId && topologyObjectPointId != invalidId));
4969
4970 if (topologyPoseId != invalidId)
4971 {
4972 databasePoseObjectPointMap.emplace(index64(topologyPoseId, topologyObjectPointId), imagePointId);
4973
4974 ocean_assert(databasePoseMap.find(topologyPoseId) != databasePoseMap.cend());
4975 databasePoseMap[topologyPoseId].registerImagePoint(imagePointId);
4976
4977 ocean_assert(databaseObjectPointMap.find(topologyObjectPointId) != databaseObjectPointMap.cend());
4978 databaseObjectPointMap[topologyObjectPointId].registerImagePoint(imagePointId);
4979 }
4980
4981 ocean_assert(imagePointId != invalidId);
4983 }
4984}
4985
4986inline Indices32 Database::filterTopologyTriplesPoses(const TopologyTriples& topologyTriples, const IndexSet32& poseIds)
4987{
4988 ocean_assert(!poseIds.empty());
4989
4990 Indices32 result;
4991 result.reserve(topologyTriples.size());
4992
4993 for (unsigned int n = 0u; n < topologyTriples.size(); ++n)
4994 if (poseIds.find(topologyTriples[n].poseId()) != poseIds.end())
4995 result.push_back(n);
4996
4997 return result;
4998}
4999
5000inline Indices32 Database::filterTopologyTriplesObjectPoints(const TopologyTriples& topologyTriples, const IndexSet32& objectPointIds)
5001{
5002 ocean_assert(!objectPointIds.empty());
5003
5004 Indices32 result;
5005 result.reserve(topologyTriples.size());
5006
5007 for (unsigned int n = 0u; n < topologyTriples.size(); ++n)
5008 if (objectPointIds.find(topologyTriples[n].objectPointId()) != objectPointIds.end())
5009 result.push_back(n);
5010
5011 return result;
5012}
5013
5014inline Indices32 Database::filterTopologyTriplesImagePoints(const TopologyTriples& topologyTriples, const IndexSet32& imagePointIds)
5015{
5016 ocean_assert(!imagePointIds.empty());
5017
5018 Indices32 result;
5019 result.reserve(topologyTriples.size());
5020
5021 for (unsigned int n = 0u; n < topologyTriples.size(); ++n)
5022 if (imagePointIds.find(topologyTriples[n].imagePointId()) != imagePointIds.end())
5023 result.push_back(n);
5024
5025 return result;
5026}
5027
5028inline Indices32 Database::reliableObjectPoints(const TopologyTriples& topologyTriples, const unsigned int minimalObservations)
5029{
5030 ocean_assert(!topologyTriples.empty());
5031
5032 Index32To32Map objectPointCounterMap;
5033 for (TopologyTriples::const_iterator i = topologyTriples.begin(); i != topologyTriples.end(); ++i)
5034 {
5035 ocean_assert(i->objectPointId() != invalidId);
5036 objectPointCounterMap[i->objectPointId()]++;
5037 }
5038
5040 objectPointIds.reserve(objectPointCounterMap.size());
5041
5042 for (Index32To32Map::const_iterator i = objectPointCounterMap.begin(); i != objectPointCounterMap.end(); ++i)
5043 if (i->second >= minimalObservations)
5044 objectPointIds.push_back(i->first);
5045
5046 return objectPointIds;
5047}
5048
5049inline Database& Database::operator=(const Database& database)
5050{
5051 if (this != &database)
5052 {
5057
5058 databasePoses = database.databasePoses;
5061 }
5062
5063 return *this;
5064}
5065
5066inline Database& Database::operator=(Database&& database) noexcept
5067{
5068 if (this != &database)
5069 {
5070 databasePoseMap = std::move(database.databasePoseMap);
5071 databaseObjectPointMap = std::move(database.databaseObjectPointMap);
5072 databaseImagePointMap = std::move(database.databaseImagePointMap);
5073 databasePoseObjectPointMap = std::move(database.databasePoseObjectPointMap);
5074
5075 databasePoses = database.databasePoses;
5076 databaseObjectPointIdCounter = database.databaseObjectPointIdCounter;
5077 databaseImagePointIdCounter = database.databaseImagePointIdCounter;
5078
5079 database.databasePoses = 0u;
5080 database.databaseObjectPointIdCounter = invalidId;
5081 database.databaseImagePointIdCounter = invalidId;
5082 }
5083
5084 return *this;
5085}
5086
5087inline Database::operator bool() const
5088{
5089 return !isEmpty<false>();
5090}
5091
5092template <bool tMatchPosition, bool tNeedValidPose>
5093inline void Database::numberCorrespondencesSubset(const Index32 lowerPoseId, const Vector3* referenceObjectPoint, const Scalar minimalPriority, unsigned int* correspondences, const unsigned int firstPose, const unsigned int numberPoses) const
5094{
5095 ocean_assert(numberPoses >= 1u);
5096 ocean_assert(referenceObjectPoint && correspondences);
5097
5098 for (unsigned int n = firstPose; n < firstPose + numberPoses; ++n)
5099 correspondences[n] = numberCorrespondences<false, tMatchPosition, tNeedValidPose>(lowerPoseId + n, *referenceObjectPoint, minimalPriority);
5100}
5101
5102template <bool tMatchPosition>
5103void Database::objectPointIdsWithNumberOfObservationsSubset(const Index32* objectPointIds, const Vector3* referencePosition, const Scalar minimalPriority, IndexPairs32* pairs, Lock* lock, const unsigned int firstObjectPoint, const unsigned int numberObjectPoints) const
5104{
5105 ocean_assert(objectPointIds && referencePosition && pairs);
5106
5107 IndexPairs32 localPairs;
5108 localPairs.reserve(numberObjectPoints);
5109
5110 for (unsigned int n = firstObjectPoint; n < firstObjectPoint + numberObjectPoints; ++n)
5111 {
5112 const ObjectPointMap::const_iterator i = databaseObjectPointMap.find(objectPointIds[n]);
5113 if (i->second.priority() >= minimalPriority && ((tMatchPosition && i->second.point() == *referencePosition) || (!tMatchPosition && i->second.point() != *referencePosition)))
5114 localPairs.push_back(std::make_pair(i->first, numberValidPoses(i->first, i->second.imagePointIds())));
5115 }
5116
5117 if (lock)
5118 {
5119 const ScopedLock scopedLock(*lock);
5120 pairs->insert(pairs->end(), localPairs.begin(), localPairs.end());
5121 }
5122 else
5123 *pairs = std::move(localPairs);
5124}
5125
5126inline unsigned int Database::numberValidPoses(const Index32 objectPointId, const IndexSet32& imagePointIds) const
5127{
5128 ocean_assert_and_suppress_unused(objectPointId != invalidId, objectPointId);
5129
5130 ocean_assert(databaseObjectPointMap.find(objectPointId) != databaseObjectPointMap.end());
5131 ocean_assert(databaseObjectPointMap.find(objectPointId)->second.imagePointIds() == imagePointIds);
5132
5133 unsigned int validPoses = 0u;
5134
5135 for (IndexSet32::const_iterator i = imagePointIds.begin(); i != imagePointIds.end(); ++i)
5136 {
5137 const ImagePointMap::const_iterator iI = databaseImagePointMap.find(*i);
5138 ocean_assert(iI != databaseImagePointMap.end());
5139
5140 const Index32 poseId = iI->second.poseId();
5141
5142 const PoseMap::const_iterator iP = databasePoseMap.find(poseId);
5143 ocean_assert(iP != databasePoseMap.end());
5144
5145 const HomogenousMatrix4& pose = iP->second.pose();
5146
5147 if (pose.isValid())
5148 validPoses++;
5149 }
5150
5151 return validPoses;
5152}
5153
5155{
5156 return Index32(index & 0xFFFFFFFFull);
5157}
5158
5160{
5161 return Index32(index >> 32);
5162}
5163
5164inline Index64 Database::index64(const Index32 first, const Index32 second)
5165{
5166 return Index64(first) | (Index64(second) << 32);
5167}
5168
5169}
5170
5171}
5172
5173#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:3023
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:1493
VectorT3< T > translation() const
Returns the translation of the transformation.
Definition HomogenousMatrix4.h:1381
bool isValid() const
Returns whether this matrix is a valid homogeneous transformation.
Definition HomogenousMatrix4.h:1806
This class implements 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:3250
This class implements a scoped lock object for recursive lock objects.
Definition Lock.h:135
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:1341
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:977
This class implements a recursive scoped lock object that is activated by a boolean template paramete...
Definition Lock.h:178
This class implements an accessor object for image points based on a set of image point ids.
Definition Database.h:263
virtual size_t size() const
Returns the number of image points of this accessor.
Definition Database.h:1919
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 & accessorImagePointIds
The reference to the image point ids.
Definition Database.h:293
virtual const Vector2 & operator[](const size_t &index) const
Returns a specific image point identified by the index within from the specified image point ids.
Definition Database.h:1925
const Database & accessorDatabase
The reference to the database holding the individual image points.
Definition Database.h:290
This class implements an accessor object for image points based on a topology between poses and image...
Definition Database.h:302
virtual size_t size() const
Returns the number of image points of this accessor.
Definition Database.h:1940
const PoseImagePointTopology & accessorTopology
The topology between poses and image points.
Definition Database.h:332
const Database & accessorDatabase
The reference to the database holding the individual image points.
Definition Database.h:329
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
virtual const Vector2 & operator[](const size_t &index) const
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 Database & accessorDatabase
The reference to the database holding the individual object points.
Definition Database.h:368
const Indices32 & accessorObjectPointIds
The reference to the object point ids.
Definition Database.h:371
virtual const Vector3 & operator[](const size_t &index) const
Returns a specific object point identified by the index within from the specified object point ids.
Definition Database.h:1967
virtual size_t size() const
Returns the number of object points of this accessor.
Definition Database.h:1961
This class implements an accessor object for poses based on a set of pose ids.
Definition Database.h:380
const Indices32 & accessorPoseIds
The reference to the pose ids.
Definition Database.h:410
virtual size_t size() const
Returns the number of poses of this accessor.
Definition Database.h:1982
virtual const HomogenousMatrix4 & operator[](const size_t &index) const
Returns a specific pose identified by the index within from the specified pose ids.
Definition Database.h:1988
const Database & accessorDatabase
The reference to the database holding the individual object points.
Definition Database.h:407
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
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
virtual const HomogenousMatrix4 & operator[](const size_t &index) const
Returns a specific pose identified by the index within from the specified topology.
Definition Database.h:2009
virtual size_t size() const
Returns the number of poses of this accessor.
Definition Database.h:2003
const Database & accessorDatabase
The reference to the database holding the individual image points.
Definition Database.h:446
const PoseImagePointTopology & accessorTopology
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:2124
IndexSet32 dataImagePointIds
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:2129
void unregisterImagePoint(const Index32 imagePointId)
Unregisters (removes) an image point id from this data object.
Definition Database.h:2135
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:2099
Vector2 dataPoint
The location of the 2D image point of this object.
Definition Database.h:513
ImagePointData()
Creates a default object.
Definition Database.h:2078
void setPoint(const Vector2 &point)
Sets the location of the image point of this object.
Definition Database.h:2109
Index32 dataObjectPointId
The id of the object point which belongs to this object.
Definition Database.h:519
Index32 objectPointId() const
Returns the ids of the 3D object point which belongs to the image point of this object.
Definition Database.h:2104
void setPoseId(const Index32 poseId)
Sets the id of the pose belonging to this image point object.
Definition Database.h:2114
Index32 dataPoseId
The id of the pose which belongs to this object.
Definition Database.h:516
void setObjectPointId(const Index32 objectPointId)
Sets the id of the object point belonging to this image point object.
Definition Database.h:2119
const Vector2 & point() const
Returns the 2D location of the image point of this object.
Definition Database.h:2094
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
Index32 objectImagePointId
The image point id of this object.
Definition Database.h:139
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:2185
ObjectPointData(const Vector3 &point=invalidObjectPoint(), const Scalar priority=-1)
Creates an object with invalid object point.
Definition Database.h:2168
void setPriority(const Scalar priority)
Sets (changes) the priority value of this object.
Definition Database.h:2190
Vector3 dataPoint
The 3D object point of this object.
Definition Database.h:641
Scalar dataPriority
The priority value of this object.
Definition Database.h:644
Scalar priority() const
Returns the priority value of this object.
Definition Database.h:2180
const Vector3 & point() const
Returns the 3D object point of this object.
Definition Database.h:2175
This class implements an object storing an id of an object point.
Definition Database.h:146
Index32 objectObjectPointId
The object point id of this object.
Definition Database.h:170
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
Scalar dataFov
The field of view value of this object.
Definition Database.h:597
PoseData(const HomogenousMatrix4 &world_T_camera=HomogenousMatrix4(false), const Scalar fov=-1)
Creates a new object with specified pose.
Definition Database.h:2141
void setPose(const HomogenousMatrix4 &world_T_camera)
Sets (changes) the pose of this object.
Definition Database.h:2158
const HomogenousMatrix4 & pose() const
Returns the pose of this object.
Definition Database.h:2148
void setFov(const Scalar fov)
Sets (changes) the field of view value of this object.
Definition Database.h:2163
Scalar fov() const
Returns the field of view value of this object.
Definition Database.h:2153
HomogenousMatrix4 world_T_camera_
The pose of this object.
Definition Database.h:594
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
Index32 objectPoseId
The camera pose id of this object.
Definition Database.h:201
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:3011
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:2316
std::unordered_map< Index64, Index32 > Index64To32Map
Definition of an (unordered) map mapping 64 bit ids to 32 bit ids.
Definition Database.h:670
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:2897
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
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:5093
Lock databaseLock
The lock for the entire database.
Definition Database.h:1902
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
void renameObjectPoint(const Index32 oldObjectPointId, const Index32 newObjectPointId)
Renames an object point, changes the id of the object point respectively.
Definition Database.h:3200
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:3621
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:3634
void removeObjectPoint(const Index32 objectPointId)
Removes an object point from this database.
Definition Database.h:3131
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:3829
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:3757
void clear()
Clears the database including all camera poses, object points, image points and any topology.
Definition Database.h:4877
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:4013
std::map< Index32, Vector2 > IdPointMap
Definition of a map mapping ids to 2D image point object.
Definition Database.h:84
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:3552
std::vector< TopologyTriple > TopologyTriples
Definition of a vector holding object of topology triple.
Definition Database.h:255
std::vector< Vectors2 > ImagePointGroups
Definition of a vector holding 2D vectors.
Definition Database.h:109
void detachImagePointFromObjectPoint(const Index32 imagePointId)
Detaches an image point from an object point (withdraws the topology).
Definition Database.h:3523
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:4437
bool hasImagePoint(const Index32 imagePointId, Vector2 *imagePoint=nullptr) const
Returns whether this database holds a specified image point.
Definition Database.h:2954
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:4846
PoseMap databasePoseMap
The map mapping unique pose ids to pose data instances.
Definition Database.h:1881
Index32 databaseImagePointIdCounter
The counter for unique image point ids.
Definition Database.h:1899
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:2267
static Index64 index64(const Index32 first, const Index32 second)
Returns the 64 bit index composed of two 32 bit indices.
Definition Database.h:5164
size_t numberImagePointsFromObjectPoint(const Index32 objectPointId) const
Returns the number of image point observations which belong to a given object point.
Definition Database.h:3350
void setObjectPointPriority(const Index32 objectPointId, const Scalar priority)
Sets (changes) the priority value of an object point.
Definition Database.h:3689
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:4651
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:5000
const IndexSet32 & imagePointsFromPose(const Index32 poseId) const
Returns all image points which belong to a given camera pose.
Definition Database.h:3447
std::vector< IdPointPair > IdPointPairs
Definition of a vector holding pairs of ids and 2D image points.
Definition Database.h:94
Indices32 poseIds(const HomogenousMatrix4 &referencePose, HomogenousMatrices4 *poses=nullptr) const
Returns the ids of specific 6DOF poses.
Definition Database.h:2552
ImagePointMap databaseImagePointMap
The map mapping unique image points ids to image point data instances.
Definition Database.h:1887
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:3312
void removeImagePoint(const Index32 imagePointId)
Removes an image point from this database.
Definition Database.h:2979
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:2881
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
bool hasPose(const Index32 poseId, HomogenousMatrix4 *pose=nullptr) const
Returns whether this database holds a specified camera pose.
Definition Database.h:3276
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:3162
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:2598
std::unordered_map< Index32, Index32 > Index32To32Map
Definition of an (unordered) map mapping 32 bit ids to 32 bit ids.
Definition Database.h:665
static Index32 secondIndex(const Index64 index)
Returns the second 32 bit index of a 64 bit index.
Definition Database.h:5159
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:2668
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:3365
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:3496
Database & operator=(const Database &database)
Assign operator copying a second database to this database object.
Definition Database.h:5049
size_t imagePointNumber() const
Returns the number of image point ids in this database.
Definition Database.h:2259
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:3027
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:2343
ObjectPointMap databaseObjectPointMap
The map mapping unique object point ids to object point data instances.
Definition Database.h:1884
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:4893
void setImagePoint(const Index32 imagePointId, const Vector2 &imagePoint)
Sets (changes) an image point.
Definition Database.h:3608
const IndexSet32 & imagePointsFromObjectPoint(const Index32 objectPointId) const
Returns all image points which belong to a given object point.
Definition Database.h:3460
Vectors3 objectPoints() const
Returns the positions of all 3D object points.
Definition Database.h:2379
Index32 addImagePoint(const Vector2 &imagePoint)
Adds a new 2D image point to this database.
Definition Database.h:2970
std::map< Index32, IdPointPairs > IdIdPointPairsMap
Definition of a map mapping ids to 2D image point id pairs.
Definition Database.h:99
unsigned int numberValidPoses(const Index32 objectPointId, const IndexSet32 &imagePointIds) const
Counts the number of valid poses of a given object point.
Definition Database.h:5126
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:2759
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:3293
std::unordered_map< Index32, ObjectPointData > ObjectPointMap
Definition of an (unordered) map mapping object point ids to object point data objects.
Definition Database.h:655
void setPoses(const Index32 *poseIds, const HomogenousMatrix4 *poses, const size_t number)
Sets (changes) a set of poses.
Definition Database.h:3715
Index32 objectPointFromImagePoint(const Index32 imagePointId) const
Returns the object point which belongs to a given image point.
Definition Database.h:3434
bool isEmpty() const
Returns whether this database holds at least one image point, one object point or one camera pose.
Definition Database.h:2235
IndexSet32 posesFromObjectPoint(const Index32 objectPointId) const
Returns all poses which belong to a given object point.
Definition Database.h:3473
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:5103
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:2794
size_t poseNumber() const
Returns the number of poses of this database.
Definition Database.h:2243
Index64To32Map databasePoseObjectPointMap
The map mapping a pair of pose id and object point id to image point ids.
Definition Database.h:1890
Index32 databaseObjectPointIdCounter
The counter for unique object point ids.
Definition Database.h:1896
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 setPose(const Index32 poseId, const HomogenousMatrix4 &pose)
Sets (changes) a pose.
Definition Database.h:3702
Lock & lock()
Returns a reference to the lock object of this database object.
Definition Database.h:2229
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:4789
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:2729
static Index32 firstIndex(const Index64 index)
Returns the first 32 bit index of a 64 bit index.
Definition Database.h:5154
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:5028
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:2368
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:2584
Database()
Creates a new empty database object.
Definition Database.h:2195
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:2251
std::vector< PoseImagePointPair > PoseImagePointTopology
Definition of a vector holding several pairs of pose and image point ids.
Definition Database.h:245
void detachImagePointFromPose(const Index32 imagePointId)
Detaches an image point from a camera pose (withdraws the topology).
Definition Database.h:3579
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:3337
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:2630
unsigned int databasePoses
The number of poses.
Definition Database.h:1893
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:3048
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:4519
Vectors2 imagePoints(const Indices32 &imagePointIds) const
Returns the positions of 2D image points specified by the ids of the image points.
Definition Database.h:2278
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:4986
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:3233
std::map< Index32, Vectors2 > ImagePointsMap
Definition of a map mapping ids to 2D vectors.
Definition Database.h:104
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:4396
std::pair< Index32, Vector2 > IdPointPair
Definition of a pair of ids and 2D image points.
Definition Database.h:89
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:5014
bool isNull() const
Returns whether this vector is a null vector up to a small epsilon.
Definition Vector3.h:866
const T * data() const noexcept
Returns an pointer to the vector elements.
Definition Vector3.h:854
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::set< Index32 > IndexSet32
Definition of a set holding 32 bit indices.
Definition Base.h:114
uint64_t Index64
Definition of a 64 bit index value.
Definition Base.h:90
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
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< 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
std::vector< SquareMatrix3 > SquareMatrices3
Definition of a vector holding SquareMatrix3 objects.
Definition SquareMatrix3.h:71
std::vector< Vector2 > Vectors2
Definition of a vector holding Vector2 objects.
Definition Vector2.h:64
HomogenousMatrixT4< Scalar > HomogenousMatrix4
Definition of the HomogenousMatrix4 object, depending on the OCEAN_MATH_USE_SINGLE_PRECISION flag eit...
Definition HomogenousMatrix4.h:44
std::vector< Vector3 > Vectors3
Definition of a vector holding Vector3 objects.
Definition Vector3.h:65
VectorT2< Scalar > Vector2
Definition of a 2D vector.
Definition Vector2.h:28
The namespace covering the entire Ocean framework.
Definition Accessor.h:15