Ocean
Loading...
Searching...
No Matches
UnidirectionalCorrespondences.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_UNIDIRECTIONAL_CORRESPONDENCES_H
9#define META_OCEAN_TRACKING_UNIDIRECTIONAL_CORRESPONDENCES_H
10
12
13#include "ocean/base/Lock.h"
14#include "ocean/base/Worker.h"
15
17
20
21namespace Ocean
22{
23
24namespace Tracking
25{
26
27/**
28 * This class provides unidirectional feature correspondences.
29 * @ingroup tracking
30 */
31class OCEAN_TRACKING_EXPORT UnidirectionalCorrespondences
32{
33 public:
34
35 /**
36 * Definition of a pair holding the indices of two corresponding features or descriptors.
37 */
38 using CorrespondencePair = std::pair<unsigned int, unsigned int>;
39
40 /**
41 * Definition of a vector holding correspondence pairs.
42 */
43 using CorrespondencePairs = std::vector<CorrespondencePair>;
44
45 protected:
46
47 /// Definition of a match count value for zero matches.
48 static constexpr Index32 matchCountZero_ = Index32(-1);
49
50 /// Definition of a match count value for two+ matches.
51 static constexpr Index32 matchCounterTwo_ = Index32(-2);
52
53 public:
54
55 /**
56 * Creates a new unidirectional correspondences object.
57 * @param numberForward The number of forward features, with range [1, infinity)
58 * @param numberBackward The number of backward features, with range [1, infinity)
59 */
60 UnidirectionalCorrespondences(const size_t numberForward, const size_t numberBackward);
61
62 /**
63 * Adds a new feature correspondence candidate.
64 * @param forwardIndex Index of the forward feature or descriptor, with range [0, sizeForward-1]
65 * @param backwardIndex Index of the corresponding backward feature or descriptor, with range [0, sizeBackward-1]
66 * @tparam tThreadSafe True, in case the call needs to be thread-safe; False, if no other thread is currently using this correspondence object
67 */
68 template <bool tThreadSafe>
69 void addCandidate(const unsigned int forwardIndex, const unsigned int backwardIndex);
70
71 /**
72 * Returns all unidirectional feature correspondences.
73 * @return The resulting unique feature correspondences
74 */
76
77 /**
78 * Determines unidirectional correspondences pairs between two sets of descriptors.
79 * @param forwardDescriptors The first (forward) set of descriptors, can be invalid if 'numberForwardDescriptors == 0'
80 * @param numberForwardDescriptors The number of descriptors in the first set, with range [0, infinity)
81 * @param backwardDescriptors The second (backward) set of descriptors, can be invalid if 'numberBackwardDescriptors == 0'
82 * @param numberBackwardDescriptors The number of descriptors in the second set, with range [0, infinity)
83 * @param maximalDistance The maximal distance between two descriptors to count as match, with range [0, infinity)
84 * @parma worker Optional worker to distribute the computation
85 * @return The resulting pairs with unidirectional correspondences
86 * @tparam TDescriptor The data type of the descriptors
87 * @tparam TDistance The data type of the distance between two descriptors
88 * @tparam tDistanceFunction The function returning the distance between two descriptors
89 */
90 template <typename TDescriptor, typename TDistance, TDistance(*tDistanceFunction)(const TDescriptor&, const TDescriptor&)>
91 static CorrespondencePairs determineCorrespondingDescriptors(const TDescriptor* forwardDescriptors, const size_t numberForwardDescriptors, const TDescriptor* backwardDescriptors, const size_t numberBackwardDescriptors, const TDistance maximalDistance, Worker* worker);
92
93 /**
94 * Determines guided unidirectional correspondence pairs between image features and object features.
95 * The resulting matches are guided based on a given rough 6-DOF camera pose.
96 * @param camera The camera profile defining the projection, must be valid
97 * @param world_T_camera The rough 6-DOF pose of the camera, with default camera pointing towards the negative z-space with y-axis upwards
98 * @param objectPoints The 3D locations of the 3D object features, one for each object feature, must be valid
99 * @param objectPointDescriptors The descriptors of the 3D object features, one for each object feature, must be valid
100 * @param numberObjectFeatures The number of 3D object features, with range [1, infinity)
101 * @param imagePoints The 2D location of the 2D image features, one for each image feature, must be valid
102 * @param imagePointDescriptors The descriptors of the 2D image features, one for each image feature, must be valid
103 * @param numberImageFeatures The number of 2D image features, with range [1, infinity)
104 * @param maximalDistance The maximal distance between two descriptors (an object descriptor and an image descriptor) to count as match, with range [0, infinity)
105 * @param maximalProjectionError The maximal projection error between image features and projected object features to count as candidate (allows to balance the number of candidates based on the precision of the given camera pose), in pixels, with range [0, infinity)
106 * @tparam TDescriptor The data type of the descriptors
107 * @tparam TDistance The data type of the distance between two descriptors
108 * @tparam tDistanceFunction The function returning the distance between two descriptors
109 */
110 template <typename TDescriptor, typename TDistance, TDistance(*tDistanceFunction)(const TDescriptor&, const TDescriptor&)>
111 static CorrespondencePairs determineCorrespondingFeatures(const AnyCamera& camera, const HomogenousMatrix4& world_T_camera, const Vector3* objectPoints, const TDescriptor* objectPointDescriptors, const size_t numberObjectFeatures, const Vector2* imagePoints, const TDescriptor* imagePointDescriptors, const size_t numberImageFeatures, const TDistance maximalDistance, const Scalar maximalProjectionError);
112
113 /**
114 * Extracts corresponding elements based on correspondence pairs.
115 * @param correspondencePairs The correspondence pairs providing the individual indices of the elements to be extracted
116 * @param firstElements The entire set of first elements, the first index of each correspondence pair belongs to these elements, must be valid
117 * @param sizeFirstElements The size of the entire set of first elements, with range [1, infinity)
118 * @param secondElements The entire set of second elements, the second index of each correspondence pair belongs to these elements, must be valid
119 * @param sizeSecondElements The size of the entire set of second elements, with range [1, infinity)
120 * @param correspondenceFirstElements The resulting elements from the first set which were defined in the provided correspondence pairs
121 * @param correspondenceSecondElements The resulting elements from the second set which were define i the provided correspondence pairs, one for each elements in correspondenceFirstElements
122 * @tparam TFirst The data type of the first elements
123 * @tparam TSecond The data type of the second elements
124 */
125 template <typename TFirst, typename TSecond>
126 static void extractCorrespondenceElements(const CorrespondencePairs& correspondencePairs, const TFirst* firstElements, const size_t sizeFirstElements, const TSecond* secondElements, const size_t sizeSecondElements, std::vector<TFirst>& correspondenceFirstElements, std::vector<TSecond>& correspondenceSecondElements);
127
128 /**
129 * Counts the number of bijective correspondences based on provided indices of used points (either image points or object points).
130 * In case a point index shows up more than once, the point is not part of a bijective correspondence.<br>
131 *
132 * Provide the indices of used image points in case the correspondence were determine by iterating over all object points and finding the best matching image point, in such a case an image point could be used more than once:
133 * <pre>
134 * objectPoint0 -> imagePoint0
135
136 * objectPoint2 -> imagePoint1 the imagePoint1 is not part of a bijective correspondence
137 * objectPoint4 -> imagePoint1
138 *
139 * objectPoint7 -> imagePoint5
140 *
141 * objectPoint8 -> imagePoint3
142 * </pre>
143 *
144 * Provide the indices of used object points in case the correspondence were determine by iterating over all image points and finding the best matching object point, in such a case an object point could be used more than once:
145 * <pre>
146 * imagePoint0 -> objectPoint0
147 *
148 * imagePoint1 -> objectPoint2 the objectPoint2 is not part of a bijective correspondence
149 * imagePoint2 -> objectPoint2
150 *
151 * imagePoint4 -> objectPoint3
152 * </pre>
153 * @param usedPointIndices The indices of the points to be checked, must be valid
154 * @param size The number of indices, with range [1, infinity)
155 * @return The number of bijective correspondences, with range [0, size]
156 */
157 static size_t countBijectiveCorrespondences(const Index32* usedPointIndices, const size_t size);
158
159 /**
160 * Counts the number of non-bijective correspondences based on provided indices of used points (either image points or object points).
161 * The function determines how many points have more than one correspondence, while each non-bijective correspondence is only counted once.
162 * @param usedPointIndices The indices of the points to be checked, must be valid
163 * @param size The number of indices, with range [1, infinity)
164 * @return The number of non-bijective correspondences, with range [0, size/2]
165 */
166 static size_t countNonBijectiveCorrespondences(const Index32* usedPointIndices, const size_t size);
167
168 /**
169 * Removes non-bijective correspondences from 2D/3D correspondences.
170 * The function will remove all non-bijective correspondences from the provided point indices.
171 * @param camera The camera profile defining the projection, must be valid
172 * @param world_T_camera The camera pose transforming camera to world, with default camera pointing towards the negative z-space with y-axis upwards, must be valid
173 * @param objectPoints All 3D object points in which the correspondences are defined, must be valid
174 * @param imagePoints All 2D image points in which the correspondences are defined, must be valid
175 * @param objectPointIndices The indices of the 3D object points which which correspond to 2D image points, at least one
176 * @param imagePointIndices The indices of the 2D image points which which correspond to 3D object points, one for each 3D object point, at least one
177 * @param checkImagePoints True, to check the provided image point indices for bijective correspondences; False, to check the provided object point indices for bijective correspondences
178 */
179 static void removeNonBijectiveCorrespondences(const AnyCamera& camera, const HomogenousMatrix4& world_T_camera, const Vector3* objectPoints, const Vector2* imagePoints, Indices32& objectPointIndices, Indices32& imagePointIndices, const bool checkImagePoints);
180
181 protected:
182
183 /**
184 * Determines a subset of all unidirectional correspondences pairs between two sets of descriptors.
185 * @param forwardDescriptors The first (forward) set of descriptors, must be valid
186 * @param numberForwardDescriptors The number of descriptors in the first set, with range [1, infinity)
187 * @param backwardDescriptors The second (backward) set of descriptors, must be valid
188 * @param numberBackwardDescriptors The number of descriptors in the second set, with range [1, infinity)
189 * @param maximalDistance The maximal distance between two descriptors to count as match, with range [0, infinity)
190 * @param forwardIndicesForBackwardDescriptors The individual indices of matching forward descriptors, one for each backward descriptor
191 * @param locks The 'tLocks' locks elements, must be valid if 'tLocks >= 1'
192 * @param subsetFirstForwardDescriptor The first forward descriptor to be handled, with range [0, numberForwardDescriptors-1]
193 * @param subsetNumberForwardDescriptors The number of forward descriptors to be handled, with range [1, numberForwardDescriptors-subsetFirstForwardDescriptor]
194 * @return The resulting pairs with unidirectional correspondences
195 * @tparam TDescriptor The data type of the descriptors
196 * @tparam TDistance The data type of the distance between two descriptors
197 * @tparam tDistanceFunction The function returning the distance between two descriptors
198 * @tparam tLocks The number of provided lock objects, with range [0, infinity)
199 */
200 template <typename TDescriptor, typename TDistance, TDistance(*tDistanceFunction)(const TDescriptor&, const TDescriptor&), unsigned int tLocks>
201 static void determineCorrespondingDescriptorsSubset(const TDescriptor* forwardDescriptors, const size_t numberForwardDescriptors, const TDescriptor* backwardDescriptors, const size_t numberBackwardDescriptors, const TDistance maximalDistance, Index32* forwardIndicesForBackwardDescriptors, Lock* locks, const unsigned int subsetFirstForwardDescriptor, const unsigned int subsetNumberForwardDescriptors);
202
203 protected:
204
205 /// Correspondence counter for forward features (or for the first features).
207
208 /// Correspondence counter for backward features (or for the second features).
210
211 /// Correspondence candidates.
213
214 /// The object's lock.
215 mutable Lock lock_;
216};
217
218template <bool tThreadSafe>
219void UnidirectionalCorrespondences::addCandidate(const unsigned int forwardIndex, const unsigned int backwardIndex)
220{
221 const TemplatedScopedLock<tThreadSafe> scopedLock(lock_);
222
223 candidates_.emplace_back(forwardIndex, backwardIndex);
224
225 ocean_assert(forwardIndex < forwardCounters_.size());
226 ++forwardCounters_[forwardIndex];
227
228 ocean_assert(backwardIndex < backwardCounters_.size());
229 ++backwardCounters_[backwardIndex];
230}
231
232template <typename TDescriptor, typename TDistance, TDistance(*tDistanceFunction)(const TDescriptor&, const TDescriptor&)>
233UnidirectionalCorrespondences::CorrespondencePairs UnidirectionalCorrespondences::determineCorrespondingDescriptors(const TDescriptor* forwardDescriptors, const size_t numberForwardDescriptors, const TDescriptor* backwardDescriptors, const size_t numberBackwardDescriptors, const TDistance maximalDistance, Worker* worker)
234{
235 if (numberForwardDescriptors == 0 || numberBackwardDescriptors == 0)
236 {
237 return CorrespondencePairs();
238 }
239
240 ocean_assert(forwardDescriptors != nullptr && backwardDescriptors != nullptr);
241
242 Indices32 forwardIndicesForBackwardDescriptors(numberBackwardDescriptors, matchCountZero_); // in the beginning no backward descriptor has a matching forward descriptor
243
244 if (worker != nullptr)
245 {
246 Lock locks[8];
247
248 worker->executeFunction(Worker::Function::createStatic(&UnidirectionalCorrespondences::determineCorrespondingDescriptorsSubset<TDescriptor, TDistance, tDistanceFunction, 8u>, forwardDescriptors, numberForwardDescriptors, backwardDescriptors, numberBackwardDescriptors, maximalDistance, forwardIndicesForBackwardDescriptors.data(), locks, 0u, 0u), 0u, (unsigned int)(numberForwardDescriptors));
249 }
250 else
251 {
252 determineCorrespondingDescriptorsSubset<TDescriptor, TDistance, tDistanceFunction, 0u>(forwardDescriptors, numberForwardDescriptors, backwardDescriptors, numberBackwardDescriptors, maximalDistance, forwardIndicesForBackwardDescriptors.data(), nullptr, 0u, (unsigned int)(numberForwardDescriptors));
253 }
254
255 CorrespondencePairs result;
256 result.reserve(min(numberForwardDescriptors, numberBackwardDescriptors));
257
258 for (size_t indexBackward = 0; indexBackward < numberBackwardDescriptors; ++indexBackward)
259 {
260 if (forwardIndicesForBackwardDescriptors[indexBackward] < Index32(numberForwardDescriptors))
261 {
262 // we only accept a pair of forward/backward descriptors if both descriptors have been assigned exactly for one match
263
264 result.emplace_back(forwardIndicesForBackwardDescriptors[indexBackward], Index32(indexBackward));
265 }
266 }
267
268 return result;
269}
270
271template <typename TDescriptor, typename TDistance, TDistance(*tDistanceFunction)(const TDescriptor&, const TDescriptor&)>
272UnidirectionalCorrespondences::CorrespondencePairs UnidirectionalCorrespondences::determineCorrespondingFeatures(const AnyCamera& camera, const HomogenousMatrix4& world_T_camera, const Vector3* objectPoints, const TDescriptor* objectPointDescriptors, const size_t numberObjectPoints, const Vector2* imagePoints, const TDescriptor* imagePointDescriptors, const size_t numberImagePoints, const TDistance maximalDistance, const Scalar maximalProjectionError)
273{
274 ocean_assert(camera.isValid() && world_T_camera.isValid());
275 ocean_assert(maximalProjectionError >= 0.0);
276
277 ocean_assert(numberObjectPoints != 0 && numberImagePoints != 0);
278
279 if (numberObjectPoints == 0 || numberImagePoints == 0 || maximalProjectionError < 0.0 || !camera.isValid() || !world_T_camera.isValid())
280 {
281 return CorrespondencePairs();
282 }
283
284 ocean_assert(objectPoints != nullptr && objectPointDescriptors != nullptr);
285 ocean_assert(imagePoints != nullptr && imagePointDescriptors != nullptr);
286
287 UnidirectionalCorrespondences candidates(numberImagePoints, numberObjectPoints);
288
289 // first, we project the 3D feature points of the feature map into the camera image and distribute all (visible) features into a 2D grid
290
291 const unsigned int horizontalBins = std::max(1u, (unsigned int)(Scalar(camera.width()) / maximalProjectionError + Scalar(0.5)));
292 const unsigned int verticalBins = std::max(1u, (unsigned int)(Scalar(camera.height()) / maximalProjectionError + Scalar(0.5)));
293
294 Geometry::SpatialDistribution::DistributionArray projectedObjectPointsDistributionArray(Scalar(0), Scalar(0), Scalar(camera.width()), Scalar(camera.height()), horizontalBins, verticalBins);
295
296 const HomogenousMatrix4 cameraFlipped_T_world = AnyCamera::standard2InvertedFlipped(world_T_camera);
297
298 Vectors2 projectedObjectPoints(numberObjectPoints);
299 camera.projectToImageIF(cameraFlipped_T_world, objectPoints, numberObjectPoints, projectedObjectPoints.data());
300
301 for (size_t n = 0; n < projectedObjectPoints.size(); ++n)
302 {
303 const Vector2& projectedObjectPoint = projectedObjectPoints[n];
304
305 const int binX = projectedObjectPointsDistributionArray.horizontalBin(projectedObjectPoint.x());
306 const int binY = projectedObjectPointsDistributionArray.horizontalBin(projectedObjectPoint.y());
307
308 if ((unsigned int)(binX) < horizontalBins && (unsigned int)(binY) < verticalBins)
309 {
310 ocean_assert(camera.isInside(projectedObjectPoint));
311
312 projectedObjectPointsDistributionArray(binX, binY).emplace_back(Index32(n));
313 }
314 }
315
316 // now, we apply a guided matching based on the 9-neighborhood within the 2D grid for each live feature point
317
318 const Scalar sqrMaximalProjectionError = Numeric::sqr(maximalProjectionError);
319
320 for (size_t indexImagePoint = 0; indexImagePoint < numberImagePoints; ++indexImagePoint)
321 {
322 const Vector2& imagePoint = imagePoints[indexImagePoint];
323 const TDescriptor& imagePointDescriptor = imagePointDescriptors[indexImagePoint];
324
325 const int binX = projectedObjectPointsDistributionArray.horizontalBin(imagePoint.x());
326 const int binY = projectedObjectPointsDistributionArray.horizontalBin(imagePoint.y());
327 ocean_assert((unsigned int)(binX) < horizontalBins && (unsigned int)(binY) < verticalBins);
328
329 TDistance bestDistance = NumericT<TDistance>::maxValue();
330 Index32 bestObjectPointIndex = Index32(-1);
331
332 // we iterate over the 9-neighborhood in the distribution array
333
334 for (unsigned int bY = (unsigned int)(std::max(0, binY - 1)); bY < std::min((unsigned int)(binY) + 2u, verticalBins); ++bY)
335 {
336 for (unsigned int bX = (unsigned int)std::max(0, binX - 1); bX < std::min((unsigned int)(binX) + 2u, horizontalBins); ++bX)
337 {
338 const Indices32& objectPointIndices = projectedObjectPointsDistributionArray(bX, bY);
339
340 for (const Index32& objectPointIndex : objectPointIndices)
341 {
342 ocean_assert(size_t(objectPointIndex) < numberObjectPoints);
343 ocean_assert(size_t(objectPointIndex) < projectedObjectPoints.size());
344
345 if (projectedObjectPoints[objectPointIndex].sqrDistance(imagePoint) <= sqrMaximalProjectionError)
346 {
347 const TDistance distance = tDistanceFunction(objectPointDescriptors[objectPointIndex], imagePointDescriptor);
348
349 if (distance < bestDistance)
350 {
351 bestDistance = distance;
352 bestObjectPointIndex = objectPointIndex;
353 }
354 }
355 }
356 }
357 }
358
359 if (bestObjectPointIndex != Index32(-1) && bestDistance <= maximalDistance)
360 {
361 candidates.addCandidate<false>(Index32(indexImagePoint), bestObjectPointIndex);
362 }
363 }
364
365 return candidates.correspondences();
366}
367
368template <typename TDescriptor, typename TDistance, TDistance(*tDistanceFunction)(const TDescriptor&, const TDescriptor&), unsigned int tLocks>
369void UnidirectionalCorrespondences::determineCorrespondingDescriptorsSubset(const TDescriptor* forwardDescriptors, const size_t numberForwardDescriptors, const TDescriptor* backwardDescriptors, const size_t numberBackwardDescriptors, const TDistance maximalDistance, Index32* forwardIndicesForBackwardDescriptors, Lock* locks, const unsigned int subsetFirstForwardDescriptor, const unsigned int subsetNumberForwardDescriptors)
370{
371 ocean_assert(forwardDescriptors != nullptr && backwardDescriptors != nullptr && forwardIndicesForBackwardDescriptors != nullptr);
372
373 for (unsigned int indexForward = subsetFirstForwardDescriptor; indexForward < subsetFirstForwardDescriptor + subsetNumberForwardDescriptors; ++indexForward)
374 {
375 ocean_assert_and_suppress_unused(indexForward < numberForwardDescriptors, numberForwardDescriptors);
376
377 TDistance bestDistance = NumericT<TDistance>::maxValue();
378 Index32 bestBackwardIndex = Index32(-1);
379
380 const TDescriptor& forwardDescriptor = forwardDescriptors[indexForward];
381
382 for (unsigned int indexBackward = 0u; indexBackward < Index32(numberBackwardDescriptors); ++indexBackward)
383 {
384 const TDistance distance = tDistanceFunction(forwardDescriptor, backwardDescriptors[indexBackward]);
385
386 if (distance < bestDistance)
387 {
388 bestDistance = distance;
389 bestBackwardIndex = indexBackward;
390 }
391 }
392
393 if (bestDistance >= maximalDistance)
394 {
395 continue;
396 }
397
398 // if we found a valid correspondence
399 if (bestBackwardIndex != Index32(-1))
400 {
401 Index32& forwardIndexForBackwardDescriptor = forwardIndicesForBackwardDescriptors[bestBackwardIndex];
402
403 if constexpr (tLocks != 0u)
404 {
405 ocean_assert(locks != nullptr);
406 const ScopedLock scopedLock(locks[bestBackwardIndex % tLocks]);
407
408 switch (forwardIndexForBackwardDescriptor)
409 {
410 // we have more than two matching feature point
411 case matchCounterTwo_:
412 break;
413
414 // we have one feature point
415 case matchCountZero_:
416 forwardIndexForBackwardDescriptor = indexForward;
417 break;
418
419 // we have more than one matching feature point
420 default:
421 forwardIndexForBackwardDescriptor = matchCounterTwo_;
422 break;
423 }
424 }
425 else
426 {
427 switch (forwardIndexForBackwardDescriptor)
428 {
429 // currently, no matching descriptor defined
430 case matchCountZero_:
431 forwardIndexForBackwardDescriptor = indexForward;
432 break;
433
434 // this descriptor already had more than two matches
435 case matchCounterTwo_:
436 break;
437
438 // currently, one matching descriptor is already defined, so we invalidate the match
439 default:
440 forwardIndexForBackwardDescriptor = matchCounterTwo_;
441 break;
442 }
443 }
444 }
445 }
446}
447
448template <typename TFirst, typename TSecond>
449void UnidirectionalCorrespondences::extractCorrespondenceElements(const CorrespondencePairs& correspondencePairs, const TFirst* firstElements, const size_t sizeFirstElements, const TSecond* secondElements, const size_t sizeSecondElements, std::vector<TFirst>& correspondenceFirstElements, std::vector<TSecond>& correspondenceSecondElements)
450{
451 correspondenceFirstElements.clear();
452 correspondenceSecondElements.clear();
453
454 correspondenceFirstElements.reserve(correspondencePairs.size());
455 correspondenceSecondElements.reserve(correspondencePairs.size());
456
457 for (const CorrespondencePair& correspondencePair : correspondencePairs)
458 {
459 ocean_assert_and_suppress_unused(correspondencePair.first < sizeFirstElements, sizeFirstElements);
460 ocean_assert_and_suppress_unused(correspondencePair.second < sizeSecondElements, sizeSecondElements);
461
462 correspondenceFirstElements.emplace_back(firstElements[correspondencePair.first]);
463 correspondenceSecondElements.emplace_back(secondElements[correspondencePair.second]);
464 }
465}
466
467
468}
469
470}
471
472#endif // META_OCEAN_TRACKING_UNIDIRECTIONAL_CORRESPONDENCES_H
This class implements the abstract base class for all AnyCamera objects.
Definition AnyCamera.h:130
virtual unsigned int width() const =0
Returns the width of the camera image.
virtual unsigned int height() const =0
Returns the height of the camera image.
virtual VectorT2< T > projectToImageIF(const VectorT3< T > &objectPoint) const =0
Projects a 3D object point into the camera frame.
virtual bool isValid() const =0
Returns whether this camera is valid.
virtual bool isInside(const VectorT2< T > &imagePoint, const T signedBorder=T(0)) const =0
Returns whether a given 2D image point lies inside the camera frame.
static Caller< void > createStatic(typename StaticFunctionPointerMaker< 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 static function with no function parameter.
Definition Caller.h:2877
static HomogenousMatrixT4< U > standard2InvertedFlipped(const HomogenousMatrixT4< U > &world_T_camera)
Transforms a standard homogenous 4x4 viewing (extrinsic camera) matrix into an inverted and flipped c...
Definition Camera.h:734
int horizontalBin(const Scalar x) const
Returns the horizontal bin of a given horizontal position.
Definition SpatialDistribution.h:1104
This class implements a distribution array.
Definition SpatialDistribution.h:228
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
static constexpr T sqr(const T value)
Returns the square of a given value.
Definition Numeric.h:1499
static constexpr T maxValue()
Returns the max scalar value.
Definition Numeric.h:3253
This class implements a scoped lock object for recursive lock objects.
Definition Lock.h:147
This class implements a recursive scoped lock object that is activated by a boolean template paramete...
Definition Lock.h:190
This class provides unidirectional feature correspondences.
Definition UnidirectionalCorrespondences.h:32
static CorrespondencePairs determineCorrespondingFeatures(const AnyCamera &camera, const HomogenousMatrix4 &world_T_camera, const Vector3 *objectPoints, const TDescriptor *objectPointDescriptors, const size_t numberObjectFeatures, const Vector2 *imagePoints, const TDescriptor *imagePointDescriptors, const size_t numberImageFeatures, const TDistance maximalDistance, const Scalar maximalProjectionError)
Determines guided unidirectional correspondence pairs between image features and object features.
Definition UnidirectionalCorrespondences.h:272
static void extractCorrespondenceElements(const CorrespondencePairs &correspondencePairs, const TFirst *firstElements, const size_t sizeFirstElements, const TSecond *secondElements, const size_t sizeSecondElements, std::vector< TFirst > &correspondenceFirstElements, std::vector< TSecond > &correspondenceSecondElements)
Extracts corresponding elements based on correspondence pairs.
Definition UnidirectionalCorrespondences.h:449
std::pair< unsigned int, unsigned int > CorrespondencePair
Definition of a pair holding the indices of two corresponding features or descriptors.
Definition UnidirectionalCorrespondences.h:38
static size_t countNonBijectiveCorrespondences(const Index32 *usedPointIndices, const size_t size)
Counts the number of non-bijective correspondences based on provided indices of used points (either i...
static CorrespondencePairs determineCorrespondingDescriptors(const TDescriptor *forwardDescriptors, const size_t numberForwardDescriptors, const TDescriptor *backwardDescriptors, const size_t numberBackwardDescriptors, const TDistance maximalDistance, Worker *worker)
Determines unidirectional correspondences pairs between two sets of descriptors.
Definition UnidirectionalCorrespondences.h:233
static void determineCorrespondingDescriptorsSubset(const TDescriptor *forwardDescriptors, const size_t numberForwardDescriptors, const TDescriptor *backwardDescriptors, const size_t numberBackwardDescriptors, const TDistance maximalDistance, Index32 *forwardIndicesForBackwardDescriptors, Lock *locks, const unsigned int subsetFirstForwardDescriptor, const unsigned int subsetNumberForwardDescriptors)
Determines a subset of all unidirectional correspondences pairs between two sets of descriptors.
Definition UnidirectionalCorrespondences.h:369
static size_t countBijectiveCorrespondences(const Index32 *usedPointIndices, const size_t size)
Counts the number of bijective correspondences based on provided indices of used points (either image...
CorrespondencePairs correspondences() const
Returns all unidirectional feature correspondences.
Indices32 backwardCounters_
Correspondence counter for backward features (or for the second features).
Definition UnidirectionalCorrespondences.h:209
void addCandidate(const unsigned int forwardIndex, const unsigned int backwardIndex)
Adds a new feature correspondence candidate.
Definition UnidirectionalCorrespondences.h:219
static constexpr Index32 matchCountZero_
Definition of a match count value for zero matches.
Definition UnidirectionalCorrespondences.h:48
UnidirectionalCorrespondences(const size_t numberForward, const size_t numberBackward)
Creates a new unidirectional correspondences object.
Indices32 forwardCounters_
Correspondence counter for forward features (or for the first features).
Definition UnidirectionalCorrespondences.h:206
static void removeNonBijectiveCorrespondences(const AnyCamera &camera, const HomogenousMatrix4 &world_T_camera, const Vector3 *objectPoints, const Vector2 *imagePoints, Indices32 &objectPointIndices, Indices32 &imagePointIndices, const bool checkImagePoints)
Removes non-bijective correspondences from 2D/3D correspondences.
CorrespondencePairs candidates_
Correspondence candidates.
Definition UnidirectionalCorrespondences.h:212
Lock lock_
The object's lock.
Definition UnidirectionalCorrespondences.h:215
static constexpr Index32 matchCounterTwo_
Definition of a match count value for two+ matches.
Definition UnidirectionalCorrespondences.h:51
std::vector< CorrespondencePair > CorrespondencePairs
Definition of a vector holding correspondence pairs.
Definition UnidirectionalCorrespondences.h:43
const T & x() const noexcept
Returns the x value.
Definition Vector2.h:710
const T & y() const noexcept
Returns the y value.
Definition Vector2.h:722
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.
unsigned int sqrDistance(const char first, const char second)
Returns the square distance between two values.
Definition base/Utilities.h:1159
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
std::vector< Vector2 > Vectors2
Definition of a vector holding Vector2 objects.
Definition Vector2.h:64
float Scalar
Definition of a scalar type.
Definition Math.h:129
The namespace covering the entire Ocean framework.
Definition Accessor.h:15