Ocean
DescriptorHandling.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_DESCRIPTOR_HANDLING_H
9 #define META_OCEAN_TRACKING_MAPBUILDING_DESCRIPTOR_HANDLING_H
10 
13 
14 #include "ocean/math/AnyCamera.h"
15 
17 
18 namespace Ocean
19 {
20 
21 namespace Tracking
22 {
23 
24 namespace MapBuilding
25 {
26 
27 /**
28  * This class implements functions necessary when handling descriptors.
29  * @ingroup trackingmapbuilding
30  */
31 class OCEAN_TRACKING_MAPBUILDING_EXPORT DescriptorHandling
32 {
33  public:
34 
35  /**
36  * Definition of a FREAK Multi Descriptor with 32 bytes or 256 bits.
37  */
39 
40  /**
41  * Definition of a vector holding FREAK Multi Descriptors with 32 bytes or 256 bits.
42  */
44 
45  /**
46  * Definition of an unordered map mapping FREAK Multi descriptors.
47  */
48  typedef std::unordered_map<Index32, FreakMultiDescriptors256> FreakMultiDescriptorMap256;
49 
50  public:
51 
52  /**
53  * Determines the minimal distance between one FREAK multi descriptor and another FREAK multi descriptors.
54  * @param descriptorA The first descriptor
55  * @param descriptorB The second descriptor
56  * @return The minimal distance between both descriptors
57  */
58  static OCEAN_FORCE_INLINE unsigned int determineFreakDistance(const FreakMultiDescriptor256& descriptorA, const FreakMultiDescriptor256& descriptorB);
59 
60  /**
61  * Determines the minimal distance between one FREAK multi descriptor and several FREAK multi descriptors.
62  * @param descriptorA The first descriptor
63  * @param descriptorsB The set of second descriptors
64  * @return The minimal distance between both descriptors
65  */
66  static OCEAN_FORCE_INLINE unsigned int determineFreakDistance(const FreakMultiDescriptor256& descriptorA, const FreakMultiDescriptors256& descriptorsB);
67 
68  /**
69  * Determines the minimal distance between two sets of FREAK descriptors.
70  * @param descriptorsA The first set of descriptors
71  * @param descriptorsB The second set of descriptors
72  * @return The minimal distance between both descriptors
73  */
74  static OCEAN_FORCE_INLINE unsigned int determineFreakDistance(const FreakMultiDescriptors256& descriptorsA, const FreakMultiDescriptors256& descriptorsB);
75 
76  /**
77  * Determines the minimal distance between a set of FREAK descriptors and a second FREAK descriptor.
78  * @param descriptorsA The first set of descriptors
79  * @param descriptorB The second descriptor
80  * @return The minimal distance between both descriptors
81  */
82  static OCEAN_FORCE_INLINE unsigned int determineFreakDistance(const FreakMultiDescriptors256* const& descriptorsA, const UnifiedDescriptor::BinaryDescriptor<256u>& descriptorB);
83 
84  /**
85  * Determines the minimal distance between two set of FREAK descriptors.
86  * @param descriptorsA The first set of descriptors
87  * @param descriptorB The second set of descriptors
88  * @return The minimal distance between both descriptors
89  */
90  static OCEAN_FORCE_INLINE unsigned int determineFreakDistance(const FreakMultiDescriptors256* const& descriptorsA, const FreakMultiDescriptors256& descriptorB);
91 
92  /**
93  * Determines the minimal distance between a set of FREAK descriptors and a binary descriptor.
94  * @param descriptorsA The first set of descriptors
95  * @param descriptorB The second descriptor
96  * @return The minimal distance between both descriptors
97  */
98  static OCEAN_FORCE_INLINE unsigned int determineFreakDistance(const FreakMultiDescriptors256& descriptorsA, const UnifiedDescriptor::BinaryDescriptor<256u>& descriptorB);
99 
100  /**
101  * Determines the minimal distance between a FREAK descriptors and a binary descriptor.
102  * @param descriptorA The first descriptors
103  * @param descriptorB The second descriptor
104  * @return The minimal distance between both descriptors
105  */
106  static OCEAN_FORCE_INLINE unsigned int calculateHammingDistance(const FreakMultiDescriptor256& descriptorA, const UnifiedDescriptor::BinaryDescriptor<256u>& descriptorB);
107 
108 
109  /**
110  * Returns one binary descriptor from a FREAK Multi descriptor.
111  * @param multiDescriptor The multi descriptor from which one binary descriptor will be extracted
112  * @param index The index of the binary descriptor to extract, with range [0, multiDescriptor.descriptorLevels() - 1]
113  * @return The resulting binary descriptor
114  */
115  static OCEAN_FORCE_INLINE const UnifiedDescriptor::BinaryDescriptor<256u>* multiDescriptorFunction(const FreakMultiDescriptor256& multiDescriptor, const size_t index);
116 
117  /**
118  * Returns one FREAK Multi descriptor from a FREAK Multi descriptor group.
119  * @param multiDescriptorGroup The multi descriptor group from which one multi descriptor will be extracted
120  * @param index The index of the multi descriptor to extract, with range [0, multiDescriptorGroup->size() - 1]
121  * @return The resulting binary descriptor
122  */
123  static OCEAN_FORCE_INLINE const FreakMultiDescriptor256* multiDescriptorGroupFunction(const FreakMultiDescriptors256* const& multiDescriptorGroup, const size_t index);
124 
125  /**
126  * Computes the FREAK Multi descriptor for a given 2D location within an image.
127  * @param yFramePyramid The image pyramid with pixel format FORMAT_Y8, must be valid
128  * @param anyCamera The camera profile defining the projection, must be valid
129  * @param point The point defined inside the image pixel domain
130  * @param freakDescriptor The resulting descriptor
131  * @return True, if succeeded
132  */
133  static bool computeFreakDescriptor(const CV::FramePyramid& yFramePyramid, const AnyCamera& anyCamera, const Vector2& point, FreakMultiDescriptor256& freakDescriptor);
134 
135  /**
136  * Replaces an image pyramid which is intended for FREAK descriptor extraction.
137  * @param yFramePyramid The source image pyramid without any additional filtering
138  * @param yFramePyramidForDescriptors The resulting image pyramid with FREAK-specific filtering
139  * @param worker Optional worker to distribute the computation
140  * @return True, if succeeded
141  */
142  static bool replaceDescriptorPyramid(const CV::FramePyramid& yFramePyramid, CV::FramePyramid& yFramePyramidForDescriptors, Worker* worker = nullptr);
143 };
144 
145 OCEAN_FORCE_INLINE unsigned int DescriptorHandling::determineFreakDistance(const FreakMultiDescriptor256& descriptorA, const FreakMultiDescriptor256& descriptorB)
146 {
147  return descriptorA.distance(descriptorB);
148 }
149 
150 OCEAN_FORCE_INLINE unsigned int DescriptorHandling::determineFreakDistance(const FreakMultiDescriptor256& descriptorA, const FreakMultiDescriptors256& descriptorsB)
151 {
152  unsigned int bestDistance = (unsigned int)(-1);
153 
154  for (const FreakMultiDescriptor256& descriptorB : descriptorsB)
155  {
156  const unsigned int distance = descriptorA.distance(descriptorB);
157 
158  if (distance < bestDistance)
159  {
160  bestDistance = distance;
161  }
162  }
163 
164  return bestDistance;
165 }
166 
167 OCEAN_FORCE_INLINE unsigned int DescriptorHandling::determineFreakDistance(const FreakMultiDescriptors256& descriptorsA, const FreakMultiDescriptors256& descriptorsB)
168 {
169  unsigned int bestDistance = (unsigned int)(-1);
170 
171  for (const FreakMultiDescriptor256& descriptorA : descriptorsA)
172  {
173  for (const FreakMultiDescriptor256& descriptorB : descriptorsB)
174  {
175  const unsigned int distance = descriptorA.distance(descriptorB);
176 
177  if (distance < bestDistance)
178  {
179  bestDistance = distance;
180  }
181  }
182  }
183 
184  return bestDistance;
185 }
186 
187 OCEAN_FORCE_INLINE unsigned int DescriptorHandling::determineFreakDistance(const FreakMultiDescriptors256* const& descriptorsA, const UnifiedDescriptor::BinaryDescriptor<256u>& descriptorB)
188 {
189  ocean_assert(descriptorsA != nullptr);
190 
191  unsigned int bestDistance = (unsigned int)(-1);
192 
193  for (const FreakMultiDescriptor256& descriptorA : *descriptorsA)
194  {
195  const unsigned int distance = calculateHammingDistance(descriptorA, descriptorB);
196 
197  if (distance < bestDistance)
198  {
199  bestDistance = distance;
200  }
201  }
202 
203  return bestDistance;
204 }
205 
206 OCEAN_FORCE_INLINE unsigned int DescriptorHandling::determineFreakDistance(const FreakMultiDescriptors256* const& descriptorsA, const FreakMultiDescriptors256& descriptorB)
207 {
208  ocean_assert(descriptorsA != nullptr);
209 
210  unsigned int bestDistance = (unsigned int)(-1);
211 
212  for (const FreakMultiDescriptor256& descriptorA : *descriptorsA)
213  {
214  const unsigned int distance = determineFreakDistance(descriptorA, descriptorB);
215 
216  if (distance < bestDistance)
217  {
218  bestDistance = distance;
219  }
220  }
221 
222  return bestDistance;
223 }
224 
225 OCEAN_FORCE_INLINE unsigned int DescriptorHandling::determineFreakDistance(const FreakMultiDescriptors256& descriptorsA, const UnifiedDescriptor::BinaryDescriptor<256u>& descriptorB)
226 {
227  unsigned int bestDistance = (unsigned int)(-1);
228 
229  for (const FreakMultiDescriptor256& descriptorA : descriptorsA)
230  {
231  const unsigned int distance = calculateHammingDistance(descriptorA, descriptorB);
232 
233  if (distance < bestDistance)
234  {
235  bestDistance = distance;
236  }
237  }
238 
239  return bestDistance;
240 }
241 
242 OCEAN_FORCE_INLINE unsigned int DescriptorHandling::calculateHammingDistance(const FreakMultiDescriptor256& descriptorA, const UnifiedDescriptor::BinaryDescriptor<256u>& descriptorB)
243 {
244  unsigned int bestDistance = (unsigned int)(-1);
245 
246  for (unsigned int n = 0u; n < descriptorA.descriptorLevels(); ++n)
247  {
248  const unsigned int distance = CV::Detector::Descriptor::calculateHammingDistance<sizeof(UnifiedDescriptor::BinaryDescriptor<256u>) * 8>(&descriptorA.data()[n], &descriptorB);
249 
250  if (distance < bestDistance)
251  {
252  bestDistance = distance;
253  }
254  }
255 
256  return bestDistance;
257 }
258 
259 OCEAN_FORCE_INLINE const UnifiedDescriptor::BinaryDescriptor<256u>* DescriptorHandling::multiDescriptorFunction(const FreakMultiDescriptor256& multiDescriptor, const size_t index)
260 {
261  if (index >= multiDescriptor.descriptorLevels())
262  {
263  return nullptr;
264  }
265 
266  return (const UnifiedDescriptor::BinaryDescriptor<256u>*)(&(multiDescriptor.data()[index]));
267 }
268 
269 OCEAN_FORCE_INLINE const DescriptorHandling::FreakMultiDescriptor256* DescriptorHandling::multiDescriptorGroupFunction(const FreakMultiDescriptors256* const& multiDescriptorGroup, const size_t index)
270 {
271  ocean_assert(multiDescriptorGroup != nullptr);
272 
273  if (index >= multiDescriptorGroup->size())
274  {
275  return nullptr;
276  }
277 
278  return &((*multiDescriptorGroup)[index]);
279 }
280 
281 }
282 
283 }
284 
285 }
286 
287 #endif // META_OCEAN_TRACKING_MAPBUILDING_DESCRIPTOR_HANDLING_H
This class implements the abstract base class for all AnyCamera objects.
Definition: AnyCamera.h:130
static OCEAN_FORCE_INLINE unsigned int calculateHammingDistance(const void *descriptorA, const void *descriptorB)
Determines the hamming distance between two binary descriptors.
Definition: cv/detector/Descriptor.h:250
This class implements a frame pyramid.
Definition: FramePyramid.h:37
This class implements functions necessary when handling descriptors.
Definition: DescriptorHandling.h:32
static bool computeFreakDescriptor(const CV::FramePyramid &yFramePyramid, const AnyCamera &anyCamera, const Vector2 &point, FreakMultiDescriptor256 &freakDescriptor)
Computes the FREAK Multi descriptor for a given 2D location within an image.
static OCEAN_FORCE_INLINE const FreakMultiDescriptor256 * multiDescriptorGroupFunction(const FreakMultiDescriptors256 *const &multiDescriptorGroup, const size_t index)
Returns one FREAK Multi descriptor from a FREAK Multi descriptor group.
Definition: DescriptorHandling.h:269
static OCEAN_FORCE_INLINE unsigned int determineFreakDistance(const FreakMultiDescriptor256 &descriptorA, const FreakMultiDescriptor256 &descriptorB)
Determines the minimal distance between one FREAK multi descriptor and another FREAK multi descriptor...
Definition: DescriptorHandling.h:145
std::unordered_map< Index32, FreakMultiDescriptors256 > FreakMultiDescriptorMap256
Definition of an unordered map mapping FREAK Multi descriptors.
Definition: DescriptorHandling.h:48
static bool replaceDescriptorPyramid(const CV::FramePyramid &yFramePyramid, CV::FramePyramid &yFramePyramidForDescriptors, Worker *worker=nullptr)
Replaces an image pyramid which is intended for FREAK descriptor extraction.
CV::Detector::FREAKDescriptors32 FreakMultiDescriptors256
Definition of a vector holding FREAK Multi Descriptors with 32 bytes or 256 bits.
Definition: DescriptorHandling.h:43
static OCEAN_FORCE_INLINE unsigned int calculateHammingDistance(const FreakMultiDescriptor256 &descriptorA, const UnifiedDescriptor::BinaryDescriptor< 256u > &descriptorB)
Determines the minimal distance between a FREAK descriptors and a binary descriptor.
Definition: DescriptorHandling.h:242
static OCEAN_FORCE_INLINE const UnifiedDescriptor::BinaryDescriptor< 256u > * multiDescriptorFunction(const FreakMultiDescriptor256 &multiDescriptor, const size_t index)
Returns one binary descriptor from a FREAK Multi descriptor.
Definition: DescriptorHandling.h:259
CV::Detector::FREAKDescriptor32 FreakMultiDescriptor256
Definition of a FREAK Multi Descriptor with 32 bytes or 256 bits.
Definition: DescriptorHandling.h:38
ByteDescriptor< tNumberBits/8u > BinaryDescriptor
Definition of a binary descriptor.
Definition: UnifiedDescriptor.h:126
This class implements a worker able to distribute function calls over different threads.
Definition: Worker.h:33
std::vector< FREAKDescriptor32 > FREAKDescriptors32
Vector of 32-bytes long FREAK descriptors.
Definition: FREAKDescriptor.h:69
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