Ocean
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"
14 #include "ocean/base/ShiftVector.h"
15 #include "ocean/base/Subset.h"
16 #include "ocean/base/Worker.h"
17 
20 
21 namespace Ocean
22 {
23 
24 namespace 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  */
66 class 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 
1906 {
1908 }
1909 
1910 template <bool tThreadSafe>
1912  accessorDatabase(database),
1913  accessorImagePointIds(imagePointIds)
1914 {
1915  // nothing to do here
1916 }
1917 
1918 template <bool tThreadSafe>
1920 {
1921  return accessorImagePointIds.size();
1922 }
1923 
1924 template <bool tThreadSafe>
1926 {
1927  ocean_assert(index < accessorImagePointIds.size());
1928  return accessorDatabase.imagePoint<tThreadSafe>(accessorImagePointIds[index]);
1929 }
1930 
1931 template <bool tThreadSafe>
1933  accessorDatabase(database),
1934  accessorTopology(topology)
1935 {
1936  // nothing to do here
1937 }
1938 
1939 template <bool tThreadSafe>
1941 {
1942  return accessorTopology.size();
1943 }
1944 
1945 template <bool tThreadSafe>
1947 {
1948  ocean_assert(index < accessorTopology.size());
1949  return accessorDatabase.imagePoint<tThreadSafe>(accessorTopology[index].imagePointId());
1950 }
1951 
1952 template <bool tThreadSafe>
1954  accessorDatabase(database),
1955  accessorObjectPointIds(objectPointIds)
1956 {
1957  // nothing to do here
1958 }
1959 
1960 template <bool tThreadSafe>
1962 {
1963  return accessorObjectPointIds.size();
1964 }
1965 
1966 template <bool tThreadSafe>
1968 {
1969  ocean_assert(index < accessorObjectPointIds.size());
1970  return accessorDatabase.objectPoint<tThreadSafe>(accessorObjectPointIds[index]);
1971 }
1972 
1973 template <bool tThreadSafe>
1975  accessorDatabase(database),
1976  accessorPoseIds(poseIds)
1977 {
1978  // nothing to do here
1979 }
1980 
1981 template <bool tThreadSafe>
1983 {
1984  return accessorPoseIds.size();
1985 }
1986 
1987 template <bool tThreadSafe>
1989 {
1990  ocean_assert(index < accessorPoseIds.size());
1991  return accessorDatabase.pose<tThreadSafe>(accessorPoseIds[index]);
1992 }
1993 
1994 template <bool tThreadSafe>
1996  accessorDatabase(database),
1997  accessorTopology(topology)
1998 {
1999  // nothing to do here
2000 }
2001 
2002 template <bool tThreadSafe>
2004 {
2005  return accessorTopology.size();
2006 }
2007 
2008 template <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 
2058 inline void Database::PoseObject::setPoseId(const Index32 poseId)
2059 {
2060  objectPoseId = poseId;
2061 }
2062 
2063 inline 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 
2071 inline 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 
2086 inline 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 
2119 inline void Database::ImagePointData::setObjectPointId(const Index32 objectPointId)
2120 {
2121  dataObjectPointId = objectPointId;
2122 }
2123 
2125 {
2126  return dataImagePointIds;
2127 }
2128 
2129 inline void Database::Data::registerImagePoint(const Index32 imagePointId)
2130 {
2131  ocean_assert(dataImagePointIds.find(imagePointId) == dataImagePointIds.end());
2132  dataImagePointIds.insert(imagePointId);
2133 }
2134 
2135 inline void Database::Data::unregisterImagePoint(const Index32 imagePointId)
2136 {
2137  ocean_assert(dataImagePointIds.find(imagePointId) != dataImagePointIds.end());
2138  dataImagePointIds.erase(imagePointId);
2139 }
2140 
2141 inline 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 
2158 inline void Database::PoseData::setPose(const HomogenousMatrix4& world_T_camera)
2159 {
2160  world_T_camera_ = world_T_camera;
2161 }
2162 
2163 inline void Database::PoseData::setFov(const Scalar fov)
2164 {
2165  dataFov = fov;
2166 }
2167 
2168 inline 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 
2203 inline 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 
2215 inline 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 
2234 template <bool tThreadSafe>
2235 inline bool Database::isEmpty() const
2236 {
2238 
2239  return databasePoseMap.empty() && databaseObjectPointMap.empty() && databaseImagePointMap.empty();
2240 }
2241 
2242 template <bool tThreadSafe>
2243 inline size_t Database::poseNumber() const
2244 {
2246 
2247  return databasePoseMap.size();
2248 }
2249 
2250 template <bool tThreadSafe>
2251 inline size_t Database::objectPointNumber() const
2252 {
2254 
2255  return databaseObjectPointMap.size();
2256 }
2257 
2258 template <bool tThreadSafe>
2259 inline size_t Database::imagePointNumber() const
2260 {
2262 
2263  return databaseImagePointMap.size();
2264 }
2265 
2266 template <bool tThreadSafe>
2267 inline 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 
2277 template <bool tThreadSafe>
2278 inline 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 
2296 template <bool tThreadSafe>
2297 inline 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 
2315 template <bool tThreadSafe>
2316 inline 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 
2342 template <bool tThreadSafe>
2343 inline 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 
2353 template <bool tThreadSafe>
2354 inline 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 
2367 template <bool tThreadSafe>
2368 inline 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 
2378 template <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 
2392 template <bool tThreadSafe, bool tMatchPosition>
2393 inline 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 
2424 template <bool tThreadSafe>
2425 inline 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 
2443 template <bool tThreadSafe>
2444 inline 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 
2454 template <bool tThreadSafe>
2455 inline 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 
2473 template <bool tThreadSafe>
2474 inline 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 
2496 template <bool tThreadSafe, bool tMatchPose>
2497 inline 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 
2528 template <bool tThreadSafe>
2529 inline 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 
2551 template <bool tThreadSafe, bool tMatchPose>
2552 inline 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 
2583 template <bool tThreadSafe>
2584 inline 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 
2597 template <bool tThreadSafe>
2598 inline 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 
2629 template <bool tThreadSafe>
2630 inline 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 
2667 template <bool tThreadSafe>
2668 inline 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 
2728 template <bool tThreadSafe, bool tMatchPosition, bool tNeedValidPose>
2729 inline 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 
2758 template <bool tThreadSafe, bool tMatchPosition, bool tNeedValidPose>
2759 inline 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 
2793 template <bool tThreadSafe>
2794 inline 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 
2880 template <bool tThreadSafe>
2881 inline 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 
2896 template <bool tThreadSafe, bool tMatchPosition, bool tNeedValidPose>
2897 inline 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 
2925 template <bool tThreadSafe, bool tMatchPosition, bool tNeedValidPose>
2926 inline 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 
2953 template <bool tThreadSafe>
2954 inline 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 
2969 template <bool tThreadSafe>
2970 inline Index32 Database::addImagePoint(const Vector2& imagePoint)
2971 {
2973 
2976 }
2977 
2978 template <bool tThreadSafe>
2979 inline 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 
3010 template <bool tThreadSafe>
3011 inline 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 
3026 template <bool tThreadSafe>
3027 inline 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 
3037 template <bool tThreadSafe>
3038 inline 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 
3048 inline 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 
3130 template <bool tThreadSafe>
3131 inline 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 
3161 template <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 
3199 template <bool tThreadSafe>
3200 inline 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 
3232 template <bool tThreadSafe>
3233 inline 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 
3275 template <bool tThreadSafe>
3276 inline 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 
3292 template <bool tThreadSafe>
3293 inline 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 
3311 template <bool tThreadSafe>
3312 inline 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 
3336 template <bool tThreadSafe>
3337 inline 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 
3349 template <bool tThreadSafe>
3350 inline 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 
3364 template <bool tThreadSafe>
3365 inline 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 
3400 template <bool tThreadSafe>
3401 inline 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 
3433 template <bool tThreadSafe>
3434 inline Index32 Database::objectPointFromImagePoint(const Index32 imagePointId) const
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 
3446 template <bool tThreadSafe>
3447 inline 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 
3459 template <bool tThreadSafe>
3460 inline 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 
3472 template <bool tThreadSafe>
3473 inline 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 
3495 template <bool tThreadSafe>
3496 inline 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 
3522 template <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 
3551 template <bool tThreadSafe>
3552 inline 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 
3578 template <bool tThreadSafe>
3579 inline 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 
3607 template <bool tThreadSafe>
3608 inline 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 
3620 template <bool tThreadSafe>
3621 inline 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 
3633 template <bool tThreadSafe>
3634 inline 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 
3649 template <bool tThreadSafe>
3650 inline 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 
3665 template <bool tThreadSafe>
3666 inline 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 
3674 template <bool tThreadSafe>
3675 inline 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 
3688 template <bool tThreadSafe>
3689 inline 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 
3701 template <bool tThreadSafe>
3702 inline 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 
3714 template <bool tThreadSafe>
3715 inline 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 
3730 template <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 
3747 template <bool tThreadSafe>
3748 inline void Database::setPoses(const HomogenousMatrix4& pose)
3749 {
3751 
3752  for (PoseMap::iterator i = databasePoseMap.begin(); i != databasePoseMap.end(); ++i)
3753  i->second.setPose(pose);
3754 }
3755 
3756 template <bool tThreadSafe>
3757 const IndexSet32& Database::imagePointIds(const Index32 poseId) const
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 
3769 template <bool tThreadSafe>
3770 inline 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 
3800 template <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 
3828 template <bool tThreadSafe>
3829 Indices32 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 
3870 template <bool tThreadSafe>
3871 Indices32 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 
3888 template <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 
3919 template <bool tThreadSafe>
3920 Vectors2 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 
3952 template <bool tThreadSafe, bool tMatchPosition>
3953 Indices32 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 
3981 template <bool tThreadSafe, bool tMatchPosition>
3982 Indices32 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 
4012 template <bool tThreadSafe, bool tMatchPosition>
4013 inline 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 
4037 template <bool tThreadSafe>
4038 Indices32 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 
4082 template <bool tThreadSafe, bool tMatchPosition>
4083 Indices32 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 
4132 template <bool tThreadSafe>
4133 Indices32 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 
4184 template <bool tThreadSafe, bool tMatchPosition, bool tVisibleInAllPoses>
4185 Indices32 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 
4288 template <bool tThreadSafe, bool tMatchPosition, bool tVisibleInAllPoses>
4289 Indices32 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 
4395 template <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 
4436 template <bool tThreadSafe>
4437 Vectors2 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 
4473 template <bool tThreadSafe>
4474 Vectors2 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 
4483 template <bool tThreadSafe>
4484 Vectors2 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 
4518 template <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 
4559 template <bool tThreadSafe>
4560 Database::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 
4610 template <bool tThreadSafe>
4611 void 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 
4650 template <bool tThreadSafe, bool tMatchPosition>
4651 void 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 
4708 template <bool tThreadSafe, bool tMatchPosition>
4709 void 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 
4788 template <bool tThreadSafe, bool tMatchPose>
4789 void 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 
4845 template <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 
4876 template <bool tThreadSafe>
4877 inline void Database::clear()
4878 {
4880 
4881  databasePoseMap.clear();
4882  databaseObjectPointMap.clear();
4883  databaseImagePointMap.clear();
4885 
4886  databasePoses = 0u;
4887 
4890 }
4891 
4892 template <bool tThreadSafe>
4893 inline 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 
4908 template <typename T, bool tThreadSafe>
4909 void 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());
4925  databasePoseMap.emplace(poseId, PoseData(HomogenousMatrix4(pose)));
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];
4936  const VectorT3<T>& objectPoint = objectPoints[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];
4960  const VectorT2<T>& imagePoint = imagePoints[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 
4986 inline 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 
5000 inline 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 
5014 inline 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 
5028 inline 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 
5049 inline Database& Database::operator=(const Database& database)
5050 {
5051  if (this != &database)
5052  {
5053  databasePoseMap = database.databasePoseMap;
5057 
5058  databasePoses = database.databasePoses;
5061  }
5062 
5063  return *this;
5064 }
5065 
5066 inline 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 
5087 inline Database::operator bool() const
5088 {
5089  return !isEmpty<false>();
5090 }
5091 
5092 template <bool tMatchPosition, bool tNeedValidPose>
5093 inline 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 
5102 template <bool tMatchPosition>
5103 void 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 
5126 inline 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 
5164 inline 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:854
const T * data() const noexcept
Returns an pointer to the vector elements.
Definition: Vector3.h:842
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
SquareMatrixT3< Scalar > SquareMatrix3
Definition of the SquareMatrix3 object, depending on the OCEAN_MATH_USE_SINGLE_PRECISION either with ...
Definition: SquareMatrix3.h:35
float Scalar
Definition of a scalar type.
Definition: Math.h:128
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:144
VectorT3< Scalar > Vector3
Definition of a 3D vector.
Definition: Vector3.h:22
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:37
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:21
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15