8#ifndef META_OCEAN_TRACKING_UNIDIRECTIONAL_CORRESPONDENCES_H
9#define META_OCEAN_TRACKING_UNIDIRECTIONAL_CORRESPONDENCES_H
68 template <
bool tThreadSafe>
69 void addCandidate(
const unsigned int forwardIndex,
const unsigned int backwardIndex);
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);
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);
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);
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);
218template <
bool tThreadSafe>
223 candidates_.emplace_back(forwardIndex, backwardIndex);
232template <
typename TDescriptor,
typename TDistance, TDistance(*tDistanceFunction)(const TDescriptor&, const TDescriptor&)>
235 if (numberForwardDescriptors == 0 || numberBackwardDescriptors == 0)
240 ocean_assert(forwardDescriptors !=
nullptr && backwardDescriptors !=
nullptr);
244 if (worker !=
nullptr)
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));
252 determineCorrespondingDescriptorsSubset<TDescriptor, TDistance, tDistanceFunction, 0u>(forwardDescriptors, numberForwardDescriptors, backwardDescriptors, numberBackwardDescriptors, maximalDistance, forwardIndicesForBackwardDescriptors.data(),
nullptr, 0u, (
unsigned int)(numberForwardDescriptors));
256 result.reserve(min(numberForwardDescriptors, numberBackwardDescriptors));
258 for (
size_t indexBackward = 0; indexBackward < numberBackwardDescriptors; ++indexBackward)
260 if (forwardIndicesForBackwardDescriptors[indexBackward] <
Index32(numberForwardDescriptors))
264 result.emplace_back(forwardIndicesForBackwardDescriptors[indexBackward],
Index32(indexBackward));
271template <
typename TDescriptor,
typename TDistance, TDistance(*tDistanceFunction)(const TDescriptor&, const TDescriptor&)>
275 ocean_assert(maximalProjectionError >= 0.0);
277 ocean_assert(numberObjectPoints != 0 && numberImagePoints != 0);
279 if (numberObjectPoints == 0 || numberImagePoints == 0 || maximalProjectionError < 0.0 || !camera.
isValid() || !world_T_camera.
isValid())
284 ocean_assert(objectPoints !=
nullptr && objectPointDescriptors !=
nullptr);
285 ocean_assert(imagePoints !=
nullptr && imagePointDescriptors !=
nullptr);
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)));
298 Vectors2 projectedObjectPoints(numberObjectPoints);
299 camera.
projectToImageIF(cameraFlipped_T_world, objectPoints, numberObjectPoints, projectedObjectPoints.data());
301 for (
size_t n = 0; n < projectedObjectPoints.size(); ++n)
303 const Vector2& projectedObjectPoint = projectedObjectPoints[n];
305 const int binX = projectedObjectPointsDistributionArray.
horizontalBin(projectedObjectPoint.
x());
306 const int binY = projectedObjectPointsDistributionArray.
horizontalBin(projectedObjectPoint.
y());
308 if ((
unsigned int)(binX) < horizontalBins && (
unsigned int)(binY) < verticalBins)
310 ocean_assert(camera.
isInside(projectedObjectPoint));
312 projectedObjectPointsDistributionArray(binX, binY).emplace_back(
Index32(n));
320 for (
size_t indexImagePoint = 0; indexImagePoint < numberImagePoints; ++indexImagePoint)
322 const Vector2& imagePoint = imagePoints[indexImagePoint];
323 const TDescriptor& imagePointDescriptor = imagePointDescriptors[indexImagePoint];
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);
334 for (
unsigned int bY = (
unsigned int)(std::max(0, binY - 1)); bY < std::min((
unsigned int)(binY) + 2u, verticalBins); ++bY)
336 for (
unsigned int bX = (
unsigned int)std::max(0, binX - 1); bX < std::min((
unsigned int)(binX) + 2u, horizontalBins); ++bX)
338 const Indices32& objectPointIndices = projectedObjectPointsDistributionArray(bX, bY);
340 for (
const Index32& objectPointIndex : objectPointIndices)
342 ocean_assert(
size_t(objectPointIndex) < numberObjectPoints);
343 ocean_assert(
size_t(objectPointIndex) < projectedObjectPoints.size());
345 if (projectedObjectPoints[objectPointIndex].
sqrDistance(imagePoint) <= sqrMaximalProjectionError)
347 const TDistance distance = tDistanceFunction(objectPointDescriptors[objectPointIndex], imagePointDescriptor);
349 if (distance < bestDistance)
351 bestDistance = distance;
352 bestObjectPointIndex = objectPointIndex;
359 if (bestObjectPointIndex !=
Index32(-1) && bestDistance <= maximalDistance)
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)
371 ocean_assert(forwardDescriptors !=
nullptr && backwardDescriptors !=
nullptr && forwardIndicesForBackwardDescriptors !=
nullptr);
373 for (
unsigned int indexForward = subsetFirstForwardDescriptor; indexForward < subsetFirstForwardDescriptor + subsetNumberForwardDescriptors; ++indexForward)
375 ocean_assert_and_suppress_unused(indexForward < numberForwardDescriptors, numberForwardDescriptors);
380 const TDescriptor& forwardDescriptor = forwardDescriptors[indexForward];
382 for (
unsigned int indexBackward = 0u; indexBackward <
Index32(numberBackwardDescriptors); ++indexBackward)
384 const TDistance distance = tDistanceFunction(forwardDescriptor, backwardDescriptors[indexBackward]);
386 if (distance < bestDistance)
388 bestDistance = distance;
389 bestBackwardIndex = indexBackward;
393 if (bestDistance >= maximalDistance)
399 if (bestBackwardIndex !=
Index32(-1))
401 Index32& forwardIndexForBackwardDescriptor = forwardIndicesForBackwardDescriptors[bestBackwardIndex];
403 if constexpr (tLocks != 0u)
405 ocean_assert(locks !=
nullptr);
406 const ScopedLock scopedLock(locks[bestBackwardIndex % tLocks]);
408 switch (forwardIndexForBackwardDescriptor)
416 forwardIndexForBackwardDescriptor = indexForward;
427 switch (forwardIndexForBackwardDescriptor)
431 forwardIndexForBackwardDescriptor = indexForward;
448template <
typename TFirst,
typename TSecond>
451 correspondenceFirstElements.clear();
452 correspondenceSecondElements.clear();
454 correspondenceFirstElements.reserve(correspondencePairs.size());
455 correspondenceSecondElements.reserve(correspondencePairs.size());
459 ocean_assert_and_suppress_unused(correspondencePair.first < sizeFirstElements, sizeFirstElements);
460 ocean_assert_and_suppress_unused(correspondencePair.second < sizeSecondElements, sizeSecondElements);
462 correspondenceFirstElements.emplace_back(firstElements[correspondencePair.first]);
463 correspondenceSecondElements.emplace_back(secondElements[correspondencePair.second]);
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