8#ifndef META_OCEAN_TRACKING_POSE_ESTIMATION_T_H
9#define META_OCEAN_TRACKING_POSE_ESTIMATION_T_H
42 template <
typename TDescriptor>
74 template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
75 static bool determinePoseBruteForce(
const AnyCamera& camera,
const Vector3* objectPoints,
const TObjectPointDescriptor* objectPointDescriptors,
const size_t numberObjectPoints,
const Vector2* imagePoints,
const TImagePointDescriptor* imagePointDescriptors,
const size_t numberImagePoints,
RandomGenerator& randomGenerator,
HomogenousMatrix4& world_T_camera,
const unsigned int minimalNumberCorrespondences,
const TDescriptorDistance maximalDescriptorDistance,
const Scalar maximalProjectionError,
const Scalar inlierRate =
Scalar(0.15),
Indices32* usedObjectPointIndices =
nullptr,
Indices32* usedImagePointIndices =
nullptr,
const HomogenousMatrix4& world_T_roughCamera =
HomogenousMatrix4(
false),
Worker* worker =
nullptr,
const Geometry::GravityConstraints* gravityConstraints =
nullptr);
105 template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
106 static bool determinePoseBruteForceWithArbitraryDescriptorOrder(
const AnyCamera& camera,
const Vector3* objectPoints,
const TObjectPointDescriptor* objectPointDescriptors,
const Index32* objectPointIndices,
const size_t numberObjectDescriptors,
const Vector2* imagePoints,
const TImagePointDescriptor* imagePointDescriptors,
const size_t numberImagePoints,
RandomGenerator& randomGenerator,
HomogenousMatrix4& world_T_camera,
const unsigned int minimalNumberCorrespondences,
const TDescriptorDistance maximalDescriptorDistance,
const Scalar maximalProjectionError,
const Scalar inlierRate =
Scalar(0.15),
Indices32* usedObjectPointIndices =
nullptr,
Indices32* usedImagePointIndices =
nullptr,
const HomogenousMatrix4& world_T_roughCamera =
HomogenousMatrix4(
false));
123 template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
124 static void determineUnguidedBruteForceMatchings(
const TObjectPointDescriptor* objectPointDescriptors,
const size_t numberObjectPointDescriptors,
const TImagePointDescriptor* imagePointDescriptors,
const size_t numberImagePointDescriptors, TDescriptorDistance maximalDescriptorDistance,
Index32* objectPointDescriptorIndices,
Worker* worker, TDescriptorDistance* distances =
nullptr);
145 template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
146 static void determineGuidedBruteForceMatchings(
const AnyCamera& camera,
const HomogenousMatrix4& world_T_roughCamera,
const Vector3* objectPoints,
const TObjectPointDescriptor* objectPointDescriptors,
const size_t numberObjectPoints,
const Vector2* imagePoints,
const TImagePointDescriptor* imagePointDescriptors,
const size_t numberImagePoints, TDescriptorDistance maximalDescriptorDistance,
const Scalar maximalProjectionError,
Index32* objectPointDescriptorIndices,
Worker* worker);
170 template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
171 static void determineGuidedMatchings(
const AnyCamera& camera,
const HomogenousMatrix4& world_T_camera,
const Vector2* imagePoints,
const TImagePointDescriptor* imagePointDescriptors,
const size_t numberImagePoints,
const Vector3* objectPoints,
const Geometry::Octree& objectPointOctree,
const Index32* objectPointIds,
const UnorderedDescriptorMap<TObjectPointDescriptor>& objectPointDescriptorMap,
Vectors2& matchedImagePoints,
Vectors3& matchedObjectPoints,
const TDescriptorDistance maximalDescriptorDistance,
Indices32* matchedImagePointIndices =
nullptr,
Indices32* matchedObjectPointIds =
nullptr,
Worker* worker =
nullptr);
187 template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
188 static std::vector<TDescriptorDistance> determineDescriptorDistances(
const TObjectPointDescriptor* objectPointDescriptors,
const TImagePointDescriptor* imagePointDescriptors,
const Index32* objectPointDescriptorIndices,
const Index32* imagePointDescriptorIndices,
const size_t numberCorrespondences);
207 template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
208 static void determineUnguidedBruteForceMatchingsSubset(
const TObjectPointDescriptor* objectPointDescriptors,
const size_t numberObjectPointDescriptors,
const TImagePointDescriptor* imagePointDescriptors, TDescriptorDistance maximalDescriptorDistance,
Index32* objectPointDescriptorIndices, TDescriptorDistance* distances,
const unsigned int firstImagePointDescriptor,
const unsigned int numberImagePointDescriptors);
229 template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
230 static void determineGuidedBruteForceMatchingsSubset(
const AnyCamera* camera,
const HomogenousMatrix4* world_T_roughCamera,
const Vector3* objectPoints,
const TObjectPointDescriptor* objectPointDescriptors,
const size_t numberObjectPoints,
const Vector2* imagePoints,
const TImagePointDescriptor* imagePointDescriptors, TDescriptorDistance maximalDescriptorDistance,
const Scalar maximalProjectionError,
Index32* objectPointDescriptorIndices,
const unsigned int firstImagePoint,
const unsigned int numberImagePoints);
255 template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
256 static void determineGuidedMatchingsSubset(
const AnyCamera* camera,
const HomogenousMatrix4* world_T_camera,
const Vector2* imagePoints,
const TImagePointDescriptor* imagePointDescriptors,
const Vector3* objectPoints,
const Geometry::Octree* objectPointOctree,
const Index32* objectPointIds,
const UnorderedDescriptorMap<TObjectPointDescriptor>* objectPointDescriptorMap,
Vectors2* matchedImagePoints,
Vectors3* matchedObjectPoints,
Indices32* matchedImagePointIndices,
Indices32* matchedObjectPointIds,
const TDescriptorDistance maximalDescriptorDistance,
Lock* lock,
const unsigned int firstImagePoint,
const unsigned int numberImagePoints);
259template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
260bool PoseEstimationT::determinePoseBruteForce(
const AnyCamera& camera,
const Vector3* objectPoints,
const TObjectPointDescriptor* objectPointDescriptors,
const size_t numberObjectPoints,
const Vector2* imagePoints,
const TImagePointDescriptor* imagePointDescriptors,
const size_t numberImagePoints,
RandomGenerator& randomGenerator,
HomogenousMatrix4& world_T_camera,
const unsigned int minimalNumberCorrespondences,
const TDescriptorDistance maximalDescriptorDistance,
const Scalar maximalProjectionError,
const Scalar inlierRate,
Indices32* usedObjectPointIndices,
Indices32* usedImagePointIndices,
const HomogenousMatrix4& world_T_roughCamera,
Worker* worker,
const Geometry::GravityConstraints* gravityConstraints)
262 ocean_assert(camera.
isValid());
264 ocean_assert(maximalProjectionError >=
Scalar(0));
265 ocean_assert(inlierRate >
Scalar(0) && inlierRate <=
Scalar(1));
267 if (numberImagePoints <
size_t(minimalNumberCorrespondences))
272 const Scalar maximalSqrProjectionError = maximalProjectionError * maximalProjectionError;
274 Indices32 matchedObjectPointIds(numberImagePoints);
279 matchedImagePoints.reserve(numberImagePoints);
280 matchedObjectPoints.reserve(numberImagePoints);
282 if (!world_T_roughCamera.
isValid())
284 determineUnguidedBruteForceMatchings<TImagePointDescriptor, TObjectPointDescriptor, TDescriptorDistance, tImageObjectDistanceFunction>(objectPointDescriptors, numberObjectPoints, imagePointDescriptors, numberImagePoints, maximalDescriptorDistance, matchedObjectPointIds.data(), worker);
286 for (
size_t imagePointIndex = 0; imagePointIndex < numberImagePoints; ++imagePointIndex)
288 const Index32& matchedObjectPointIndex = matchedObjectPointIds[imagePointIndex];
290 if (matchedObjectPointIndex !=
Index32(-1))
292 matchedImagePoints.emplace_back(imagePoints[imagePointIndex]);
293 matchedObjectPoints.emplace_back(objectPoints[matchedObjectPointIndex]);
297 ocean_assert(matchedImagePoints.size() == matchedObjectPoints.size());
299 if (matchedImagePoints.size() <
size_t(minimalNumberCorrespondences))
306 Indices32 internalUsedObjectPointIndices;
309 const bool useInternalIndices = usedObjectPointIndices !=
nullptr || usedImagePointIndices !=
nullptr;
311 if (useInternalIndices)
313 internalUsedObjectPointIndices.reserve(numberImagePoints);
314 internalUsedImagePointIndices.reserve(numberImagePoints);
318 ocean_assert(faultyRate >=
Scalar(0) && faultyRate <
Scalar(1));
323 if (world_T_roughCamera.
isValid() ||
Geometry::RANSAC::p3p(camera,
ConstArrayAccessor<Vector3>(matchedObjectPoints),
ConstArrayAccessor<Vector2>(matchedImagePoints), randomGenerator, world_T_camera, 20u,
true, unguidedIterations, maximalSqrProjectionError, &validIndices,
nullptr, gravityConstraints))
327 if (world_T_roughCamera.
isValid())
329 world_T_camera = world_T_roughCamera;
332 matchedImagePoints.clear();
333 matchedObjectPoints.clear();
335 determineGuidedBruteForceMatchings<TImagePointDescriptor, TObjectPointDescriptor, TDescriptorDistance, tImageObjectDistanceFunction>(camera, world_T_camera, objectPoints, objectPointDescriptors, numberObjectPoints, imagePoints, imagePointDescriptors, numberImagePoints, maximalDescriptorDistance, maximalProjectionError, matchedObjectPointIds.data(), worker);
337 for (
size_t imagePointIndex = 0; imagePointIndex < numberImagePoints; ++imagePointIndex)
339 const Index32& matchedObjectPointIndex = matchedObjectPointIds[imagePointIndex];
341 if (matchedObjectPointIndex !=
Index32(-1))
343 matchedImagePoints.emplace_back(imagePoints[imagePointIndex]);
344 matchedObjectPoints.emplace_back(objectPoints[matchedObjectPointIndex]);
346 if (useInternalIndices)
348 internalUsedImagePointIndices.emplace_back(
Index32(imagePointIndex));
349 internalUsedObjectPointIndices.emplace_back(matchedObjectPointIndex);
354 if (matchedImagePoints.size() <
size_t(minimalNumberCorrespondences))
360 constexpr unsigned int guidedIterations = 40u;
363 validIndices.clear();
364 if (
Geometry::RANSAC::p3p(camera,
ConstArrayAccessor<Vector3>(matchedObjectPoints),
ConstArrayAccessor<Vector2>(matchedImagePoints), randomGenerator, world_T_camera, 20u,
true, guidedIterations, maximalSqrProjectionError, &validIndices,
nullptr, gravityConstraints))
366 if (validIndices.size() <
size_t(minimalNumberCorrespondences))
372 if (usedObjectPointIndices !=
nullptr)
374 ocean_assert(useInternalIndices);
376 usedObjectPointIndices->clear();
377 usedObjectPointIndices->reserve(validIndices.size());
379 for (
const Index32 validIndex : validIndices)
381 usedObjectPointIndices->emplace_back(internalUsedObjectPointIndices[validIndex]);
385 if (usedImagePointIndices !=
nullptr)
387 ocean_assert(useInternalIndices);
389 usedImagePointIndices->clear();
390 usedImagePointIndices->reserve(validIndices.size());
392 for (
const Index32 validIndex : validIndices)
394 usedImagePointIndices->emplace_back(internalUsedImagePointIndices[validIndex]);
397 ocean_assert(
UnorderedIndexSet32(usedImagePointIndices->cbegin(), usedImagePointIndices->cend()).size() == usedImagePointIndices->size());
400 if (usedObjectPointIndices !=
nullptr && usedImagePointIndices !=
nullptr)
411 if (usedObjectPointIndices->size() <
size_t(minimalNumberCorrespondences))
427template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
428bool PoseEstimationT::determinePoseBruteForceWithArbitraryDescriptorOrder(
const AnyCamera& camera,
const Vector3* objectPoints,
const TObjectPointDescriptor* objectPointDescriptors,
const Index32* objectPointIndices,
const size_t numberObjectDescriptors,
const Vector2* imagePoints,
const TImagePointDescriptor* imagePointDescriptors,
const size_t numberImagePoints,
RandomGenerator& randomGenerator,
HomogenousMatrix4& world_T_camera,
const unsigned int minimalNumberCorrespondences,
const TDescriptorDistance maximalDescriptorDistance,
const Scalar maximalProjectionError,
const Scalar inlierRate,
Indices32* usedObjectPointIndices,
Indices32* usedImagePointIndices,
const HomogenousMatrix4& world_T_roughCamera)
430 ocean_assert(camera.
isValid());
432 ocean_assert(maximalProjectionError >=
Scalar(0));
433 ocean_assert(inlierRate >
Scalar(0) && inlierRate <=
Scalar(1));
435 if (numberImagePoints <
size_t(minimalNumberCorrespondences))
440 const Scalar maximalSqrProjectionError = maximalProjectionError * maximalProjectionError;
445 matchedImagePoints.reserve(numberImagePoints);
446 matchedObjectPoints.reserve(numberImagePoints);
448 if (!world_T_roughCamera.
isValid())
452 for (
size_t imagePointIndex = 0; imagePointIndex < numberImagePoints; ++imagePointIndex)
454 const TImagePointDescriptor& imagePointDescriptor = imagePointDescriptors[imagePointIndex];
459 for (
size_t nObjectPoint = 0; nObjectPoint < numberObjectDescriptors; ++nObjectPoint)
461 const TDescriptorDistance distance = tImageObjectDistanceFunction(imagePointDescriptor, objectPointDescriptors[nObjectPoint]);
463 if (distance < bestDistance)
465 bestDistance = distance;
466 bestObjectPointDescriptorIndex =
Index32(nObjectPoint);
470 if (bestDistance <= maximalDescriptorDistance)
472 const Index32 objectPointIndex = objectPointIndices[bestObjectPointDescriptorIndex];
474 matchedImagePoints.emplace_back(imagePoints[imagePointIndex]);
475 matchedObjectPoints.emplace_back(objectPoints[objectPointIndex]);
479 if (matchedImagePoints.size() <
size_t(minimalNumberCorrespondences))
486 Indices32 internalUsedObjectPointIndices;
489 const bool useInternalIndices = usedObjectPointIndices !=
nullptr || usedImagePointIndices !=
nullptr;
491 if (useInternalIndices)
493 internalUsedObjectPointIndices.reserve(numberImagePoints);
494 internalUsedImagePointIndices.reserve(numberImagePoints);
498 ocean_assert(faultyRate >=
Scalar(0) && faultyRate <
Scalar(1));
507 if (world_T_roughCamera.
isValid())
509 world_T_camera = world_T_roughCamera;
512 matchedImagePoints.clear();
513 matchedObjectPoints.clear();
517 for (
size_t imagePointIndex = 0; imagePointIndex < numberImagePoints; ++imagePointIndex)
519 const Vector2& imagePoint = imagePoints[imagePointIndex];
520 const TImagePointDescriptor& imagePointDescriptor = imagePointDescriptors[imagePointIndex];
525 for (
size_t nObjectPoint = 0; nObjectPoint < numberObjectDescriptors; ++nObjectPoint)
527 const TDescriptorDistance distance = tImageObjectDistanceFunction(imagePointDescriptor, objectPointDescriptors[nObjectPoint]);
529 if (distance < bestDistance)
531 const Index32 objectPointIndex = objectPointIndices[nObjectPoint];
533 const Vector3& objectPoint = objectPoints[objectPointIndex];
535 constexpr Scalar generousSqrProjectionError =
Scalar(20 * 20);
539 bestDistance = distance;
540 bestObjectPointDescriptorIndex =
Index32(nObjectPoint);
545 if (bestDistance <= maximalDescriptorDistance)
547 const Index32 objectPointIndex = objectPointIndices[bestObjectPointDescriptorIndex];
549 matchedImagePoints.emplace_back(imagePoints[imagePointIndex]);
550 matchedObjectPoints.emplace_back(objectPoints[objectPointIndex]);
552 if (useInternalIndices)
554 internalUsedObjectPointIndices.emplace_back(objectPointIndex);
555 internalUsedImagePointIndices.emplace_back(
Index32(imagePointIndex));
560 if (matchedImagePoints.size() <
size_t(minimalNumberCorrespondences))
566 constexpr unsigned int guidedIterations = 40u;
569 validIndices.clear();
572 if (usedObjectPointIndices !=
nullptr)
574 ocean_assert(useInternalIndices);
576 usedObjectPointIndices->clear();
577 usedObjectPointIndices->reserve(validIndices.size());
579 for (
const Index32 validIndex : validIndices)
581 usedObjectPointIndices->emplace_back(internalUsedObjectPointIndices[validIndex]);
585 if (usedImagePointIndices !=
nullptr)
587 ocean_assert(useInternalIndices);
589 usedImagePointIndices->clear();
590 usedImagePointIndices->reserve(validIndices.size());
592 for (
const Index32 validIndex : validIndices)
594 usedImagePointIndices->emplace_back(internalUsedImagePointIndices[validIndex]);
607template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
608void PoseEstimationT::determineUnguidedBruteForceMatchings(
const TObjectPointDescriptor* objectPointDescriptors,
const size_t numberObjectPointDescriptors,
const TImagePointDescriptor* imagePointDescriptors,
const size_t numberImagePointDescriptors,
const TDescriptorDistance maximalDescriptorDistance,
Index32* objectPointDescriptorIndices,
Worker* worker, TDescriptorDistance* distances)
610 ocean_assert(objectPointDescriptors !=
nullptr);
611 ocean_assert(imagePointDescriptors !=
nullptr);
612 ocean_assert(objectPointDescriptorIndices !=
nullptr);
614 if (worker && (numberObjectPointDescriptors >= 1000 || numberImagePointDescriptors >= 1000))
616 worker->
executeFunction(
Worker::Function::createStatic(&determineUnguidedBruteForceMatchingsSubset<TImagePointDescriptor, TObjectPointDescriptor, TDescriptorDistance, tImageObjectDistanceFunction>, objectPointDescriptors, numberObjectPointDescriptors, imagePointDescriptors, maximalDescriptorDistance, objectPointDescriptorIndices, distances, 0u, 0u), 0u, (
unsigned int)(numberImagePointDescriptors));
620 determineUnguidedBruteForceMatchingsSubset<TImagePointDescriptor, TObjectPointDescriptor, TDescriptorDistance, tImageObjectDistanceFunction>(objectPointDescriptors, numberObjectPointDescriptors, imagePointDescriptors, maximalDescriptorDistance, objectPointDescriptorIndices, distances, 0u, (
unsigned int)(numberImagePointDescriptors));
624template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
625void PoseEstimationT::determineGuidedBruteForceMatchings(
const AnyCamera& camera,
const HomogenousMatrix4& world_T_roughCamera,
const Vector3* objectPoints,
const TObjectPointDescriptor* objectPointDescriptors,
const size_t numberObjectPoints,
const Vector2* imagePoints,
const TImagePointDescriptor* imagePointDescriptors,
const size_t numberImagePoints, TDescriptorDistance maximalDescriptorDistance,
const Scalar maximalProjectionError,
Index32* objectPointDescriptorIndices,
Worker* worker)
627 ocean_assert(camera.
isValid());
628 ocean_assert(world_T_roughCamera.
isValid());
629 ocean_assert(objectPoints !=
nullptr);
630 ocean_assert(objectPointDescriptors !=
nullptr);
631 ocean_assert(imagePoints !=
nullptr);
632 ocean_assert(imagePointDescriptors !=
nullptr);
633 ocean_assert(objectPointDescriptorIndices !=
nullptr);
634 ocean_assert(maximalProjectionError >= 0);
636 if (worker && (numberObjectPoints >= 1000 || numberImagePoints >= 1000))
638 worker->
executeFunction(
Worker::Function::createStatic(&determineGuidedBruteForceMatchingsSubset<TImagePointDescriptor, TObjectPointDescriptor, TDescriptorDistance, tImageObjectDistanceFunction>, &camera, &world_T_roughCamera, objectPoints, objectPointDescriptors, numberObjectPoints, imagePoints, imagePointDescriptors, maximalDescriptorDistance, maximalProjectionError, objectPointDescriptorIndices, 0u, 0u), 0u, (
unsigned int)(numberImagePoints));
642 determineGuidedBruteForceMatchingsSubset<TImagePointDescriptor, TObjectPointDescriptor, TDescriptorDistance, tImageObjectDistanceFunction>(&camera, &world_T_roughCamera, objectPoints, objectPointDescriptors, numberObjectPoints, imagePoints, imagePointDescriptors, maximalDescriptorDistance, maximalProjectionError, objectPointDescriptorIndices, 0u, (
unsigned int)(numberImagePoints));
646template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
647void PoseEstimationT::determineUnguidedBruteForceMatchingsSubset(
const TObjectPointDescriptor* objectPointDescriptors,
const size_t numberObjectPointDescriptors,
const TImagePointDescriptor* imagePointDescriptors,
const TDescriptorDistance maximalDescriptorDistance,
Index32* objectPointDescriptorIndices, TDescriptorDistance* distances,
const unsigned int firstImagePointDescriptor,
const unsigned int numberImagePointDescriptors)
649 ocean_assert(objectPointDescriptors !=
nullptr);
650 ocean_assert(imagePointDescriptors !=
nullptr);
652 for (
size_t imagePointIndex =
size_t(firstImagePointDescriptor); imagePointIndex <
size_t(firstImagePointDescriptor + numberImagePointDescriptors); ++imagePointIndex)
654 const TImagePointDescriptor& imagePointDescriptor = imagePointDescriptors[imagePointIndex];
659 for (
size_t objectPointIndex = 0; objectPointIndex < numberObjectPointDescriptors; ++objectPointIndex)
661 const TDescriptorDistance distance = tImageObjectDistanceFunction(imagePointDescriptor, objectPointDescriptors[objectPointIndex]);
663 if (distance < bestDistance)
665 bestDistance = distance;
666 bestObjectPointIndex =
Index32(objectPointIndex);
670 if (bestDistance <= maximalDescriptorDistance)
672 objectPointDescriptorIndices[imagePointIndex] = bestObjectPointIndex;
674 if (distances !=
nullptr)
676 distances[imagePointIndex] = bestDistance;
681 objectPointDescriptorIndices[imagePointIndex] =
Index32(-1);
686template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
687void PoseEstimationT::determineGuidedBruteForceMatchingsSubset(
const AnyCamera* camera,
const HomogenousMatrix4* world_T_roughCamera,
const Vector3* objectPoints,
const TObjectPointDescriptor* objectPointDescriptors,
const size_t numberObjectPoints,
const Vector2* imagePoints,
const TImagePointDescriptor* imagePointDescriptors, TDescriptorDistance maximalDescriptorDistance,
const Scalar maximalProjectionError,
Index32* objectPointDescriptorIndices,
const unsigned int firstImagePoint,
const unsigned int numberImagePoints)
689 ocean_assert(camera !=
nullptr && camera->
isValid());
690 ocean_assert(world_T_roughCamera !=
nullptr && world_T_roughCamera->
isValid());
691 ocean_assert(objectPoints !=
nullptr);
692 ocean_assert(objectPointDescriptors !=
nullptr);
693 ocean_assert(imagePoints !=
nullptr);
694 ocean_assert(imagePointDescriptors !=
nullptr);
695 ocean_assert(maximalProjectionError >= 0);
701 for (
size_t imagePointIndex =
size_t(firstImagePoint); imagePointIndex <
size_t(firstImagePoint + numberImagePoints); ++imagePointIndex)
703 const Vector2& imagePoint = imagePoints[imagePointIndex];
704 ocean_assert(camera->
isInside(imagePoint));
706 const TImagePointDescriptor& imagePointDescriptor = imagePointDescriptors[imagePointIndex];
711 for (
size_t objectPointIndex = 0; objectPointIndex < numberObjectPoints; ++objectPointIndex)
713 const TDescriptorDistance distance = tImageObjectDistanceFunction(imagePointDescriptor, objectPointDescriptors[objectPointIndex]);
715 if (distance < bestDistance)
717 const Vector3& objectPoint = objectPoints[objectPointIndex];
721 bestDistance = distance;
722 bestObjectPointIndex =
Index32(objectPointIndex);
727 if (bestDistance <= maximalDescriptorDistance)
729 objectPointDescriptorIndices[imagePointIndex] = bestObjectPointIndex;
733 objectPointDescriptorIndices[imagePointIndex] =
Index32(-1);
738template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
739void PoseEstimationT::determineGuidedMatchings(
const AnyCamera& camera,
const HomogenousMatrix4& world_T_camera,
const Vector2* imagePoints,
const TImagePointDescriptor* imagePointDescriptors,
const size_t numberImagePoints,
const Vector3* objectPoints,
const Geometry::Octree& objectPointOctree,
const Index32* objectPointIds,
const UnorderedDescriptorMap<TObjectPointDescriptor>& objectPointDescriptorMap,
Vectors2& matchedImagePoints,
Vectors3& matchedObjectPoints,
const TDescriptorDistance maximalDescriptorDistance,
Indices32* matchedImagePointIndices,
Indices32* matchedObjectPointIds,
Worker* worker)
742 ocean_assert(imagePoints !=
nullptr && imagePointDescriptors !=
nullptr && numberImagePoints >= 1);
743 ocean_assert(objectPoints !=
nullptr && objectPointIds !=
nullptr);
745 ocean_assert(matchedImagePoints.empty());
746 ocean_assert(matchedObjectPoints.empty());
748 if (matchedObjectPointIds !=
nullptr)
750 matchedObjectPointIds->clear();
753 if (matchedImagePointIndices !=
nullptr)
755 matchedImagePointIndices->clear();
758 if (worker !=
nullptr)
761 worker->
executeFunction(
Worker::Function::createStatic(&PoseEstimationT::determineGuidedMatchingsSubset<TImagePointDescriptor, TObjectPointDescriptor, TDescriptorDistance, tImageObjectDistanceFunction>, &camera, &world_T_camera, imagePoints, imagePointDescriptors, objectPoints, &objectPointOctree, objectPointIds, &objectPointDescriptorMap, &matchedImagePoints, &matchedObjectPoints, matchedImagePointIndices, matchedObjectPointIds, maximalDescriptorDistance, &lock, 0u, 0u), 0u, (
unsigned int)(numberImagePoints));
765 determineGuidedMatchingsSubset<TImagePointDescriptor, TObjectPointDescriptor, TDescriptorDistance, tImageObjectDistanceFunction>(&camera, &world_T_camera, imagePoints, imagePointDescriptors, objectPoints, &objectPointOctree, objectPointIds, &objectPointDescriptorMap, &matchedImagePoints, &matchedObjectPoints, matchedImagePointIndices, matchedObjectPointIds, maximalDescriptorDistance,
nullptr, 0u, (
unsigned int)(numberImagePoints));
769template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
770std::vector<TDescriptorDistance>
PoseEstimationT::determineDescriptorDistances(
const TObjectPointDescriptor* objectPointDescriptors,
const TImagePointDescriptor* imagePointDescriptors,
const Index32* objectPointDescriptorIndices,
const Index32* imagePointDescriptorIndices,
const size_t numberCorrespondences)
772 ocean_assert(objectPointDescriptors !=
nullptr);
773 ocean_assert(imagePointDescriptors !=
nullptr);
774 ocean_assert(objectPointDescriptorIndices !=
nullptr);
775 ocean_assert(imagePointDescriptorIndices !=
nullptr);
776 ocean_assert(numberCorrespondences >= 1);
778 std::vector<TDescriptorDistance> result;
779 result.reserve(numberCorrespondences);
781 for (
size_t n = 0; n < numberCorrespondences; ++n)
783 const Index32& objectPointDescriptorIndex = objectPointDescriptorIndices[n];
784 const Index32& imagePointDescriptorIndex = imagePointDescriptorIndices[n];
786 result.emplace_back(tImageObjectDistanceFunction(imagePointDescriptors[imagePointDescriptorIndex], objectPointDescriptors[objectPointDescriptorIndex]));
792template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
793void PoseEstimationT::determineGuidedMatchingsSubset(
const AnyCamera* camera,
const HomogenousMatrix4* world_T_camera,
const Vector2* imagePoints,
const TImagePointDescriptor* imagePointDescriptors,
const Vector3* objectPoints,
const Geometry::Octree* objectPointOctree,
const Index32* objectPointIds,
const UnorderedDescriptorMap<TObjectPointDescriptor>* objectPointDescriptorMap,
Vectors2* matchedImagePoints,
Vectors3* matchedObjectPoints,
Indices32* matchedImagePointIndices,
Indices32* matchedObjectPointIds,
const TDescriptorDistance maximalDescriptorDistance,
Lock* lock,
const unsigned int firstImagePoint,
const unsigned int numberImagePoints)
795 static_assert(tImageObjectDistanceFunction !=
nullptr);
797 ocean_assert(camera !=
nullptr && camera->
isValid());
798 ocean_assert(world_T_camera && world_T_camera->
isValid());
800 ocean_assert(imagePoints !=
nullptr && imagePointDescriptors !=
nullptr && objectPoints !=
nullptr);
801 ocean_assert(objectPointOctree !=
nullptr && objectPointIds !=
nullptr && objectPointDescriptorMap !=
nullptr);
803 ocean_assert(matchedImagePoints !=
nullptr);
804 ocean_assert(matchedObjectPoints !=
nullptr);
811 localMatchedImagePoints.reserve(numberImagePoints);
812 localMatchedObjectPoints.reserve(numberImagePoints);
813 localMatchedImagePointIndices.reserve(numberImagePoints);
814 localMatchedObjectPointIds.reserve(numberImagePoints);
820 std::vector<const Indices32*> leaves;
823 constexpr Scalar generousSqrProjectionError =
Scalar(20 * 20);
825 Geometry::Octree::ReusableData reusableData;
827 for (
unsigned int nImagePoint = firstImagePoint; nImagePoint < firstImagePoint + numberImagePoints; ++nImagePoint)
829 const Vector2& imagePoint = imagePoints[nImagePoint];
830 ocean_assert(camera->
isInside(imagePoint));
832 const TImagePointDescriptor& imagePointDescriptor = imagePointDescriptors[nImagePoint];
834 const Line3 ray = camera->
ray(imagePoint, *world_T_camera);
837 objectPointOctree->intersectingLeaves(ray, tanHalfAngle, leaves, reusableData);
844 for (
const Index32& objectPointIndex : *leaf)
846 const Vector3& objectPoint = objectPoints[objectPointIndex];
850 const Index32 objectPointId = objectPointIds[objectPointIndex];
852 ocean_assert(iObjectPointDescriptor != objectPointDescriptorMap->cend());
854 const TDescriptorDistance distance = tImageObjectDistanceFunction(imagePointDescriptor, iObjectPointDescriptor->second);
856 if (distance < bestDistance)
858 bestDistance = distance;
859 bestObjectPointIndex = objectPointIndex;
865 if (bestDistance <= maximalDescriptorDistance)
867 ocean_assert(bestObjectPointIndex !=
Index32(-1));
869 localMatchedImagePoints.emplace_back(imagePoint);
870 localMatchedObjectPoints.emplace_back(objectPoints[bestObjectPointIndex]);
872 localMatchedImagePointIndices.emplace_back(nImagePoint);
873 localMatchedObjectPointIds.emplace_back(objectPointIds[bestObjectPointIndex]);
879 matchedImagePoints->insert(matchedImagePoints->cend(), localMatchedImagePoints.cbegin(), localMatchedImagePoints.cend());
880 matchedObjectPoints->insert(matchedObjectPoints->cend(), localMatchedObjectPoints.cbegin(), localMatchedObjectPoints.cend());
882 if (matchedImagePointIndices !=
nullptr)
884 matchedImagePointIndices->insert(matchedImagePointIndices->cend(), localMatchedImagePointIndices.cbegin(), localMatchedImagePointIndices.cend());
887 if (matchedObjectPointIds !=
nullptr)
889 matchedObjectPointIds->insert(matchedObjectPointIds->cend(), localMatchedObjectPointIds.cbegin(), localMatchedObjectPointIds.cend());
This class implements the abstract base class for all AnyCamera objects.
Definition AnyCamera.h:131
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 LineT3< T > ray(const VectorT2< T > &distortedImagePoint, const HomogenousMatrixT4< T > &world_T_camera) const =0
Returns a ray starting at the camera's center and intersecting a given 2D point in the image.
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:778
static bool isObjectPointInFrontIF(const HomogenousMatrixT4< Scalar > &flippedCamera_T_world, const VectorT3< Scalar > &objectPoint, const Scalar epsilon=NumericT< Scalar >::eps())
Determines whether a given 3D object point lies in front of a camera while the location of the camera...
Definition Camera.h:855
This class implements an accessor providing direct access to a constant array of elements.
Definition Accessor.h:400
This class implements a container allowing to define gravity constraints during e....
Definition GravityConstraints.h:63
static bool p3p(const AnyCamera &anyCamera, const ConstIndexedAccessor< Vector3 > &objectPointAccessor, const ConstIndexedAccessor< Vector2 > &imagePointAccessor, RandomGenerator &randomGenerator, HomogenousMatrix4 &world_T_camera, const unsigned int minimalValidCorrespondences=5u, const bool refine=true, const unsigned int iterations=20u, const Scalar sqrPixelErrorThreshold=Scalar(5 *5), Indices32 *usedIndices=nullptr, Scalar *sqrAccuracy=nullptr, const GravityConstraints *gravityConstraints=nullptr)
Calculates a pose using the perspective pose problem with three point correspondences using any camer...
static unsigned int iterations(const unsigned int model, const Scalar successProbability=Scalar(0.99), const Scalar faultyRate=Scalar(0.2), const unsigned int maximalIterations=1000000u)
Calculates the number of iterations necessary to find an outlier-free model data set.
void toNull()
Sets the matrix to a zero matrix (including the lower right element).
Definition HomogenousMatrix4.h:1795
bool isValid() const
Returns whether this matrix is a valid homogeneous transformation.
Definition HomogenousMatrix4.h:1806
This class implements an infinite line in 3D space.
Definition Line3.h:68
This class implements a recursive lock object.
Definition Lock.h:31
static constexpr T deg2rad(const T deg)
Converts deg to rad.
Definition Numeric.h:3241
static T tan(const T value)
Returns the tangent of a given value.
Definition Numeric.h:1604
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 an optional recursive scoped lock object locking the lock object only if it's d...
Definition Lock.h:387
This class implements a generator for random numbers.
Definition RandomGenerator.h:42
This class implements functions to estimate camera poses using template-based data types.
Definition PoseEstimationT.h:36
static void determineGuidedBruteForceMatchings(const AnyCamera &camera, const HomogenousMatrix4 &world_T_roughCamera, const Vector3 *objectPoints, const TObjectPointDescriptor *objectPointDescriptors, const size_t numberObjectPoints, const Vector2 *imagePoints, const TImagePointDescriptor *imagePointDescriptors, const size_t numberImagePoints, TDescriptorDistance maximalDescriptorDistance, const Scalar maximalProjectionError, Index32 *objectPointDescriptorIndices, Worker *worker)
Determines the guided matching (with known rough camera pose) between image point and object point fe...
Definition PoseEstimationT.h:625
static void determineGuidedBruteForceMatchingsSubset(const AnyCamera *camera, const HomogenousMatrix4 *world_T_roughCamera, const Vector3 *objectPoints, const TObjectPointDescriptor *objectPointDescriptors, const size_t numberObjectPoints, const Vector2 *imagePoints, const TImagePointDescriptor *imagePointDescriptors, TDescriptorDistance maximalDescriptorDistance, const Scalar maximalProjectionError, Index32 *objectPointDescriptorIndices, const unsigned int firstImagePoint, const unsigned int numberImagePoints)
Determines the guided matching (without known rough camera pose) between a subset of image point and ...
Definition PoseEstimationT.h:687
static bool determinePoseBruteForce(const AnyCamera &camera, const Vector3 *objectPoints, const TObjectPointDescriptor *objectPointDescriptors, const size_t numberObjectPoints, const Vector2 *imagePoints, const TImagePointDescriptor *imagePointDescriptors, const size_t numberImagePoints, RandomGenerator &randomGenerator, HomogenousMatrix4 &world_T_camera, const unsigned int minimalNumberCorrespondences, const TDescriptorDistance maximalDescriptorDistance, const Scalar maximalProjectionError, const Scalar inlierRate=Scalar(0.15), Indices32 *usedObjectPointIndices=nullptr, Indices32 *usedImagePointIndices=nullptr, const HomogenousMatrix4 &world_T_roughCamera=HomogenousMatrix4(false), Worker *worker=nullptr, const Geometry::GravityConstraints *gravityConstraints=nullptr)
Determines the 6-DOF pose for 2D/3D correspondences applying a brute-force search.
Definition PoseEstimationT.h:260
static void determineGuidedMatchingsSubset(const AnyCamera *camera, const HomogenousMatrix4 *world_T_camera, const Vector2 *imagePoints, const TImagePointDescriptor *imagePointDescriptors, const Vector3 *objectPoints, const Geometry::Octree *objectPointOctree, const Index32 *objectPointIds, const UnorderedDescriptorMap< TObjectPointDescriptor > *objectPointDescriptorMap, Vectors2 *matchedImagePoints, Vectors3 *matchedObjectPoints, Indices32 *matchedImagePointIndices, Indices32 *matchedObjectPointIds, const TDescriptorDistance maximalDescriptorDistance, Lock *lock, const unsigned int firstImagePoint, const unsigned int numberImagePoints)
Determines the guided matching between 2D/3D correspondences for a subset of the given 2D image point...
Definition PoseEstimationT.h:793
static std::vector< TDescriptorDistance > determineDescriptorDistances(const TObjectPointDescriptor *objectPointDescriptors, const TImagePointDescriptor *imagePointDescriptors, const Index32 *objectPointDescriptorIndices, const Index32 *imagePointDescriptorIndices, const size_t numberCorrespondences)
Returns the individual descriptor distances for a given set of corresponding feature descriptor pairs...
Definition PoseEstimationT.h:770
std::unordered_map< Index32, TDescriptor > UnorderedDescriptorMap
Definition of an unordered map mapping object point ids to descriptors.
Definition PoseEstimationT.h:43
static void determineUnguidedBruteForceMatchings(const TObjectPointDescriptor *objectPointDescriptors, const size_t numberObjectPointDescriptors, const TImagePointDescriptor *imagePointDescriptors, const size_t numberImagePointDescriptors, TDescriptorDistance maximalDescriptorDistance, Index32 *objectPointDescriptorIndices, Worker *worker, TDescriptorDistance *distances=nullptr)
Determines the unguided matching (without apriori information) between image point and object point f...
Definition PoseEstimationT.h:608
static void determineUnguidedBruteForceMatchingsSubset(const TObjectPointDescriptor *objectPointDescriptors, const size_t numberObjectPointDescriptors, const TImagePointDescriptor *imagePointDescriptors, TDescriptorDistance maximalDescriptorDistance, Index32 *objectPointDescriptorIndices, TDescriptorDistance *distances, const unsigned int firstImagePointDescriptor, const unsigned int numberImagePointDescriptors)
Determines the unguided matching between a subset of image point and object point features applying a...
Definition PoseEstimationT.h:647
static bool determinePoseBruteForceWithArbitraryDescriptorOrder(const AnyCamera &camera, const Vector3 *objectPoints, const TObjectPointDescriptor *objectPointDescriptors, const Index32 *objectPointIndices, const size_t numberObjectDescriptors, const Vector2 *imagePoints, const TImagePointDescriptor *imagePointDescriptors, const size_t numberImagePoints, RandomGenerator &randomGenerator, HomogenousMatrix4 &world_T_camera, const unsigned int minimalNumberCorrespondences, const TDescriptorDistance maximalDescriptorDistance, const Scalar maximalProjectionError, const Scalar inlierRate=Scalar(0.15), Indices32 *usedObjectPointIndices=nullptr, Indices32 *usedImagePointIndices=nullptr, const HomogenousMatrix4 &world_T_roughCamera=HomogenousMatrix4(false))
Determines the 6-DOF pose for 2D/3D correspondences applying a brute-force search.
Definition PoseEstimationT.h:428
static void determineGuidedMatchings(const AnyCamera &camera, const HomogenousMatrix4 &world_T_camera, const Vector2 *imagePoints, const TImagePointDescriptor *imagePointDescriptors, const size_t numberImagePoints, const Vector3 *objectPoints, const Geometry::Octree &objectPointOctree, const Index32 *objectPointIds, const UnorderedDescriptorMap< TObjectPointDescriptor > &objectPointDescriptorMap, Vectors2 &matchedImagePoints, Vectors3 &matchedObjectPoints, const TDescriptorDistance maximalDescriptorDistance, Indices32 *matchedImagePointIndices=nullptr, Indices32 *matchedObjectPointIds=nullptr, Worker *worker=nullptr)
Determines the guided matching between 2D/3D correspondences.
Definition PoseEstimationT.h:739
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...
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.
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.
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::unordered_set< Index32 > UnorderedIndexSet32
Definition of an unordered_set holding 32 bit indices.
Definition Base.h:126
OctreeT< Scalar > Octree
Definition of an Octree using Scalar as data type.
Definition Octree.h:32
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
std::vector< Vector3 > Vectors3
Definition of a vector holding Vector3 objects.
Definition Vector3.h:65
The namespace covering the entire Ocean framework.
Definition Accessor.h:15