Ocean
UnifiedDescriptor.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_MAPBUILDING_UNIFIED_DESCRIPTOR_H
9 #define META_OCEAN_TRACKING_MAPBUILDING_UNIFIED_DESCRIPTOR_H
10 
12 
14 
16 
17 namespace Ocean
18 {
19 
20 namespace Tracking
21 {
22 
23 namespace MapBuilding
24 {
25 
26 /**
27  * This class implements the base class for all unified descriptor objects.
28  * @ingroup trackingmapbuilding
29  */
31 {
32  protected:
33 
34  /// The first bit at which the number of items are defined in the descriptor type.
35  static constexpr uint64_t desriptorTypeNumberItemsBeginBit_ = 32ull;
36 
37  /// The end/exclusive bit up to which the number of items are defined in the descriptor type.
39 
40  /// The first bit at which custom descriptors are defined in the descriptor type.
41  static constexpr uint64_t desriptorTypeCustomTypeBeginBit_ = 56ull;
42 
43  public:
44 
45  /**
46  * Definition of descriptor types.
47  */
48  enum DescriptorType : uint64_t
49  {
50  /// An invalid descriptor.
51  DT_INVALID = 0ull,
52 
53  /// A binary-based descriptor.
54  DT_BINARY = 1ull << 0ull,
55  /// A float-based descriptor.
56  DT_FLOAT = 1ull << 1ull,
57 
58  /// A descriptor containing only one level.
59  DT_SINGLE_LEVEL = 1ull << 2ull,
60  /// A descriptor containing multiple levels (e.g., scale level).
61  DT_MULTI_LEVEL = 1ull << 3ull,
62 
63  /// A descriptor based on a single view (e.g., a descriptor of a 2D image point in a single camera image).
64  DT_SINGLE_VIEW = 1ull << 4ull,
65  /// A descriptor based on multiple views (e.g., a descriptor of a 3D object point observed from several different locations/angles etc.)
66  DT_MULTI_VIEW = 1ull << 5ull,
67 
68  /// A single level binary descriptor.
70  /// A multi level binary descriptor.
72 
73  /// A single level float descriptor.
75  /// A multi level float descriptor.
77 
78  /// A single view, single level, binary descriptor.
80  /// A multi view, single level, binary descriptor.
82  /// A single view, multi level, binary descriptor.
84  /// A multi view, multi level, binary descriptor.
86 
87  /// A single view, single level, float descriptor.
89  /// A multi view, single level, float descriptor.
91  /// A single view, multi level, float descriptor.
93  /// A multi view, multi level, float descriptor.
95 
96  /// A single view, single level, float descriptor with 128 elements.
98  /// A multi view, single level, float descriptor with 128 elements.
100 
101  /// A custom single view, multi level, FREAK descriptor with 256 bits.
103  /// A custom multi view, multi level, FREAK descriptor with 256 bits.
105  };
106 
107  /**
108  * Definition of a byte descriptor.
109  * @tparam tNumberBytes The number of bytes the descriptor has, with range [1, 8191]
110  */
111  template <uint16_t tNumberBytes>
112  using ByteDescriptor = std::array<uint8_t, tNumberBytes>;
113 
114  /**
115  * Definition of a vector holding byte descriptors.
116  * @tparam tNumberBytes The number of bytes each descriptor has, with range [1, infinity)
117  */
118  template <uint16_t tNumberBytes>
119  using ByteDescriptors = std::vector<ByteDescriptor<tNumberBytes>>;
120 
121  /**
122  * Definition of a binary descriptor.
123  * @tparam tNumberBits The number of bits the descriptor has, with range [1, infinity)
124  */
125  template <uint16_t tNumberBits>
126  using BinaryDescriptor = ByteDescriptor<tNumberBits / 8u>;
127 
128  /**
129  * Definition of a vector holding binary descriptors.
130  * @tparam tNumberBits The number of bits each descriptor has, with range [1, infinity)
131  */
132  template <uint16_t tNumberBits>
133  using BinaryDescriptors = std::vector<BinaryDescriptor<tNumberBits>>;
134 
135  /**
136  * Definition of a float descriptor.
137  * @tparam tNumberElements The number of descriptor elements, with range [1, infinity)
138  */
139  template <uint16_t tNumberElements>
140  using FloatDescriptor = std::array<float, tNumberElements>;
141 
142  /**
143  * Definition of a vector holding float descriptors.
144  * @tparam tNumberElements The number of elements each descriptor has, with range [1, infinity)
145  */
146  template <uint16_t tNumberElements>
147  using FloatDescriptors = std::vector<FloatDescriptor<tNumberElements>>;
148 
149  /**
150  * Definition of a FREAK Multi Descriptor with 256 bits (32 bytes).
151  * This custom definition should be removed unce entirely replaced with generic binary descriptors.
152  */
154 
155  /**
156  * Definition of vector holding FREAK Multi Descriptors with 256 bits (32 bytes).
157  * This custom definition should be removed unce entirely replaced with generic binary descriptors.
158  */
159  typedef std::vector<FreakMultiDescriptor256> FreakMultiDescriptors256;
160 
161  /**
162  * This class implements a helper class allowing to determine the type of the distance value between two descriptors.
163  * @param T The data type of the descriptor for which the type of the distance value is needed
164  */
165  template <typename T>
167  {
168  // nothing to do here, needs to be implemented in a template specialization.
169  };
170 
171  /**
172  * This class implements a helper class allowing to determine the descriptor type value for a descriptor data type.
173  * @param T The data type of the descriptor for which the type value is needed
174  */
175  template <typename T>
177  {
178  // nothing to do here, needs to be implemented in a template specialization.
179  };
180 
181  public:
182 
183  /**
184  * Returns the descriptor type of all descriptors hold in this object.
185  * @return The type of all descriptors
186  */
187  inline DescriptorType descriptorType() const;
188 
189  /**
190  * Returns whether a descriptor type represents a binary-based descriptor.
191  * @param descriptorType The descriptor type to check
192  * @return True, if so
193  */
194  static constexpr bool isBinary(const DescriptorType descriptorType);
195 
196  /**
197  * Returns whether a descriptor type represents a float-based descriptor.
198  * @param descriptorType The descriptor type to check
199  * @return True, if so
200  */
201  static constexpr bool isFloat(const DescriptorType descriptorType);
202 
203  /**
204  * Returns whether a descriptor type represents a single level descriptor.
205  * @param descriptorType The descriptor type to check
206  * @return True, if so
207  */
208  static constexpr bool isSingleLevel(const DescriptorType descriptorType);
209 
210  /**
211  * Returns whether a descriptor type represents a multi level descriptor.
212  * @param descriptorType The descriptor type to check
213  * @return True, if so
214  */
215  static constexpr bool isMultiLevel(const DescriptorType descriptorType);
216 
217  /**
218  * Returns whether a descriptor type represents a single view descriptor.
219  * @param descriptorType The descriptor type to check
220  * @return True, if so
221  */
222  static constexpr bool isSingleView(const DescriptorType descriptorType);
223 
224  /**
225  * Returns whether a descriptor type represents a multi view descriptor.
226  * @param descriptorType The descriptor type to check
227  * @return True, if so
228  */
229  static constexpr bool isMultiView(const DescriptorType descriptorType);
230 
231  /**
232  * Returns the number of bits a binary descriptor is composed of.
233  * @param descriptorType The descriptor type for which the number of bits will be returned
234  * @return The number of bits in the binary descriptor, 0 if the descriptor is not a binary descriptor
235  */
236  static constexpr uint16_t numberBits(const DescriptorType descriptorType);
237 
238  /**
239  * Returns the number of elements a float descriptor is composed of.
240  * @param descriptorType The descriptor type for which the number of elements will be returned
241  * @return The number of elements in the float descriptor, 0 if the descriptor is not a float descriptor
242  */
243  static constexpr uint16_t numberElements(const DescriptorType descriptorType);
244 
245  /**
246  * Returns whether a descriptor type represents a custom descriptor.
247  * @param descriptorType The descriptor type to check
248  * @return True, if so
249  */
250  static constexpr bool isCustom(const DescriptorType descriptorType);
251 
252  /**
253  * Returns a binary descriptor type.
254  * @param multiLevel True, if the descriptor is a multi level descriptor; False, if the descriptor is a single level descriptor
255  * @param multiView True, if the descriptor is a multi view descriptor; False, if the descriptor is a single view descriptor
256  * @param numberBits The number of bits the binary descriptor has, with range [1, infinity)
257  * @return The descriptor type of the specified descriptor
258  */
259  static constexpr DescriptorType binaryDescriptorType(const bool multiLevel, const bool multiView, const uint16_t numberBits);
260 
261  /**
262  * Returns a float descriptor type.
263  * @param multiLevel True, if the descriptor is a multi level descriptor; False, if the descriptor is a single level descriptor
264  * @param multiView True, if the descriptor is a multi view descriptor; False, if the descriptor is a single view descriptor
265  * @param numberElements The number of elements the float descriptor has, with range [1, infinity)
266  * @return The descriptor type of the specified descriptor
267  */
268  static constexpr DescriptorType floatDescriptorType(const bool multiLevel, const bool multiView, const uint16_t numberElements);
269 
270  /**
271  * Returns a descriptor type with a specific number of items (either bits or elements).
272  * @param descriptorType The descriptor type to for which the number of items will be set, must be valid, must be either a binary descriptor or a float descriptor
273  * @param numberItems The number of items to set, items are bits for binary descriptors and elements for float descriptors, with range [1, infinity)
274  * @return The resulting descriptor type
275  */
276  static constexpr DescriptorType descriptorType(const DescriptorType descriptorType, const uint16_t numberItems);
277 
278  /**
279  * Returns a binary descriptor type.
280  * @tparam tMultiLevel True, if the descriptor is a multi level descriptor; False, if the descriptor is a single level descriptor
281  * @tparam tMultiView True, if the descriptor is a multi view descriptor; False, if the descriptor is a single view descriptor
282  * @tparam tNumberBits The number of bits the binary descriptor has, with range [1, infinity)
283  * @return The descriptor type of the specified descriptor
284  */
285  template <bool tMultiLevel, bool tMultiView, uint16_t tNumberBits>
286  static constexpr DescriptorType binaryDescriptorType();
287 
288  /**
289  * Returns a float descriptor type.
290  * @tparam tMultiLevel True, if the descriptor is a multi level descriptor; False, if the descriptor is a single level descriptor
291  * @tparam tMultiView True, if the descriptor is a multi view descriptor; False, if the descriptor is a single view descriptor
292  * @tparam tNumberElements The number of elements the float descriptor has, with range [1, infinity)
293  * @return The descriptor type of the specified descriptor
294  */
295  template <bool tMultiLevel, bool tMultiView, uint16_t tNumberElements>
296  static constexpr DescriptorType floatDescriptorType();
297 
298  /**
299  * Returns a descriptor type with a specific number of items (either bits or elements).
300  * @tparam tDescriptorType The descriptor type to for which the number of items will be set, must be valid, must be either a binary descriptor or a float descriptor
301  * @tparam tNumberItems The number of items to set, items are bits for binary descriptors and elements for float descriptors, with range [1, infinity)
302  * @return The resulting descriptor type
303  */
304  template <DescriptorType tDescriptorType, uint16_t tNumberItems>
305  static constexpr DescriptorType descriptorType();
306 
307  protected:
308 
309  /**
310  * Creates a new descriptors object.
311  * @param descriptorType The type of the descriptors
312  */
313  explicit inline UnifiedDescriptor(const DescriptorType descriptorType);
314 
315  protected:
316 
317  /// The descriptor type of all descriptors hold in this object.
319 };
320 
321 /**
322  * Specialization of UnifiedDescriptor::DistanceTyper for UnifiedDescriptor::ByteDescriptor.
323  * @tparam tNumberBytes The number of byte elements the descriptor has, with range [8, 8191]
324  * @ingroup trackingmapbuilding
325  */
326 template <uint16_t tNumberBytes>
328 {
329  static_assert(tNumberBytes >= 8u, "Most likely wrong descriptor!");
330  static_assert(tNumberBytes <= 8191u, "Invalid descriptor!");
331 
332  public:
333 
334  /// The distance type the descriptor uses.
335  typedef unsigned int Type;
336 };
337 
338 /**
339  * Specialization of UnifiedDescriptor::DistanceTyper for UnifiedDescriptor::FloatDescriptor.
340  * @tparam tNumberElements The number of float elements the descriptor has, with range [1, infinity)
341  * @ingroup trackingmapbuilding
342  */
343 template <uint16_t tNumberElements>
345 {
346  static_assert(tNumberElements >= 1u, "Invalid number of elements!");
347 
348  public:
349 
350  /// The distance type the descriptor uses.
351  typedef float Type;
352 };
353 
354 /**
355  * Specialization of UnifiedDescriptor::DistanceTyper for CV::Detector::FREAKDescriptor32.
356  * This class should be removed once the custom FREAK descriptor is not used anymore.
357  * @ingroup trackingmapbuilding
358  */
359 template <>
361 {
362  public:
363 
364  /// The distance type the descriptor uses.
365  typedef unsigned int Type;
366 };
367 
368 /**
369  * Specialization of UnifiedDescriptor::DescriptorTyper for UnifiedDescriptor::ByteDescriptor.
370  * @tparam tNumberBytes The number of byte elements the descriptor has, with range [8, 8191]
371  * @ingroup trackingmapbuilding
372  */
373 template <uint16_t tNumberBytes>
375 {
376  static_assert(tNumberBytes >= 8u, "Most likely wrong descriptor!");
377  static_assert(tNumberBytes <= 8191u, "Invalid descriptor!");
378 
379  public:
380 
381  /**
382  * Returns the type of the descriptor
383  * @return The descriptor's type
384  */
385  static constexpr DescriptorType type()
386  {
387  return UnifiedDescriptor::descriptorType<DT_BINARY_SINGLE_LEVEL_SINGLE_VIEW, tNumberBytes * 8u>();
388  }
389 };
390 
391 /**
392  * Specialization of UnifiedDescriptor::DescriptorTyper for UnifiedDescriptor::ByteDescriptors.
393  * @tparam tNumberBytes The number of byte elements the descriptor has, with range [8, 8191]
394  * @ingroup trackingmapbuilding
395  */
396 template <uint16_t tNumberBytes>
398 {
399  static_assert(tNumberBytes >= 8u, "Most likely wrong descriptor!");
400  static_assert(tNumberBytes <= 8191u, "Invalid descriptor!");
401 
402  public:
403 
404  /**
405  * Returns the type of the descriptor
406  * @return The descriptor's type
407  */
408  static constexpr DescriptorType type()
409  {
410  return UnifiedDescriptor::descriptorType<DT_BINARY_SINGLE_LEVEL_MULTI_VIEW, tNumberBytes * 8u>();
411  }
412 };
413 
414 /**
415  * Specialization of UnifiedDescriptor::DescriptorTyper for UnifiedDescriptor::FloatDescriptor.
416  * @tparam tNumberElements The number of float elements the descriptor has, with range [1, infinity)
417  * @ingroup trackingmapbuilding
418  */
419 template <uint16_t tNumberElements>
421 {
422  static_assert(tNumberElements >= 1u, "Invalid number of elements!");
423 
424  public:
425 
426  /**
427  * Returns the type of the descriptor
428  * @return The descriptor's type
429  */
430  static constexpr DescriptorType type()
431  {
432  return descriptorType<DT_FLOAT_SINGLE_LEVEL_SINGLE_VIEW, tNumberElements>();
433  }
434 };
435 
436 /**
437  * Specialization of UnifiedDescriptor::DescriptorTyper for UnifiedDescriptor::FloatDescriptors.
438  * @tparam tNumberElements The number of float elements the descriptor has, with range [1, infinity)
439  * @ingroup trackingmapbuilding
440  */
441 template <uint16_t tNumberElements>
443 {
444  static_assert(tNumberElements >= 1u, "Invalid number of elements!");
445 
446  public:
447 
448  static constexpr DescriptorType type()
449  {
450  return descriptorType<DT_FLOAT_SINGLE_LEVEL_MULTI_VIEW, tNumberElements>();
451  }
452 };
453 
454 /**
455  * Specialization of UnifiedDescriptor::DescriptorTyper for FreakMultiDescriptor256.
456  * This class should be removed once the custom FREAK descriptor is not used anymore.
457  * @ingroup trackingmapbuilding
458  */
459 template <>
461 {
462  public:
463 
464  static constexpr DescriptorType type()
465  {
467  }
468 };
469 
470 /**
471  * Specialization of UnifiedDescriptor::DescriptorTyper for FreakMultiDescriptors256.
472  * This class should be removed once the custom FREAK descriptor is not used anymore.
473  * @ingroup trackingmapbuilding
474  */
475 template <>
477 {
478  public:
479 
480  static constexpr DescriptorType type()
481  {
483  }
484 };
485 
487  descriptorType_(descriptorType)
488 {
489  // nothing to do here
490 }
491 
493 {
494  return descriptorType_;
495 }
496 
497 constexpr bool UnifiedDescriptor::isBinary(const DescriptorType descriptorType)
498 {
499  return (descriptorType & DT_BINARY) == DT_BINARY;
500 }
501 
502 constexpr bool UnifiedDescriptor::isFloat(const DescriptorType descriptorType)
503 {
504  return (descriptorType & DT_FLOAT) == DT_FLOAT;
505 }
506 
507 constexpr bool UnifiedDescriptor::isSingleLevel(const DescriptorType descriptorType)
508 {
510 }
511 
512 constexpr bool UnifiedDescriptor::isMultiLevel(const DescriptorType descriptorType)
513 {
515 }
516 
517 constexpr bool UnifiedDescriptor::isSingleView(const DescriptorType descriptorType)
518 {
520 }
521 
522 constexpr bool UnifiedDescriptor::isMultiView(const DescriptorType descriptorType)
523 {
525 }
526 
527 constexpr uint16_t UnifiedDescriptor::numberBits(const DescriptorType descriptorType)
528 {
530 }
531 
532 constexpr uint16_t UnifiedDescriptor::numberElements(const DescriptorType descriptorType)
533 {
535 }
536 
537 constexpr bool UnifiedDescriptor::isCustom(const DescriptorType descriptorType)
538 {
540 }
541 
542 constexpr UnifiedDescriptor::DescriptorType UnifiedDescriptor::binaryDescriptorType(const bool multiLevel, const bool multiView, const uint16_t numberBits)
543 {
544  ocean_assert(numberBits >= 1u && numberBits % 8u == 0u);
545 
547 }
548 
549 constexpr UnifiedDescriptor::DescriptorType UnifiedDescriptor::floatDescriptorType(const bool multiLevel, const bool multiView, const uint16_t numberElements)
550 {
552 }
553 
554 constexpr UnifiedDescriptor::DescriptorType UnifiedDescriptor::descriptorType(const DescriptorType descriptorType, const uint16_t numberItems)
555 {
556  ocean_assert(numberBits(descriptorType) == 0u);
557 
558  return DescriptorType(descriptorType | (uint64_t(numberItems) << desriptorTypeNumberItemsBeginBit_));
559 }
560 
561 template <bool tMultiLevel, bool tMultiView, uint16_t tNumberBits>
563 {
564  static_assert(tNumberBits >= 1u, "Invalid number bits!");
565 
566  return binaryDescriptorType(tMultiLevel, tMultiView, tNumberBits);
567 }
568 
569 template <bool tMultiLevel, bool tMultiView, uint16_t tNumberElements>
571 {
572  static_assert(tNumberElements >= 1u, "Invalid number elements!");
573 
574  return floatDescriptorType(tMultiLevel, tMultiView, tNumberElements);
575 }
576 
577 template <UnifiedDescriptor::DescriptorType tDescriptorType, uint16_t tNumberItems>
579 {
580  static_assert(tDescriptorType != DescriptorType::DT_INVALID, "Invalid descriptor type!");
581  static_assert(tNumberItems >= 1u, "Invalid item number!");
582 
583  return descriptorType(tDescriptorType, tNumberItems);
584 }
585 
586 /**
587  * This class implements the base class for unified descriptor objects with specific descriptor type.
588  * This class needs to be specialized for the individual descriptors.
589  * @tparam TDescriptor The data type of the descriptor to be used
590  * @tparam TDistance The data type of the distance between two descriptors
591  * @ingroup trackingmapbuilding
592  */
593 template <typename TDescriptor, typename TDistance = typename UnifiedDescriptor::DistanceTyper<TDescriptor>::Type>
595 {
596  // nothing to do here
597 };
598 
599 /**
600  * Specialization of UnifiedDescriptorT for UnifiedDescriptor::ByteDescriptor.
601  * @tparam tNumberBytes The number of bytes the descriptor has, with range [8, 8191]
602  * @ingroup trackingmapbuilding
603  */
604 template <uint16_t tNumberBytes>
606 {
607  static_assert(tNumberBytes >= 8u && tNumberBytes <= 8191u, "Most likely wrong descriptor!");
608  static_assert(tNumberBytes <= 8191u, "Invalid descriptor!");
609 
610  public:
611 
612  /**
613  * The data type of the descriptor.
614  */
616 
617  /**
618  * Definition of a vector holding descriptors.
619  */
620  typedef std::vector<Descriptor> Descriptors;
621 
622  public:
623 
624  /**
625  * Determines the distance between two single-view descriptors.
626  * The used metric depends on the feature descriptor type (e.g., square distance for float features, or Hamming distance for binary features).
627  * @param descriptorA The first single-view descriptor
628  * @param descriptorB The second single-view descriptor
629  * @return The resulting distance between both features
630  */
631  static OCEAN_FORCE_INLINE unsigned int determineDistance(const Descriptor& descriptorA, const Descriptor& descriptorB);
632 
633  /**
634  * Determines the distance between a single-view descriptor and a multi-view descriptor.
635  * The used metric depends on the feature descriptor type (e.g., square distance for float features, or Hamming distance for binary features).
636  * @param descriptorA The single-view descriptor
637  * @param descriptorsB The multi-view descriptor
638  * @return The resulting distance between both features
639  */
640  static OCEAN_FORCE_INLINE unsigned int determineDistance(const Descriptor& descriptorA, const Descriptors& descriptorsB);
641 };
642 
643 template <uint16_t tNumberBytes>
644 OCEAN_FORCE_INLINE unsigned int UnifiedDescriptorT<typename UnifiedDescriptor::ByteDescriptor<tNumberBytes>>::determineDistance(const Descriptor& descriptorA, const Descriptor& descriptorB)
645 {
646  return CV::Detector::Descriptor::calculateHammingDistance<sizeof(Descriptor) * 8>(&descriptorA, &descriptorB);
647 }
648 
649 template <uint16_t tNumberBytes>
650 OCEAN_FORCE_INLINE unsigned int UnifiedDescriptorT<typename UnifiedDescriptor::ByteDescriptor<tNumberBytes>>::determineDistance(const Descriptor& descriptorA, const Descriptors& descriptorsB)
651 {
652  unsigned int bestDistance = (unsigned int)(-1);
653 
654  for (const Descriptor& descriptorB : descriptorsB)
655  {
656  const unsigned int distance = determineDistance(descriptorA, descriptorB);
657 
658  if (distance < bestDistance)
659  {
660  bestDistance = distance;
661  }
662  }
663 
664  return bestDistance;
665 }
666 
667 /**
668  * Specialization of UnifiedDescriptorT for UnifiedDescriptor::FloatDescriptor.
669  * @tparam tNumberElements The number of float elements the descriptor has, with range [1, infinity)
670  * @ingroup trackingmapbuilding
671  */
672 template <uint16_t tNumberElements>
674 {
675  static_assert(tNumberElements >= 1u, "Invalid number of elements!");
676 
677  public:
678 
679  /**
680  * The data type of the descriptor.
681  */
683 
684  /**
685  * Definition of a vector holding descriptors.
686  */
687  typedef std::vector<Descriptor> Descriptors;
688 
689  public:
690 
691  /**
692  * Determines the distance between two single-view descriptors.
693  * The used metric depends on the feature descriptor type (e.g., square distance for float features, or Hamming distance for binary features).
694  * @param descriptorA The first single-view descriptor
695  * @param descriptorB The second single-view descriptor
696  * @return The resulting distance between both features
697  */
698  static OCEAN_FORCE_INLINE float determineDistance(const Descriptor& descriptorA, const Descriptor& descriptorB);
699 
700  /**
701  * Determines the distance between a single-view descriptor and a multi-view descriptor.
702  * The used metric depends on the feature descriptor type (e.g., square distance for float features, or Hamming distance for binary features).
703  * @param descriptorA The single-view descriptor
704  * @param descriptorsB The multi-view descriptor
705  * @return The resulting distance between both features
706  */
707  static OCEAN_FORCE_INLINE float determineDistance(const Descriptor& descriptorA, const Descriptors& descriptorsB);
708 };
709 
710 template <uint16_t tNumberElements>
711 OCEAN_FORCE_INLINE float UnifiedDescriptorT<typename UnifiedDescriptor::FloatDescriptor<tNumberElements>>::determineDistance(const Descriptor& descriptorA, const Descriptor& descriptorB)
712 {
713  static_assert(tNumberElements >= 1u, "Invalid number of elements!");
714 
715  float sqrDistance = 0.0f;
716 
717  for (unsigned int n = 0u; n < tNumberElements; ++n)
718  {
719  const float difference = descriptorA[n] - descriptorB[n];
720 
721  sqrDistance += difference * difference;
722  }
723 
724  return sqrDistance;
725 }
726 
727 template <uint16_t tNumberElements>
728 OCEAN_FORCE_INLINE float UnifiedDescriptorT<typename UnifiedDescriptor::FloatDescriptor<tNumberElements>>::determineDistance(const Descriptor& descriptorA, const Descriptors& descriptorsB)
729 {
730  static_assert(tNumberElements >= 1u, "Invalid number of elements!");
731 
732  ocean_assert(descriptorsB.size() >= 1);
733 
734  float bestSqrDistance = NumericF::maxValue();
735 
736  for (const Descriptor& descriptorB : descriptorsB)
737  {
738  const float sqrDistance = determineDistance(descriptorA, descriptorB);
739 
740  if (sqrDistance < bestSqrDistance)
741  {
742  bestSqrDistance = sqrDistance;
743  }
744  }
745 
746  return bestSqrDistance;
747 }
748 
749 /**
750  * Specialization of UnifiedDescriptorT for FreakMultiDescriptor256.
751  * @ingroup trackingmapbuilding
752  */
753 template <>
755 {
756  public:
757 
758  /**
759  * The data type of the descriptor.
760  */
762 
763  /**
764  * Definition of a vector holding descriptors.
765  */
766  typedef std::vector<Descriptor> Descriptors;
767 
768  public:
769 
770  /**
771  * Determines the distance between two single-view descriptors.
772  * The used metric depends on the feature descriptor type (e.g., square distance for float features, or Hamming distance for binary features).
773  * @param descriptorA The first single-view descriptor
774  * @param descriptorB The second single-view descriptor
775  * @return The resulting distance between both features
776  */
777  static OCEAN_FORCE_INLINE unsigned int determineDistance(const Descriptor& descriptorA, const Descriptor& descriptorB);
778 
779  /**
780  * Determines the distance between a single-view descriptor and a multi-view descriptor.
781  * The used metric depends on the feature descriptor type (e.g., square distance for float features, or Hamming distance for binary features).
782  * @param descriptorA The single-view descriptor
783  * @param descriptorsB The multi-view descriptor
784  * @return The resulting distance between both features
785  */
786  static OCEAN_FORCE_INLINE unsigned int determineDistance(const Descriptor& descriptorA, const Descriptors& descriptorsB);
787 };
788 
789 OCEAN_FORCE_INLINE unsigned int UnifiedDescriptorT<UnifiedDescriptor::FreakMultiDescriptor256>::determineDistance(const Descriptor& descriptorA, const Descriptor& descriptorB)
790 {
791  return descriptorA.distance(descriptorB);
792 }
793 
794 OCEAN_FORCE_INLINE unsigned int UnifiedDescriptorT<UnifiedDescriptor::FreakMultiDescriptor256>::determineDistance(const Descriptor& descriptorA, const Descriptors& descriptorsB)
795 {
796  unsigned int bestDistance = (unsigned int)(-1);
797 
798  for (const Descriptor& descriptorB : descriptorsB)
799  {
800  const unsigned int distance = determineDistance(descriptorA, descriptorB);
801 
802  if (distance < bestDistance)
803  {
804  bestDistance = distance;
805  }
806  }
807 
808  return bestDistance;
809 }
810 
811 }
812 
813 }
814 
815 }
816 
817 #endif // META_OCEAN_TRACKING_MAPBUILDING_UNIFIED_DESCRIPTOR_H
static constexpr T maxValue()
Returns the max scalar value.
Definition: Numeric.h:3244
static constexpr DescriptorType type()
Returns the type of the descriptor.
Definition: UnifiedDescriptor.h:385
static constexpr DescriptorType type()
Returns the type of the descriptor.
Definition: UnifiedDescriptor.h:408
static constexpr DescriptorType type()
Returns the type of the descriptor.
Definition: UnifiedDescriptor.h:430
This class implements a helper class allowing to determine the descriptor type value for a descriptor...
Definition: UnifiedDescriptor.h:177
unsigned int Type
The distance type the descriptor uses.
Definition: UnifiedDescriptor.h:365
unsigned int Type
The distance type the descriptor uses.
Definition: UnifiedDescriptor.h:329
This class implements a helper class allowing to determine the type of the distance value between two...
Definition: UnifiedDescriptor.h:167
This class implements the base class for all unified descriptor objects.
Definition: UnifiedDescriptor.h:31
UnifiedDescriptor(const DescriptorType descriptorType)
Creates a new descriptors object.
Definition: UnifiedDescriptor.h:486
std::array< float, tNumberElements > FloatDescriptor
Definition of a float descriptor.
Definition: UnifiedDescriptor.h:140
DescriptorType descriptorType_
The descriptor type of all descriptors hold in this object.
Definition: UnifiedDescriptor.h:318
static constexpr uint16_t numberElements(const DescriptorType descriptorType)
Returns the number of elements a float descriptor is composed of.
Definition: UnifiedDescriptor.h:532
static constexpr uint64_t desriptorTypeNumberItemsEndBit_
The end/exclusive bit up to which the number of items are defined in the descriptor type.
Definition: UnifiedDescriptor.h:38
CV::Detector::FREAKDescriptor32 FreakMultiDescriptor256
Definition of a FREAK Multi Descriptor with 256 bits (32 bytes).
Definition: UnifiedDescriptor.h:153
static constexpr bool isBinary(const DescriptorType descriptorType)
Returns whether a descriptor type represents a binary-based descriptor.
Definition: UnifiedDescriptor.h:497
static constexpr uint64_t desriptorTypeNumberItemsBeginBit_
The first bit at which the number of items are defined in the descriptor type.
Definition: UnifiedDescriptor.h:35
static constexpr DescriptorType floatDescriptorType()
Returns a float descriptor type.
Definition: UnifiedDescriptor.h:570
static constexpr DescriptorType binaryDescriptorType()
Returns a binary descriptor type.
Definition: UnifiedDescriptor.h:562
static constexpr bool isMultiLevel(const DescriptorType descriptorType)
Returns whether a descriptor type represents a multi level descriptor.
Definition: UnifiedDescriptor.h:512
static constexpr bool isSingleLevel(const DescriptorType descriptorType)
Returns whether a descriptor type represents a single level descriptor.
Definition: UnifiedDescriptor.h:507
static constexpr uint64_t desriptorTypeCustomTypeBeginBit_
The first bit at which custom descriptors are defined in the descriptor type.
Definition: UnifiedDescriptor.h:41
std::vector< FreakMultiDescriptor256 > FreakMultiDescriptors256
Definition of vector holding FREAK Multi Descriptors with 256 bits (32 bytes).
Definition: UnifiedDescriptor.h:159
std::vector< FloatDescriptor< tNumberElements > > FloatDescriptors
Definition of a vector holding float descriptors.
Definition: UnifiedDescriptor.h:147
static constexpr bool isMultiView(const DescriptorType descriptorType)
Returns whether a descriptor type represents a multi view descriptor.
Definition: UnifiedDescriptor.h:522
std::vector< BinaryDescriptor< tNumberBits > > BinaryDescriptors
Definition of a vector holding binary descriptors.
Definition: UnifiedDescriptor.h:133
DescriptorType descriptorType() const
Returns the descriptor type of all descriptors hold in this object.
Definition: UnifiedDescriptor.h:492
static constexpr bool isCustom(const DescriptorType descriptorType)
Returns whether a descriptor type represents a custom descriptor.
Definition: UnifiedDescriptor.h:537
static constexpr uint16_t numberBits(const DescriptorType descriptorType)
Returns the number of bits a binary descriptor is composed of.
Definition: UnifiedDescriptor.h:527
std::vector< ByteDescriptor< tNumberBytes > > ByteDescriptors
Definition of a vector holding byte descriptors.
Definition: UnifiedDescriptor.h:119
static constexpr bool isSingleView(const DescriptorType descriptorType)
Returns whether a descriptor type represents a single view descriptor.
Definition: UnifiedDescriptor.h:517
DescriptorType
Definition of descriptor types.
Definition: UnifiedDescriptor.h:49
@ DT_FLOAT_SINGLE_LEVEL_MULTI_VIEW
A multi view, single level, float descriptor.
Definition: UnifiedDescriptor.h:90
@ DT_FLOAT_MULTI_LEVEL_MULTI_VIEW
A multi view, multi level, float descriptor.
Definition: UnifiedDescriptor.h:94
@ DT_BINARY_MULTI_LEVEL_MULTI_VIEW
A multi view, multi level, binary descriptor.
Definition: UnifiedDescriptor.h:85
@ DT_FLOAT_MULTI_LEVEL_SINGLE_VIEW
A single view, multi level, float descriptor.
Definition: UnifiedDescriptor.h:92
@ DT_FLOAT_SINGLE_LEVEL_SINGLE_VIEW
A single view, single level, float descriptor.
Definition: UnifiedDescriptor.h:88
@ DT_MULTI_LEVEL
A descriptor containing multiple levels (e.g., scale level).
Definition: UnifiedDescriptor.h:61
@ DT_BINARY_SINGLE_LEVEL
A single level binary descriptor.
Definition: UnifiedDescriptor.h:69
@ DT_FREAK_MULTI_LEVEL_MULTI_VIEW_256
A custom multi view, multi level, FREAK descriptor with 256 bits.
Definition: UnifiedDescriptor.h:104
@ DT_BINARY_SINGLE_LEVEL_MULTI_VIEW
A multi view, single level, binary descriptor.
Definition: UnifiedDescriptor.h:81
@ DT_FLOAT_MULTI_LEVEL
A multi level float descriptor.
Definition: UnifiedDescriptor.h:76
@ DT_BINARY_SINGLE_LEVEL_SINGLE_VIEW
A single view, single level, binary descriptor.
Definition: UnifiedDescriptor.h:79
@ DT_BINARY
A binary-based descriptor.
Definition: UnifiedDescriptor.h:54
@ DT_INVALID
An invalid descriptor.
Definition: UnifiedDescriptor.h:51
@ DT_FLOAT_SINGLE_LEVEL_SINGLE_VIEW_128
A single view, single level, float descriptor with 128 elements.
Definition: UnifiedDescriptor.h:97
@ DT_FLOAT_SINGLE_LEVEL
A single level float descriptor.
Definition: UnifiedDescriptor.h:74
@ DT_FLOAT
A float-based descriptor.
Definition: UnifiedDescriptor.h:56
@ DT_FLOAT_SINGLE_LEVEL_MULTI_VIEW_128
A multi view, single level, float descriptor with 128 elements.
Definition: UnifiedDescriptor.h:99
@ DT_SINGLE_LEVEL
A descriptor containing only one level.
Definition: UnifiedDescriptor.h:59
@ DT_BINARY_MULTI_LEVEL
A multi level binary descriptor.
Definition: UnifiedDescriptor.h:71
@ DT_BINARY_MULTI_LEVEL_SINGLE_VIEW
A single view, multi level, binary descriptor.
Definition: UnifiedDescriptor.h:83
@ DT_MULTI_VIEW
A descriptor based on multiple views (e.g., a descriptor of a 3D object point observed from several d...
Definition: UnifiedDescriptor.h:66
@ DT_SINGLE_VIEW
A descriptor based on a single view (e.g., a descriptor of a 2D image point in a single camera image)...
Definition: UnifiedDescriptor.h:64
@ DT_FREAK_MULTI_LEVEL_SINGLE_VIEW_256
A custom single view, multi level, FREAK descriptor with 256 bits.
Definition: UnifiedDescriptor.h:102
static constexpr bool isFloat(const DescriptorType descriptorType)
Returns whether a descriptor type represents a float-based descriptor.
Definition: UnifiedDescriptor.h:502
ByteDescriptor< tNumberBits/8u > BinaryDescriptor
Definition of a binary descriptor.
Definition: UnifiedDescriptor.h:126
std::array< uint8_t, tNumberBytes > ByteDescriptor
Definition of a byte descriptor.
Definition: UnifiedDescriptor.h:112
std::vector< Descriptor > Descriptors
Definition of a vector holding descriptors.
Definition: UnifiedDescriptor.h:620
static OCEAN_FORCE_INLINE unsigned int determineDistance(const Descriptor &descriptorA, const Descriptors &descriptorsB)
Determines the distance between a single-view descriptor and a multi-view descriptor.
ByteDescriptor< tNumberBytes > Descriptor
The data type of the descriptor.
Definition: UnifiedDescriptor.h:607
static OCEAN_FORCE_INLINE unsigned int determineDistance(const Descriptor &descriptorA, const Descriptor &descriptorB)
Determines the distance between two single-view descriptors.
static OCEAN_FORCE_INLINE float determineDistance(const Descriptor &descriptorA, const Descriptors &descriptorsB)
Determines the distance between a single-view descriptor and a multi-view descriptor.
FloatDescriptor< tNumberElements > Descriptor
The data type of the descriptor.
Definition: UnifiedDescriptor.h:675
static OCEAN_FORCE_INLINE float determineDistance(const Descriptor &descriptorA, const Descriptor &descriptorB)
Determines the distance between two single-view descriptors.
std::vector< Descriptor > Descriptors
Definition of a vector holding descriptors.
Definition: UnifiedDescriptor.h:687
UnifiedDescriptor::FreakMultiDescriptor256 Descriptor
The data type of the descriptor.
Definition: UnifiedDescriptor.h:761
std::vector< Descriptor > Descriptors
Definition of a vector holding descriptors.
Definition: UnifiedDescriptor.h:766
This class implements the base class for unified descriptor objects with specific descriptor type.
Definition: UnifiedDescriptor.h:595
unsigned int sqrDistance(const char first, const char second)
Returns the square distance between two values.
Definition: base/Utilities.h:1089
FREAKDescriptorT< 32 > FREAKDescriptor32
Typedef for the 32-bytes long FREAK descriptor.
Definition: FREAKDescriptor.h:66
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15