Ocean
OfflineTracker.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_OFFLINE_OFFLINE_TRACKER_H
9 #define META_OCEAN_TRACKING_OFFLINE_OFFLINE_TRACKER_H
10 
14 
15 #include "ocean/base/ObjectRef.h"
16 #include "ocean/base/Thread.h"
17 
20 
21 namespace Ocean
22 {
23 
24 namespace Tracking
25 {
26 
27 namespace Offline
28 {
29 
30 // Forward declaration.
31 class OfflineTracker;
32 
33 /**
34  * Definition of an object reference holding an offline tracker object.
35  * @ingroup trackingoffline
36  */
38 
39 /**
40  * This class is the base class for all offline tracker objects.
41  * @see OfflineTrackerRef.
42  * @ingroup trackingoffline
43  */
44 class OCEAN_TRACKING_OFFLINE_EXPORT OfflineTracker : protected Thread
45 {
46  friend class EventStackLayer;
47 
48  public:
49 
50  /**
51  * Definition of individual tracking qualities.
52  */
54  {
55  /// A low tracking quality with high performance.
57  /// A moderate tracking quality with moderate performance.
59  /// A high tracking quality with low performance.
61  /// A very high tracking quality with very low performance.
63  /// An insane tracking quality with very low performance.
65  /// Automatic tracking quality.
67  /// Coverage with coarse grid
69  /// Coverage with fine grid
70  TQ_FINE
71  };
72 
73  /**
74  * Definition of individual abstract camera motion types.
75  */
77  {
78  /// An unknown abstract camera motion.
80  /// A pure rotational camera motion.
82  /// A complex camera motion (may include rotational and translational motion).
83  AMT_COMPLEX
84  };
85 
86  /**
87  * Definition of individual camera models.
88  */
90  {
91  /// Invalid camera model parameter.
93  /// Low quality camera, equivalent to a state-of-the-art webcams.
95  /// Medium camera model, equivalent to an amateur camera.
97  /// High quality camera, equivalent to a professional cinema camera.
98  CM_HIGH_QUALITY
99  };
100 
101  /**
102  * Definition of a component event callback function.
103  * The first parameter provides the event.
104  */
106 
107  /**
108  * Frees the offline tracker object.
109  */
110  virtual ~OfflineTracker();
111 
112  protected:
113 
114  /**
115  * This class implements one layer in a progress event stack allowing to define the start and stop progress value.
116  * The start and stop progress values are relative progress values in relation to the next older layer of the stack.<br>
117  * Thus, by application of individual layers an hierarchy of progress states can be created.<br>
118  */
120  {
121  public:
122 
123  /**
124  * Creates a new layer object.
125  * @param startProgress The start progress value defined relative to the next older layer of the stack, with range [0, 1]
126  * @param stopProgress The stop progress value defined relative to the next older layer of the stack, with range [startProgress, 1]
127  */
128  inline EventStackLayer(const Scalar startProgress, const Scalar stopProgress);
129 
130  /**
131  * Returns the relative start progress value of this object.
132  * @return Relative start progress value
133  */
134  inline Scalar startProgress() const;
135 
136  /**
137  * Returns the relative stop progress value of this object.
138  * @return Relative stop progress value
139  */
140  inline Scalar stopProgress() const;
141 
142  /**
143  * Returns whether two objects have identical start and stop values.
144  * @param layer The second value to compare
145  * @return True, if so
146  */
147  inline bool operator==(const EventStackLayer& layer) const;
148 
149  protected:
150 
151  /// The relative start progress value of this object.
152  Scalar startProgress_ = Scalar(0);
153 
154  /// the relative stop progress value of this object.
155  Scalar stopProgress_ = Scalar(0);
156  };
157 
158  /**
159  * This class implements an event stack layer object that pushes the relative progress parameters on the stack during creation and pops the layer if the object is disposed.
160  * Further, the relative progress values of this object can be changed after the creation.<br>
161  */
163  {
164  public:
165 
166  /**
167  * Move constructor.
168  * @param scopedLayer Scoped layer to move
169  */
170  inline ScopedEventStackLayer(ScopedEventStackLayer&& scopedLayer) noexcept;
171 
172  /**
173  * Creates a new object by the given owner of the event stack and two relative progress parameters.
174  * @param owner The owner of the stack in which the progress values are pushed
175  * @param startProgress The start progress value defined relative to the next older layer of the stack, with range [0, 1]
176  * @param stopProgress The stop progress value defined relative to the next older layer of the stack, with range [startProgress, 1]
177  */
178  inline ScopedEventStackLayer(OfflineTracker& owner, const Scalar startProgress, const Scalar stopProgress);
179 
180  /**
181  * Destructs the scoped layer object and pops the relative progress values from the stack.
182  */
183  inline ~ScopedEventStackLayer();
184 
185  /**
186  * Releases this scoped layer object explicitly before the scope ends.
187  */
188  inline void release();
189 
190  /**
191  * Modifies the relative start and stop progress values of this object.
192  * @param startProgress The start progress value defined relative to the next older layer of the stack, with range [0, 1]
193  * @param stopProgress The stop progress value defined relative to the next older layer of the stack, with range [startProgress, 1]
194  */
195  inline void modify(const Scalar startProgress, const Scalar stopProgress);
196 
197  /**
198  * Modifies the relative start and stop progress values of this object by using the previous stop progress value as new start progress value and taking the new value as new stop progress value.
199  * @param stopProgress The stop progress value defined relative to the next older layer of the stack, with range [stopProgress(), 1]
200  */
201  inline void modify(const Scalar stopProgress);
202 
203  /**
204  * Move operator.
205  * @param scopedLayer The scoped layer object to move
206  * @return Reference to this object
207  */
208  inline ScopedEventStackLayer& operator=(ScopedEventStackLayer&& scopedLayer) noexcept;
209 
210  private:
211 
212  /**
213  * Copy constructor.
214  */
216 
217  /**
218  * Assign operator.
219  * @return Reference to this object
220  */
222 
223  protected:
224 
225  /// The owner of the stack that is associated with this object.
226  OfflineTracker* owner_ = nullptr;
227  };
228 
229  /**
230  * Definition of a vector holding EventStackLayer objects which actually is used to implement a stack of these objects.
231  */
232  typedef std::vector<EventStackLayer> EventStack;
233 
234  /**
235  * Definition of a vector holding event callback functions.
236  */
238 
239  public:
240 
241  /**
242  * Starts the offline tracker.
243  * @return True, if succeeded
244  * @see stop(), finished().
245  */
246  virtual bool start();
247 
248  /**
249  * Stops the offline tracker.
250  * All poses that have been determined since the start of the tracker will be untouched.<br>
251  * @param timeout if 0, this call is asynchronous and will return immediately. Otherwise wait time in ms or -1 for infinite wait
252  * @return True, if succeeded
253  * @see start().
254  */
255  virtual bool stop(const unsigned int timeout = 0u);
256 
257  /**
258  * Returns the unique id of this tracker object.
259  * Each tracker has an own unique id allowing to separate individual trackers or their events.
260  * @return Unique tracker id
261  */
262  inline unsigned int id() const;
263 
264  /**
265  * Returns whether the tracker has been started (and is currently tracking).
266  * @return True, if so
267  */
268  virtual bool running() const;
269 
270  /**
271  * Returns whether the offline tracker has finished since the last start or has not been started yet.
272  * @return True, if so
273  * @see start().
274  */
275  virtual bool finished() const;
276 
277  /**
278  * Returns whether the offline tracker has finished and succeeded since the last start or has not been started yet.
279  * @return True, if so
280  * @see finished().
281  */
282  virtual bool succeeded() const = 0;
283 
284  /**
285  * Returns the currently determined poses of this tracker.
286  * @return Tracker poses
287  */
288  virtual OfflinePoses poses() const;
289 
290  /**
291  * Returns one pose of this tracker.
292  * @param index The index of the frame for that the pose will be returned
293  * @return Tracker pose
294  */
295  virtual OfflinePose pose(const unsigned int index) const;
296 
297  /**
298  * Adds a state event callback function.
299  * @param callback The callback function to be added
300  */
301  inline void addEventCallback(const EventCallback& callback);
302 
303  /**
304  * Removes a state event callback function.
305  * @param callback The callback function to be removed
306  */
307  inline void removeEventCallback(const EventCallback& callback);
308 
309  protected:
310 
311  /**
312  * Creates a new offline tracker object.
313  */
315 
316  /**
317  * Checks whether the camera parameters of a given camera profiles matches to the specified camera model.
318  * @param pinholeCamera The pinhole camera profile that will be checked
319  * @param model The model to that the camera profiles must match
320  * @return True, if so
321  */
322  static bool isPlausibleCamera(const PinholeCamera& pinholeCamera, const CameraModel model);
323 
324  /**
325  * Updates the tracker process progress value of this tracker.
326  * This tracker stores a stack with EventStackLayer objects defining a hierarchy of individual relative progress ranges.<br>
327  * The given progress value should be independent of any stack layer and should simply give the progress state of e.g. a component.<br>
328  * @param localProgress The local progress value of e.g. a component, with range [0, 1]
329  */
330  void updateTrackerProgress(const Scalar localProgress);
331 
332  /**
333  * Updates all poses of this tracker and invokes the corresponding state event(s).
334  * @param poses New poses for this tracker
335  */
336  void updatePoses(const OfflinePoses& poses);
337 
338  /**
339  * Removes irregular poses at the boundary between valid and invalid poses.
340  * A pose is voted as irregular if the rotation angle between two successive frame is larger than the median rotation angle (between successive frame) multiplied by a factor.
341  * @param factor The factor that is multiplied with the media angle
342  */
343  void removeIrregularPoses(const Scalar factor = Scalar(5));
344 
345  /**
346  * Extrapolates poses at the boundary between valid and invalid poses.
347  * @param number The number of poses that will be extrapolated at each border
348  * @param base The maximal number of poses that are used as interpolation base
349  */
350  void extrapolatePoses(const unsigned int number, const unsigned int base);
351 
352  /**
353  * Interpolates the pose of a single invalid pose which is enclosed by two valid poses.
354  * @param invalidIndex The index of the (single) invalid pose
355  * @param offlinePoses The offline poses on which the poses are extrapolated
356  */
358 
359  /**
360  * Interpolates some poses to the left of a gap with invalid poses.
361  * @param invalidIndex The index of the invalid pose with valid poses on the right
362  * @param number The number of poses that will be extrapolated in the left area
363  * @param base The maximal number of poses that are used as interpolation base
364  * @param offlinePoses The offline poses on which the poses are extrapolated
365  */
366  static void extrapolateLeftPoses(const OfflinePoses::Index invalidIndex, const unsigned int number, const unsigned int base, OfflinePoses& offlinePoses);
367 
368  /**
369  * Interpolates some poses to the right of a gap with invalid poses.
370  * @param invalidIndex The index of the invalid pose with valid poses on the left
371  * @param number The number of poses that will be extrapolated in the right area
372  * @param base The maximal number of poses that are used as interpolation base
373  * @param offlinePoses The offline poses on which the poses are extrapolated
374  */
375  static void extrapolateRightPoses(const OfflinePoses::Index invalidIndex, const unsigned int number, const unsigned int base, OfflinePoses& offlinePoses);
376 
377  /**
378  * Interpolates some poses to the left or to the right of a gap with invalid poses.
379  * @param invalidIndex The index of the invalid pose with valid poses
380  * @param number The number of poses that will be extrapolated in the area
381  * @param base The maximal number of poses that are used as interpolation base
382  * @param offlinePoses The offline poses on which the poses are extrapolated
383  */
384  static void extrapolateCenterPoses(const OfflinePoses::Index invalidIndex, const unsigned int number, const unsigned int base, OfflinePoses& offlinePoses);
385 
386  /**
387  * Returns a reference to the lock for the tracker id counter.
388  * @return The lock for the tracker id counter
389  */
390  static Lock& idCounterLock();
391 
392  private:
393 
394  /**
395  * Pushes a new progress event stack layer on the stack of this tracker.
396  * Do not call this function, this function will be called by the ScopedEventStackLayer object only.
397  * @param layer New layer to be pushed
398  * @see ScopedEventStackLayer
399  */
401 
402  /**
403  * Pops a progress event stack layer from the stack of this tracker.
404  * Do not call this function, this function will be called by the ScopedEventStackLayer object only.
405  * @param layer New layer to be pushed
406  * @see ScopedEventStackLayer
407  */
409 
410  protected:
411 
412  /// The unique id that identifies this tracker.
413  unsigned int id_ = 0u;
414 
415  /// Finished state of the tracker.
416  bool finished_ = true;
417 
418  /// Stop-request state of the tracker, this state should have the same state as the threadShouldStop variable but will be accessible in all trackers.
419  bool shouldStop_ = false;
420 
421  /// Offline poses of this tracker.
423 
424  /// State event callback functions.
426 
427  /// Tracker lock object.
428  mutable Lock lock_;
429 
430  /// The stack with progress event layers allowing for a convenient process progress event handling.
432 
433  /// The lock for the progress event layer stack.
435 
436  /// The previous process progress.
437  Scalar previousProcessProgress_ = Scalar(0);
438 
439  /// The tracker id counter.
440  static unsigned int idCounter_;
441 };
442 
443 inline OfflineTracker::EventStackLayer::EventStackLayer(const Scalar startProgress, const Scalar stopProgress) :
444  startProgress_(startProgress),
445  stopProgress_(stopProgress)
446 {
447  ocean_assert(startProgress <= stopProgress);
448  ocean_assert(startProgress >= Scalar(0) && stopProgress <= Scalar(1));
449 }
450 
452 {
453  return startProgress_;
454 }
455 
457 {
458  return stopProgress_;
459 }
460 
462 {
463  return startProgress_ == layer.startProgress_ && stopProgress_ == layer.stopProgress_;
464 }
465 
467  EventStackLayer(scopedLayer.startProgress_, scopedLayer.stopProgress_),
468  owner_(scopedLayer.owner_)
469 {
470  scopedLayer.owner_ = nullptr;
471 }
472 
473 inline OfflineTracker::ScopedEventStackLayer::ScopedEventStackLayer(OfflineTracker& owner, const Scalar startProgress, const Scalar stopProgress) :
474  EventStackLayer(startProgress, stopProgress),
475  owner_(&owner)
476 {
478 }
479 
481 {
482  release();
483 }
484 
486 {
487  if (owner_)
488  {
489  owner_->popProgressEventStackLayer(*this);
490  owner_ = nullptr;
491  }
492 }
493 
494 void OfflineTracker::ScopedEventStackLayer::modify(const Scalar startProgress, const Scalar stopProgress)
495 {
496  ocean_assert(owner_);
497 
498  if (owner_)
499  {
500  ocean_assert(startProgress <= stopProgress);
501  ocean_assert(startProgress >= Scalar(0) && stopProgress <= Scalar(1));
502 
503  owner_->popProgressEventStackLayer(*this);
504 
505  startProgress_ = startProgress;
506  stopProgress_ = stopProgress;
507 
508  owner_->pushProgressEventStackLayer(*this);
509  }
510 }
511 
513 {
514  modify(stopProgress_, stopProgress);
515 }
517 {
518  if (this != &scopedLayer)
519  {
520  release();
521 
522  owner_ = scopedLayer.owner_;
523  scopedLayer.owner_ = nullptr;
524  }
525 
526  return *this;
527 }
528 
529 inline unsigned int OfflineTracker::id() const
530 {
531  return id_;
532 }
533 
535 {
536  eventCallbacks_.addCallback(callback);
537 }
538 
540 {
542 }
543 
544 }
545 
546 }
547 
548 }
549 
550 #endif // META_OCEAN_TRACKING_OFFLINE_OFFLINE_TRACKER_H
This class implements a container for callback functions.
Definition: Callback.h:3456
void addCallback(const T &callback)
Adds a new callback object.
Definition: Callback.h:4304
void removeCallback(const T &callback)
Removes a callback object.
Definition: Callback.h:4329
This class implements a recursive lock object.
Definition: Lock.h:31
This template class implements a object reference with an internal reference counter.
Definition: base/ObjectRef.h:58
std::ptrdiff_t Index
Definition of an element index.
Definition: ShiftVector.h:38
This class implements a thread.
Definition: Thread.h:115
This class encapsulates the tracking pose data.
Definition: OfflinePose.h:41
This class implements one layer in a progress event stack allowing to define the start and stop progr...
Definition: OfflineTracker.h:120
bool operator==(const EventStackLayer &layer) const
Returns whether two objects have identical start and stop values.
Definition: OfflineTracker.h:461
Scalar startProgress_
The relative start progress value of this object.
Definition: OfflineTracker.h:152
Scalar stopProgress_
the relative stop progress value of this object.
Definition: OfflineTracker.h:155
Scalar stopProgress() const
Returns the relative stop progress value of this object.
Definition: OfflineTracker.h:456
EventStackLayer(const Scalar startProgress, const Scalar stopProgress)
Creates a new layer object.
Definition: OfflineTracker.h:443
Scalar startProgress() const
Returns the relative start progress value of this object.
Definition: OfflineTracker.h:451
This class implements an event stack layer object that pushes the relative progress parameters on the...
Definition: OfflineTracker.h:163
ScopedEventStackLayer & operator=(ScopedEventStackLayer &&scopedLayer) noexcept
Move operator.
Definition: OfflineTracker.h:516
OfflineTracker * owner_
The owner of the stack that is associated with this object.
Definition: OfflineTracker.h:226
ScopedEventStackLayer & operator=(const ScopedEventStackLayer &)=delete
Assign operator.
~ScopedEventStackLayer()
Destructs the scoped layer object and pops the relative progress values from the stack.
Definition: OfflineTracker.h:480
ScopedEventStackLayer(const ScopedEventStackLayer &)=delete
Copy constructor.
void modify(const Scalar startProgress, const Scalar stopProgress)
Modifies the relative start and stop progress values of this object.
Definition: OfflineTracker.h:494
ScopedEventStackLayer(ScopedEventStackLayer &&scopedLayer) noexcept
Move constructor.
Definition: OfflineTracker.h:466
void release()
Releases this scoped layer object explicitly before the scope ends.
Definition: OfflineTracker.h:485
This class is the base class for all offline tracker objects.
Definition: OfflineTracker.h:45
Callback< void, const TrackerEvent & > EventCallback
Definition of a component event callback function.
Definition: OfflineTracker.h:105
void updateTrackerProgress(const Scalar localProgress)
Updates the tracker process progress value of this tracker.
void removeIrregularPoses(const Scalar factor=Scalar(5))
Removes irregular poses at the boundary between valid and invalid poses.
static bool isPlausibleCamera(const PinholeCamera &pinholeCamera, const CameraModel model)
Checks whether the camera parameters of a given camera profiles matches to the specified camera model...
unsigned int id() const
Returns the unique id of this tracker object.
Definition: OfflineTracker.h:529
OfflinePoses offlinePoses_
Offline poses of this tracker.
Definition: OfflineTracker.h:422
std::vector< EventStackLayer > EventStack
Definition of a vector holding EventStackLayer objects which actually is used to implement a stack of...
Definition: OfflineTracker.h:232
void removeEventCallback(const EventCallback &callback)
Removes a state event callback function.
Definition: OfflineTracker.h:539
virtual ~OfflineTracker()
Frees the offline tracker object.
virtual bool succeeded() const =0
Returns whether the offline tracker has finished and succeeded since the last start or has not been s...
static void extrapolateLeftPoses(const OfflinePoses::Index invalidIndex, const unsigned int number, const unsigned int base, OfflinePoses &offlinePoses)
Interpolates some poses to the left of a gap with invalid poses.
virtual bool start()
Starts the offline tracker.
ConcurrentCallbacks< EventCallback > EventCallbacks
Definition of a vector holding event callback functions.
Definition: OfflineTracker.h:237
Lock lock_
Tracker lock object.
Definition: OfflineTracker.h:428
void pushProgressEventStackLayer(const EventStackLayer &layer)
Pushes a new progress event stack layer on the stack of this tracker.
virtual OfflinePose pose(const unsigned int index) const
Returns one pose of this tracker.
unsigned int id_
The unique id that identifies this tracker.
Definition: OfflineTracker.h:413
static void extrapolateCenterPoses(const OfflinePoses::Index invalidIndex, const unsigned int number, const unsigned int base, OfflinePoses &offlinePoses)
Interpolates some poses to the left or to the right of a gap with invalid poses.
TrackingQuality
Definition of individual tracking qualities.
Definition: OfflineTracker.h:54
@ TQ_HIGH
A high tracking quality with low performance.
Definition: OfflineTracker.h:60
@ TQ_COARSE
Coverage with coarse grid.
Definition: OfflineTracker.h:68
@ TQ_ULTRA
A very high tracking quality with very low performance.
Definition: OfflineTracker.h:62
@ TQ_MODERATE
A moderate tracking quality with moderate performance.
Definition: OfflineTracker.h:58
@ TQ_INSANE
An insane tracking quality with very low performance.
Definition: OfflineTracker.h:64
@ TQ_AUTOMATIC
Automatic tracking quality.
Definition: OfflineTracker.h:66
@ TQ_LOW
A low tracking quality with high performance.
Definition: OfflineTracker.h:56
virtual bool running() const
Returns whether the tracker has been started (and is currently tracking).
static void extrapolateRightPoses(const OfflinePoses::Index invalidIndex, const unsigned int number, const unsigned int base, OfflinePoses &offlinePoses)
Interpolates some poses to the right of a gap with invalid poses.
virtual OfflinePoses poses() const
Returns the currently determined poses of this tracker.
static Lock & idCounterLock()
Returns a reference to the lock for the tracker id counter.
static void extrapolateSinglePose(const OfflinePoses::Index invalidIndex, OfflinePoses &offlinePoses)
Interpolates the pose of a single invalid pose which is enclosed by two valid poses.
static unsigned int idCounter_
The tracker id counter.
Definition: OfflineTracker.h:440
void extrapolatePoses(const unsigned int number, const unsigned int base)
Extrapolates poses at the boundary between valid and invalid poses.
void addEventCallback(const EventCallback &callback)
Adds a state event callback function.
Definition: OfflineTracker.h:534
EventStack eventStack_
The stack with progress event layers allowing for a convenient process progress event handling.
Definition: OfflineTracker.h:431
CameraModel
Definition of individual camera models.
Definition: OfflineTracker.h:90
@ CM_LOW_QUALITY
Low quality camera, equivalent to a state-of-the-art webcams.
Definition: OfflineTracker.h:94
@ CM_MEDIUM_QUALITY
Medium camera model, equivalent to an amateur camera.
Definition: OfflineTracker.h:96
@ CM_INVALID
Invalid camera model parameter.
Definition: OfflineTracker.h:92
void updatePoses(const OfflinePoses &poses)
Updates all poses of this tracker and invokes the corresponding state event(s).
virtual bool stop(const unsigned int timeout=0u)
Stops the offline tracker.
virtual bool finished() const
Returns whether the offline tracker has finished since the last start or has not been started yet.
EventCallbacks eventCallbacks_
State event callback functions.
Definition: OfflineTracker.h:425
Lock eventStackLock_
The lock for the progress event layer stack.
Definition: OfflineTracker.h:434
OfflineTracker()
Creates a new offline tracker object.
void popProgressEventStackLayer(const EventStackLayer &layer)
Pops a progress event stack layer from the stack of this tracker.
AbstractMotionType
Definition of individual abstract camera motion types.
Definition: OfflineTracker.h:77
@ AMT_PURE_ROTATIONAL
A pure rotational camera motion.
Definition: OfflineTracker.h:81
@ AMT_UNKNOWN
An unknown abstract camera motion.
Definition: OfflineTracker.h:79
friend class EventStackLayer
Definition: OfflineTracker.h:46
float Scalar
Definition of a scalar type.
Definition: Math.h:128
void release(T *object)
This functions allows to release a DirectShow object if it does exist.
Definition: DSObject.h:266
constexpr VertexIndex invalidIndex
Definition of an invalid vertex index.
Definition: rendering/Rendering.h:77
ObjectRef< OfflineTracker > OfflineTrackerRef
Definition of an object reference holding an offline tracker object.
Definition: OfflineTracker.h:31
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15