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);
147 template <
typename TDescriptor,
typename TDistance, TDistance(*tDistanceFunction)(const TDescriptor&, const TDescriptor&),
unsigned int tLocks>
148 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);
165 template <
bool tThreadSafe>
170 candidates_.emplace_back(forwardIndex, backwardIndex);
179 template <
typename TDescriptor,
typename TDistance, TDistance(*tDistanceFunction)(const TDescriptor&, const TDescriptor&)>
182 if (numberForwardDescriptors == 0 || numberBackwardDescriptors == 0)
187 ocean_assert(forwardDescriptors !=
nullptr && backwardDescriptors !=
nullptr);
191 if (worker !=
nullptr)
195 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));
199 determineCorrespondingDescriptorsSubset<TDescriptor, TDistance, tDistanceFunction, 0u>(forwardDescriptors, numberForwardDescriptors, backwardDescriptors, numberBackwardDescriptors, maximalDistance, forwardIndicesForBackwardDescriptors.data(),
nullptr, 0u, (
unsigned int)(numberForwardDescriptors));
203 result.reserve(min(numberForwardDescriptors, numberBackwardDescriptors));
205 for (
size_t indexBackward = 0; indexBackward < numberBackwardDescriptors; ++indexBackward)
207 if (forwardIndicesForBackwardDescriptors[indexBackward] <
Index32(numberForwardDescriptors))
211 result.emplace_back(forwardIndicesForBackwardDescriptors[indexBackward],
Index32(indexBackward));
218 template <
typename TDescriptor,
typename TDistance, TDistance(*tDistanceFunction)(const TDescriptor&, const TDescriptor&)>
222 ocean_assert(maximalProjectionError >= 0.0);
224 ocean_assert(numberObjectPoints != 0 && numberImagePoints != 0);
226 if (numberObjectPoints == 0 || numberImagePoints == 0 || maximalProjectionError < 0.0 || !camera.
isValid() || !world_T_camera.
isValid())
231 ocean_assert(objectPoints !=
nullptr && objectPointDescriptors !=
nullptr);
232 ocean_assert(imagePoints !=
nullptr && imagePointDescriptors !=
nullptr);
238 const unsigned int horizontalBins = std::max(1u, (
unsigned int)(
Scalar(camera.
width()) / maximalProjectionError +
Scalar(0.5)));
239 const unsigned int verticalBins = std::max(1u, (
unsigned int)(
Scalar(camera.
height()) / maximalProjectionError +
Scalar(0.5)));
245 Vectors2 projectedObjectPoints(numberObjectPoints);
246 camera.
projectToImageIF(cameraFlipped_T_world, objectPoints, numberObjectPoints, projectedObjectPoints.
data());
248 for (
size_t n = 0; n < projectedObjectPoints.size(); ++n)
250 const Vector2& projectedObjectPoint = projectedObjectPoints[n];
252 const int binX = projectedObjectPointsDistributionArray.
horizontalBin(projectedObjectPoint.
x());
253 const int binY = projectedObjectPointsDistributionArray.
horizontalBin(projectedObjectPoint.
y());
255 if ((
unsigned int)(binX) < horizontalBins && (
unsigned int)(binY) < verticalBins)
257 ocean_assert(camera.
isInside(projectedObjectPoint));
259 projectedObjectPointsDistributionArray(binX, binY).emplace_back(
Index32(n));
267 for (
size_t indexImagePoint = 0; indexImagePoint < numberImagePoints; ++indexImagePoint)
269 const Vector2& imagePoint = imagePoints[indexImagePoint];
270 const TDescriptor& imagePointDescriptor = imagePointDescriptors[indexImagePoint];
272 const int binX = projectedObjectPointsDistributionArray.
horizontalBin(imagePoint.
x());
273 const int binY = projectedObjectPointsDistributionArray.
horizontalBin(imagePoint.
y());
274 ocean_assert((
unsigned int)(binX) < horizontalBins && (
unsigned int)(binY) < verticalBins);
281 for (
unsigned int bY = (
unsigned int)(std::max(0, binY - 1)); bY < std::min((
unsigned int)(binY) + 2u, verticalBins); ++bY)
283 for (
unsigned int bX = (
unsigned int)std::max(0, binX - 1); bX < std::min((
unsigned int)(binX) + 2u, horizontalBins); ++bX)
285 const Indices32& objectPointIndices = projectedObjectPointsDistributionArray(bX, bY);
287 for (
const Index32& objectPointIndex : objectPointIndices)
289 ocean_assert(
size_t(objectPointIndex) < numberObjectPoints);
290 ocean_assert(
size_t(objectPointIndex) < projectedObjectPoints.size());
292 if (projectedObjectPoints[objectPointIndex].
sqrDistance(imagePoint) <= sqrMaximalProjectionError)
294 const TDistance distance = tDistanceFunction(objectPointDescriptors[objectPointIndex], imagePointDescriptor);
296 if (distance < bestDistance)
298 bestDistance = distance;
299 bestObjectPointIndex = objectPointIndex;
306 if (bestObjectPointIndex !=
Index32(-1) && bestDistance <= maximalDistance)
315 template <
typename TDescriptor,
typename TDistance, TDistance(*tDistanceFunction)(const TDescriptor&, const TDescriptor&),
unsigned int tLocks>
316 void 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)
318 ocean_assert(forwardDescriptors !=
nullptr && backwardDescriptors !=
nullptr && forwardIndicesForBackwardDescriptors !=
nullptr);
320 for (
unsigned int indexForward = subsetFirstForwardDescriptor; indexForward < subsetFirstForwardDescriptor + subsetNumberForwardDescriptors; ++indexForward)
322 ocean_assert_and_suppress_unused(indexForward < numberForwardDescriptors, numberForwardDescriptors);
327 const TDescriptor& forwardDescriptor = forwardDescriptors[indexForward];
329 for (
unsigned int indexBackward = 0u; indexBackward <
Index32(numberBackwardDescriptors); ++indexBackward)
331 const TDistance distance = tDistanceFunction(forwardDescriptor, backwardDescriptors[indexBackward]);
333 if (distance < bestDistance)
335 bestDistance = distance;
336 bestBackwardIndex = indexBackward;
340 if (bestDistance >= maximalDistance)
346 if (bestBackwardIndex !=
Index32(-1))
348 Index32& forwardIndexForBackwardDescriptor = forwardIndicesForBackwardDescriptors[bestBackwardIndex];
350 if constexpr (tLocks != 0u)
352 ocean_assert(locks !=
nullptr);
353 const ScopedLock scopedLock(locks[bestBackwardIndex % tLocks]);
355 switch (forwardIndexForBackwardDescriptor)
363 forwardIndexForBackwardDescriptor = indexForward;
374 switch (forwardIndexForBackwardDescriptor)
378 forwardIndexForBackwardDescriptor = indexForward;
395 template <
typename TFirst,
typename TSecond>
398 correspondenceFirstElements.clear();
399 correspondenceSecondElements.clear();
401 correspondenceFirstElements.reserve(correspondencePairs.size());
402 correspondenceSecondElements.reserve(correspondencePairs.size());
406 ocean_assert_and_suppress_unused(correspondencePair.first < sizeFirstElements, sizeFirstElements);
407 ocean_assert_and_suppress_unused(correspondencePair.second < sizeSecondElements, sizeSecondElements);
409 correspondenceFirstElements.emplace_back(firstElements[correspondencePair.first]);
410 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 VectorT2< T > projectToImageIF(const VectorT3< T > &objectPoint) const =0
Projects a 3D object point into the camera frame.
virtual unsigned int height() const =0
Returns the height of the camera image.
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:2876
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:1105
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:1495
static constexpr T maxValue()
Returns the max scalar value.
Definition: Numeric.h:3244
This class implements a scoped lock object for recursive lock objects.
Definition: Lock.h:135
This class implements a recursive scoped lock object that is activated by a boolean template paramete...
Definition: Lock.h:178
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:219
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:396
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 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:180
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:316
CorrespondencePairs correspondences() const
Returns all unidirectional feature correspondences.
Indices32 backwardCounters_
Correspondence counter for backward features (or for the second features).
Definition: UnidirectionalCorrespondences.h:156
void addCandidate(const unsigned int forwardIndex, const unsigned int backwardIndex)
Adds a new feature correspondence candidate.
Definition: UnidirectionalCorrespondences.h:166
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:153
CorrespondencePairs candidates_
Correspondence candidates.
Definition: UnidirectionalCorrespondences.h:159
Lock lock_
The object's lock.
Definition: UnidirectionalCorrespondences.h:162
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:698
const T & y() const noexcept
Returns the y value.
Definition: Vector2.h:710
const T * data() const noexcept
Returns an pointer to the vector elements.
Definition: Vector3.h:842
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:1089
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
float Scalar
Definition of a scalar type.
Definition: Math.h:128
std::vector< Vector2 > Vectors2
Definition of a vector holding Vector2 objects.
Definition: Vector2.h:64
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15