8#ifndef META_OCEAN_TRACKING_POSE_ESTIMATION_T_H
9#define META_OCEAN_TRACKING_POSE_ESTIMATION_T_H
41 template <
typename TDescriptor>
72 template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
73 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);
103 template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
104 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));
121 template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
122 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);
143 template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
144 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);
168 template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
169 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);
185 template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
186 static std::vector<TDescriptorDistance> determineDescriptorDistances(
const TObjectPointDescriptor* objectPointDescriptors,
const TImagePointDescriptor* imagePointDescriptors,
const Index32* objectPointDescriptorIndices,
const Index32* imagePointDescriptorIndices,
const size_t numberCorrespondences);
205 template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
206 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);
227 template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
228 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);
253 template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
254 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);
257template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
259* 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)
261 ocean_assert(camera.
isValid());
263 ocean_assert(maximalProjectionError >=
Scalar(0));
264 ocean_assert(inlierRate >
Scalar(0) && inlierRate <=
Scalar(1));
266 if (numberImagePoints <
size_t(minimalNumberCorrespondences))
271 const Scalar maximalSqrProjectionError = maximalProjectionError * maximalProjectionError;
273 Indices32 matchedObjectPointIds(numberImagePoints);
278 matchedImagePoints.reserve(numberImagePoints);
279 matchedObjectPoints.reserve(numberImagePoints);
281 if (!world_T_roughCamera.
isValid())
283 determineUnguidedBruteForceMatchings<TImagePointDescriptor, TObjectPointDescriptor, TDescriptorDistance, tImageObjectDistanceFunction>(objectPointDescriptors, numberObjectPoints, imagePointDescriptors, numberImagePoints, maximalDescriptorDistance, matchedObjectPointIds.data(), worker);
285 for (
size_t imagePointIndex = 0; imagePointIndex < numberImagePoints; ++imagePointIndex)
287 const Index32& matchedObjectPointIndex = matchedObjectPointIds[imagePointIndex];
289 if (matchedObjectPointIndex !=
Index32(-1))
291 matchedImagePoints.emplace_back(imagePoints[imagePointIndex]);
292 matchedObjectPoints.emplace_back(objectPoints[matchedObjectPointIndex]);
296 if (matchedImagePoints.size() <
size_t(minimalNumberCorrespondences))
303 Indices32 internalUsedObjectPointIndices;
306 const bool useInternalIndices = usedObjectPointIndices !=
nullptr || usedImagePointIndices !=
nullptr;
308 if (useInternalIndices)
310 internalUsedObjectPointIndices.reserve(numberImagePoints);
311 internalUsedImagePointIndices.reserve(numberImagePoints);
315 ocean_assert(faultyRate >=
Scalar(0) && faultyRate <
Scalar(1));
324 if (world_T_roughCamera.
isValid())
326 world_T_camera = world_T_roughCamera;
329 matchedImagePoints.clear();
330 matchedObjectPoints.clear();
332 determineGuidedBruteForceMatchings<TImagePointDescriptor, TObjectPointDescriptor, TDescriptorDistance, tImageObjectDistanceFunction>(camera, world_T_camera, objectPoints, objectPointDescriptors, numberObjectPoints, imagePoints, imagePointDescriptors, numberImagePoints, maximalDescriptorDistance, maximalProjectionError, matchedObjectPointIds.data(), worker);
334 for (
size_t imagePointIndex = 0; imagePointIndex < numberImagePoints; ++imagePointIndex)
336 const Index32& matchedObjectPointIndex = matchedObjectPointIds[imagePointIndex];
338 if (matchedObjectPointIndex !=
Index32(-1))
340 matchedImagePoints.emplace_back(imagePoints[imagePointIndex]);
341 matchedObjectPoints.emplace_back(objectPoints[matchedObjectPointIndex]);
343 if (useInternalIndices)
345 internalUsedImagePointIndices.emplace_back(
Index32(imagePointIndex));
346 internalUsedObjectPointIndices.emplace_back(matchedObjectPointIndex);
351 if (matchedImagePoints.size() <
size_t(minimalNumberCorrespondences))
357 constexpr unsigned int guidedIterations = 40u;
360 validIndices.clear();
363 if (usedObjectPointIndices !=
nullptr)
365 ocean_assert(useInternalIndices);
367 usedObjectPointIndices->clear();
368 usedObjectPointIndices->reserve(validIndices.size());
370 for (
const Index32 validIndex : validIndices)
372 usedObjectPointIndices->emplace_back(internalUsedObjectPointIndices[validIndex]);
376 if (usedImagePointIndices !=
nullptr)
378 ocean_assert(useInternalIndices);
380 usedImagePointIndices->clear();
381 usedImagePointIndices->reserve(validIndices.size());
383 for (
const Index32 validIndex : validIndices)
385 usedImagePointIndices->emplace_back(internalUsedImagePointIndices[validIndex]);
398template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
399bool 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)
401 ocean_assert(camera.
isValid());
403 ocean_assert(maximalProjectionError >=
Scalar(0));
404 ocean_assert(inlierRate >
Scalar(0) && inlierRate <=
Scalar(1));
406 if (numberImagePoints <
size_t(minimalNumberCorrespondences))
411 const Scalar maximalSqrProjectionError = maximalProjectionError * maximalProjectionError;
416 matchedImagePoints.reserve(numberImagePoints);
417 matchedObjectPoints.reserve(numberImagePoints);
419 if (!world_T_roughCamera.
isValid())
423 for (
size_t imagePointIndex = 0; imagePointIndex < numberImagePoints; ++imagePointIndex)
425 const TImagePointDescriptor& imagePointDescriptor = imagePointDescriptors[imagePointIndex];
430 for (
size_t nObjectPoint = 0; nObjectPoint < numberObjectDescriptors; ++nObjectPoint)
432 const TDescriptorDistance distance = tImageObjectDistanceFunction(imagePointDescriptor, objectPointDescriptors[nObjectPoint]);
434 if (distance < bestDistance)
436 bestDistance = distance;
437 bestObjectPointDescriptorIndex =
Index32(nObjectPoint);
441 if (bestDistance <= maximalDescriptorDistance)
443 const Index32 objectPointIndex = objectPointIndices[bestObjectPointDescriptorIndex];
445 matchedImagePoints.emplace_back(imagePoints[imagePointIndex]);
446 matchedObjectPoints.emplace_back(objectPoints[objectPointIndex]);
450 if (matchedImagePoints.size() <
size_t(minimalNumberCorrespondences))
457 Indices32 internalUsedObjectPointIndices;
460 const bool useInternalIndices = usedObjectPointIndices !=
nullptr || usedImagePointIndices !=
nullptr;
462 if (useInternalIndices)
464 internalUsedObjectPointIndices.reserve(numberImagePoints);
465 internalUsedImagePointIndices.reserve(numberImagePoints);
469 ocean_assert(faultyRate >=
Scalar(0) && faultyRate <
Scalar(1));
478 if (world_T_roughCamera.
isValid())
480 world_T_camera = world_T_roughCamera;
483 matchedImagePoints.clear();
484 matchedObjectPoints.clear();
488 for (
size_t imagePointIndex = 0; imagePointIndex < numberImagePoints; ++imagePointIndex)
490 const Vector2& imagePoint = imagePoints[imagePointIndex];
491 const TImagePointDescriptor& imagePointDescriptor = imagePointDescriptors[imagePointIndex];
496 for (
size_t nObjectPoint = 0; nObjectPoint < numberObjectDescriptors; ++nObjectPoint)
498 const TDescriptorDistance distance = tImageObjectDistanceFunction(imagePointDescriptor, objectPointDescriptors[nObjectPoint]);
500 if (distance < bestDistance)
502 const Index32 objectPointIndex = objectPointIndices[nObjectPoint];
504 const Vector3& objectPoint = objectPoints[objectPointIndex];
508 bestDistance = distance;
509 bestObjectPointDescriptorIndex =
Index32(nObjectPoint);
514 if (bestDistance <= maximalDescriptorDistance)
516 const Index32 objectPointIndex = objectPointIndices[bestObjectPointDescriptorIndex];
518 matchedImagePoints.emplace_back(imagePoints[imagePointIndex]);
519 matchedObjectPoints.emplace_back(objectPoints[objectPointIndex]);
521 if (useInternalIndices)
523 internalUsedObjectPointIndices.emplace_back(objectPointIndex);
524 internalUsedImagePointIndices.emplace_back(
Index32(imagePointIndex));
529 if (matchedImagePoints.size() <
size_t(minimalNumberCorrespondences))
535 constexpr unsigned int guidedIterations = 40u;
538 validIndices.clear();
541 if (usedObjectPointIndices !=
nullptr)
543 ocean_assert(useInternalIndices);
545 usedObjectPointIndices->clear();
546 usedObjectPointIndices->reserve(validIndices.size());
548 for (
const Index32 validIndex : validIndices)
550 usedObjectPointIndices->emplace_back(internalUsedObjectPointIndices[validIndex]);
554 if (usedImagePointIndices !=
nullptr)
556 ocean_assert(useInternalIndices);
558 usedImagePointIndices->clear();
559 usedImagePointIndices->reserve(validIndices.size());
561 for (
const Index32 validIndex : validIndices)
563 usedImagePointIndices->emplace_back(internalUsedImagePointIndices[validIndex]);
576template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
577void 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)
579 ocean_assert(objectPointDescriptors !=
nullptr);
580 ocean_assert(imagePointDescriptors !=
nullptr);
581 ocean_assert(objectPointDescriptorIndices !=
nullptr);
583 if (worker && (numberObjectPointDescriptors >= 1000 || numberImagePointDescriptors >= 1000))
585 worker->
executeFunction(
Worker::Function::createStatic(&determineUnguidedBruteForceMatchingsSubset<TImagePointDescriptor, TObjectPointDescriptor, TDescriptorDistance, tImageObjectDistanceFunction>, objectPointDescriptors, numberObjectPointDescriptors, imagePointDescriptors, maximalDescriptorDistance, objectPointDescriptorIndices, distances, 0u, 0u), 0u, (
unsigned int)(numberImagePointDescriptors));
589 determineUnguidedBruteForceMatchingsSubset<TImagePointDescriptor, TObjectPointDescriptor, TDescriptorDistance, tImageObjectDistanceFunction>(objectPointDescriptors, numberObjectPointDescriptors, imagePointDescriptors, maximalDescriptorDistance, objectPointDescriptorIndices, distances, 0u, (
unsigned int)(numberImagePointDescriptors));
593template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
594void 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)
596 ocean_assert(camera.
isValid());
597 ocean_assert(world_T_roughCamera.
isValid());
598 ocean_assert(objectPoints !=
nullptr);
599 ocean_assert(objectPointDescriptors !=
nullptr);
600 ocean_assert(imagePoints !=
nullptr);
601 ocean_assert(imagePointDescriptors !=
nullptr);
602 ocean_assert(objectPointDescriptorIndices !=
nullptr);
603 ocean_assert(maximalProjectionError >= 0);
605 if (worker && (numberObjectPoints >= 1000 || numberImagePoints >= 1000))
607 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));
611 determineGuidedBruteForceMatchingsSubset<TImagePointDescriptor, TObjectPointDescriptor, TDescriptorDistance, tImageObjectDistanceFunction>(&camera, &world_T_roughCamera, objectPoints, objectPointDescriptors, numberObjectPoints, imagePoints, imagePointDescriptors, maximalDescriptorDistance, maximalProjectionError, objectPointDescriptorIndices, 0u, (
unsigned int)(numberImagePoints));
615template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
616void 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)
618 ocean_assert(objectPointDescriptors !=
nullptr);
619 ocean_assert(imagePointDescriptors !=
nullptr);
621 for (
size_t imagePointIndex =
size_t(firstImagePointDescriptor); imagePointIndex <
size_t(firstImagePointDescriptor + numberImagePointDescriptors); ++imagePointIndex)
623 const TImagePointDescriptor& imagePointDescriptor = imagePointDescriptors[imagePointIndex];
628 for (
size_t objectPointIndex = 0; objectPointIndex < numberObjectPointDescriptors; ++objectPointIndex)
630 const TDescriptorDistance distance = tImageObjectDistanceFunction(imagePointDescriptor, objectPointDescriptors[objectPointIndex]);
632 if (distance < bestDistance)
634 bestDistance = distance;
635 bestObjectPointIndex =
Index32(objectPointIndex);
639 if (bestDistance <= maximalDescriptorDistance)
641 objectPointDescriptorIndices[imagePointIndex] = bestObjectPointIndex;
643 if (distances !=
nullptr)
645 distances[imagePointIndex] = bestDistance;
650 objectPointDescriptorIndices[imagePointIndex] =
Index32(-1);
655template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
656void 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)
658 ocean_assert(camera !=
nullptr && camera->
isValid());
659 ocean_assert(world_T_roughCamera !=
nullptr && world_T_roughCamera->
isValid());
660 ocean_assert(objectPoints !=
nullptr);
661 ocean_assert(objectPointDescriptors !=
nullptr);
662 ocean_assert(imagePoints !=
nullptr);
663 ocean_assert(imagePointDescriptors !=
nullptr);
664 ocean_assert(maximalProjectionError >= 0);
670 for (
size_t imagePointIndex =
size_t(firstImagePoint); imagePointIndex <
size_t(firstImagePoint + numberImagePoints); ++imagePointIndex)
672 const Vector2& imagePoint = imagePoints[imagePointIndex];
673 ocean_assert(camera->
isInside(imagePoint));
675 const TImagePointDescriptor& imagePointDescriptor = imagePointDescriptors[imagePointIndex];
680 for (
size_t objectPointIndex = 0; objectPointIndex < numberObjectPoints; ++objectPointIndex)
682 const TDescriptorDistance distance = tImageObjectDistanceFunction(imagePointDescriptor, objectPointDescriptors[objectPointIndex]);
684 if (distance < bestDistance)
686 const Vector3& objectPoint = objectPoints[objectPointIndex];
690 bestDistance = distance;
691 bestObjectPointIndex =
Index32(objectPointIndex);
696 if (bestDistance <= maximalDescriptorDistance)
698 objectPointDescriptorIndices[imagePointIndex] = bestObjectPointIndex;
702 objectPointDescriptorIndices[imagePointIndex] =
Index32(-1);
707template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
708void 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)
711 ocean_assert(imagePoints !=
nullptr && imagePointDescriptors !=
nullptr && numberImagePoints >= 1);
712 ocean_assert(objectPoints !=
nullptr && objectPointIds !=
nullptr);
714 ocean_assert(matchedImagePoints.empty());
715 ocean_assert(matchedObjectPoints.empty());
717 if (matchedObjectPointIds !=
nullptr)
719 matchedObjectPointIds->clear();
722 if (matchedImagePointIndices !=
nullptr)
724 matchedImagePointIndices->clear();
727 if (worker !=
nullptr)
730 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));
734 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));
738template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
739std::vector<TDescriptorDistance>
PoseEstimationT::determineDescriptorDistances(
const TObjectPointDescriptor* objectPointDescriptors,
const TImagePointDescriptor* imagePointDescriptors,
const Index32* objectPointDescriptorIndices,
const Index32* imagePointDescriptorIndices,
const size_t numberCorrespondences)
741 ocean_assert(objectPointDescriptors !=
nullptr);
742 ocean_assert(imagePointDescriptors !=
nullptr);
743 ocean_assert(objectPointDescriptorIndices !=
nullptr);
744 ocean_assert(imagePointDescriptorIndices !=
nullptr);
745 ocean_assert(numberCorrespondences >= 1);
747 std::vector<TDescriptorDistance> result;
748 result.reserve(numberCorrespondences);
750 for (
size_t n = 0; n < numberCorrespondences; ++n)
752 const Index32& objectPointDescriptorIndex = objectPointDescriptorIndices[n];
753 const Index32& imagePointDescriptorIndex = imagePointDescriptorIndices[n];
755 result.emplace_back(tImageObjectDistanceFunction(imagePointDescriptors[imagePointDescriptorIndex], objectPointDescriptors[objectPointDescriptorIndex]));
761template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
762void 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)
764 static_assert(tImageObjectDistanceFunction !=
nullptr);
766 ocean_assert(camera !=
nullptr && camera->
isValid());
767 ocean_assert(world_T_camera && world_T_camera->
isValid());
769 ocean_assert(imagePoints !=
nullptr && imagePointDescriptors !=
nullptr && objectPoints !=
nullptr);
770 ocean_assert(objectPointOctree !=
nullptr && objectPointIds !=
nullptr && objectPointDescriptorMap !=
nullptr);
772 ocean_assert(matchedImagePoints !=
nullptr);
773 ocean_assert(matchedObjectPoints !=
nullptr);
780 localMatchedImagePoints.reserve(numberImagePoints);
781 localMatchedObjectPoints.reserve(numberImagePoints);
782 localMatchedImagePointIndices.reserve(numberImagePoints);
783 localMatchedObjectPointIds.reserve(numberImagePoints);
789 std::vector<const Indices32*> leaves;
792 constexpr Scalar maximalSqrProjectionError =
Scalar(20 * 20);
794 Geometry::Octree::ReusableData reusableData;
796 for (
unsigned int nImagePoint = firstImagePoint; nImagePoint < firstImagePoint + numberImagePoints; ++nImagePoint)
798 const Vector2& imagePoint = imagePoints[nImagePoint];
799 ocean_assert(camera->
isInside(imagePoint));
801 const TImagePointDescriptor& imagePointDescriptor = imagePointDescriptors[nImagePoint];
803 const Line3 ray = camera->
ray(imagePoint, *world_T_camera);
806 objectPointOctree->intersectingLeaves(ray, tanHalfAngle, leaves, reusableData);
813 for (
const Index32& objectPointIndex : *leaf)
815 const Vector3& objectPoint = objectPoints[objectPointIndex];
819 const Index32 objectPointId = objectPointIds[objectPointIndex];
821 ocean_assert(iObjectPointDescriptor != objectPointDescriptorMap->cend());
823 const TDescriptorDistance distance = tImageObjectDistanceFunction(imagePointDescriptor, iObjectPointDescriptor->second);
825 if (distance < bestDistance)
827 bestDistance = distance;
828 bestObjectPointIndex = objectPointIndex;
834 if (bestDistance <= maximalDescriptorDistance)
836 ocean_assert(bestObjectPointIndex !=
Index32(-1));
838 localMatchedImagePoints.emplace_back(imagePoint);
839 localMatchedObjectPoints.emplace_back(objectPoints[bestObjectPointIndex]);
841 localMatchedImagePointIndices.emplace_back(nImagePoint);
842 localMatchedObjectPointIds.emplace_back(objectPointIds[bestObjectPointIndex]);
848 matchedImagePoints->insert(matchedImagePoints->cend(), localMatchedImagePoints.cbegin(), localMatchedImagePoints.cend());
849 matchedObjectPoints->insert(matchedObjectPoints->cend(), localMatchedObjectPoints.cbegin(), localMatchedObjectPoints.cend());
851 if (matchedImagePointIndices !=
nullptr)
853 matchedImagePointIndices->insert(matchedImagePointIndices->cend(), localMatchedImagePointIndices.cbegin(), localMatchedImagePointIndices.cend());
856 if (matchedObjectPointIds !=
nullptr)
858 matchedObjectPointIds->insert(matchedObjectPointIds->cend(), localMatchedObjectPointIds.cbegin(), localMatchedObjectPointIds.cend());
This class implements the abstract base class for all AnyCamera objects.
Definition AnyCamera.h:130
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:734
static bool isObjectPointInFrontIF(const HomogenousMatrixT4< T > &flippedCamera_T_world, const VectorT3< T > &objectPoint, const T epsilon=NumericT< T >::eps())
Determines whether a given 3D object point lies in front of a camera while the location of the camera...
Definition Camera.h:811
This class implements an accessor providing direct access to a constant array of elements.
Definition Accessor.h:400
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.
static bool p3p(const AnyCamera &anyCamera, const ConstIndexedAccessor< ObjectPoint > &objectPointAccessor, const ConstIndexedAccessor< ImagePoint > &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...
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:3235
static T tan(const T value)
Returns the tangent of a given value.
Definition Numeric.h:1600
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:3247
This class implements an optional recursive scoped lock object locking the lock object only if it's d...
Definition Lock.h:337
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:35
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 (without known rough camera pose) between image point and object point...
Definition PoseEstimationT.h:594
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:656
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:762
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:739
std::unordered_map< Index32, TDescriptor > UnorderedDescriptorMap
Definition of an unordered map mapping object point ids to descriptors.
Definition PoseEstimationT.h:42
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:577
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)
Determines the 6-DOF pose for 2D/3D correspondences applying a brute-force search.
Definition PoseEstimationT.h:258
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:616
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:399
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:708
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
OctreeT< Scalar > Octree
Definition of an Octree using Scalar as data type.
Definition Octree.h:32
float Scalar
Definition of a scalar type.
Definition Math.h:129
std::vector< Vector2 > Vectors2
Definition of a vector holding Vector2 objects.
Definition Vector2.h:64
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