8 #ifndef META_OCEAN_TRACKING_MAPBUILDING_POSE_ESTIMATION_T_H
9 #define META_OCEAN_TRACKING_MAPBUILDING_POSE_ESTIMATION_T_H
44 template <
typename TDescriptor>
75 template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
76 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);
106 template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
107 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));
124 template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
125 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);
146 template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
147 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);
171 template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
172 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);
188 template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
189 static std::vector<TDescriptorDistance> determineDescriptorDistances(
const TObjectPointDescriptor* objectPointDescriptors,
const TImagePointDescriptor* imagePointDescriptors,
const Index32* objectPointDescriptorIndices,
const Index32* imagePointDescriptorIndices,
const size_t numberCorrespondences);
208 template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
209 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);
230 template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
231 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);
256 template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
257 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);
260 template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
262 * 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)
264 ocean_assert(camera.
isValid());
266 ocean_assert(maximalProjectionError >=
Scalar(0));
267 ocean_assert(inlierRate >
Scalar(0) && inlierRate <=
Scalar(1));
269 if (numberImagePoints <
size_t(minimalNumberCorrespondences))
274 const Scalar maximalSqrProjectionError = maximalProjectionError * maximalProjectionError;
276 Indices32 matchedObjectPointIds(numberImagePoints);
281 matchedImagePoints.reserve(numberImagePoints);
282 matchedObjectPoints.reserve(numberImagePoints);
284 if (!world_T_roughCamera.
isValid())
286 determineUnguidedBruteForceMatchings<TImagePointDescriptor, TObjectPointDescriptor, TDescriptorDistance, tImageObjectDistanceFunction>(objectPointDescriptors, numberObjectPoints, imagePointDescriptors, numberImagePoints, maximalDescriptorDistance, matchedObjectPointIds.data(), worker);
288 for (
size_t imagePointIndex = 0; imagePointIndex < numberImagePoints; ++imagePointIndex)
290 const Index32& matchedObjectPointIndex = matchedObjectPointIds[imagePointIndex];
292 if (matchedObjectPointIndex !=
Index32(-1))
294 matchedImagePoints.emplace_back(imagePoints[imagePointIndex]);
295 matchedObjectPoints.emplace_back(objectPoints[matchedObjectPointIndex]);
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));
329 if (world_T_roughCamera.
isValid())
331 world_T_camera = world_T_roughCamera;
334 matchedImagePoints.clear();
335 matchedObjectPoints.clear();
337 determineGuidedBruteForceMatchings<TImagePointDescriptor, TObjectPointDescriptor, TDescriptorDistance, tImageObjectDistanceFunction>(camera, world_T_camera, objectPoints, objectPointDescriptors, numberObjectPoints, imagePoints, imagePointDescriptors, numberImagePoints, maximalDescriptorDistance, maximalProjectionError, matchedObjectPointIds.
data(), worker);
339 for (
size_t imagePointIndex = 0; imagePointIndex < numberImagePoints; ++imagePointIndex)
341 const Index32& matchedObjectPointIndex = matchedObjectPointIds[imagePointIndex];
343 if (matchedObjectPointIndex !=
Index32(-1))
345 matchedImagePoints.emplace_back(imagePoints[imagePointIndex]);
346 matchedObjectPoints.emplace_back(objectPoints[matchedObjectPointIndex]);
348 if (useInternalIndices)
350 internalUsedImagePointIndices.emplace_back(
Index32(imagePointIndex));
351 internalUsedObjectPointIndices.emplace_back(matchedObjectPointIndex);
356 if (matchedImagePoints.size() <
size_t(minimalNumberCorrespondences))
362 constexpr
unsigned int guidedIterations = 40u;
365 validIndices.clear();
368 if (usedObjectPointIndices !=
nullptr)
370 ocean_assert(useInternalIndices);
372 usedObjectPointIndices->clear();
373 usedObjectPointIndices->reserve(validIndices.size());
375 for (
const Index32 validIndex : validIndices)
377 usedObjectPointIndices->emplace_back(internalUsedObjectPointIndices[validIndex]);
381 if (usedImagePointIndices !=
nullptr)
383 ocean_assert(useInternalIndices);
385 usedImagePointIndices->clear();
386 usedImagePointIndices->reserve(validIndices.size());
388 for (
const Index32 validIndex : validIndices)
390 usedImagePointIndices->emplace_back(internalUsedImagePointIndices[validIndex]);
403 template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
404 bool 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)
406 ocean_assert(camera.
isValid());
408 ocean_assert(maximalProjectionError >=
Scalar(0));
409 ocean_assert(inlierRate >
Scalar(0) && inlierRate <=
Scalar(1));
411 if (numberImagePoints <
size_t(minimalNumberCorrespondences))
416 const Scalar maximalSqrProjectionError = maximalProjectionError * maximalProjectionError;
421 matchedImagePoints.reserve(numberImagePoints);
422 matchedObjectPoints.reserve(numberImagePoints);
424 if (!world_T_roughCamera.
isValid())
428 for (
size_t imagePointIndex = 0; imagePointIndex < numberImagePoints; ++imagePointIndex)
430 const TImagePointDescriptor& imagePointDescriptor = imagePointDescriptors[imagePointIndex];
435 for (
size_t nObjectPoint = 0; nObjectPoint < numberObjectDescriptors; ++nObjectPoint)
437 const TDescriptorDistance distance = tImageObjectDistanceFunction(imagePointDescriptor, objectPointDescriptors[nObjectPoint]);
439 if (distance < bestDistance)
441 bestDistance = distance;
442 bestObjectPointDescriptorIndex =
Index32(nObjectPoint);
446 if (bestDistance <= maximalDescriptorDistance)
448 const Index32 objectPointIndex = objectPointIndices[bestObjectPointDescriptorIndex];
450 matchedImagePoints.emplace_back(imagePoints[imagePointIndex]);
451 matchedObjectPoints.emplace_back(objectPoints[objectPointIndex]);
455 if (matchedImagePoints.size() <
size_t(minimalNumberCorrespondences))
462 Indices32 internalUsedObjectPointIndices;
465 const bool useInternalIndices = usedObjectPointIndices !=
nullptr || usedImagePointIndices !=
nullptr;
467 if (useInternalIndices)
469 internalUsedObjectPointIndices.reserve(numberImagePoints);
470 internalUsedImagePointIndices.reserve(numberImagePoints);
474 ocean_assert(faultyRate >=
Scalar(0) && faultyRate <
Scalar(1));
483 if (world_T_roughCamera.
isValid())
485 world_T_camera = world_T_roughCamera;
488 matchedImagePoints.clear();
489 matchedObjectPoints.clear();
493 for (
size_t imagePointIndex = 0; imagePointIndex < numberImagePoints; ++imagePointIndex)
495 const Vector2& imagePoint = imagePoints[imagePointIndex];
496 const TImagePointDescriptor& imagePointDescriptor = imagePointDescriptors[imagePointIndex];
501 for (
size_t nObjectPoint = 0; nObjectPoint < numberObjectDescriptors; ++nObjectPoint)
503 const TDescriptorDistance distance = tImageObjectDistanceFunction(imagePointDescriptor, objectPointDescriptors[nObjectPoint]);
505 if (distance < bestDistance)
507 const Index32 objectPointIndex = objectPointIndices[nObjectPoint];
509 const Vector3& objectPoint = objectPoints[objectPointIndex];
513 bestDistance = distance;
514 bestObjectPointDescriptorIndex =
Index32(nObjectPoint);
519 if (bestDistance <= maximalDescriptorDistance)
521 const Index32 objectPointIndex = objectPointIndices[bestObjectPointDescriptorIndex];
523 matchedImagePoints.emplace_back(imagePoints[imagePointIndex]);
524 matchedObjectPoints.emplace_back(objectPoints[objectPointIndex]);
526 if (useInternalIndices)
528 internalUsedObjectPointIndices.emplace_back(objectPointIndex);
529 internalUsedImagePointIndices.emplace_back(
Index32(imagePointIndex));
534 if (matchedImagePoints.size() <
size_t(minimalNumberCorrespondences))
540 constexpr
unsigned int guidedIterations = 40u;
543 validIndices.clear();
546 if (usedObjectPointIndices !=
nullptr)
548 ocean_assert(useInternalIndices);
550 usedObjectPointIndices->clear();
551 usedObjectPointIndices->reserve(validIndices.size());
553 for (
const Index32 validIndex : validIndices)
555 usedObjectPointIndices->emplace_back(internalUsedObjectPointIndices[validIndex]);
559 if (usedImagePointIndices !=
nullptr)
561 ocean_assert(useInternalIndices);
563 usedImagePointIndices->clear();
564 usedImagePointIndices->reserve(validIndices.size());
566 for (
const Index32 validIndex : validIndices)
568 usedImagePointIndices->emplace_back(internalUsedImagePointIndices[validIndex]);
581 template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
582 void 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)
584 ocean_assert(objectPointDescriptors !=
nullptr);
585 ocean_assert(imagePointDescriptors !=
nullptr);
586 ocean_assert(objectPointDescriptorIndices !=
nullptr);
588 if (worker && (numberObjectPointDescriptors >= 1000 || numberImagePointDescriptors >= 1000))
590 worker->
executeFunction(
Worker::Function::createStatic(&determineUnguidedBruteForceMatchingsSubset<TImagePointDescriptor, TObjectPointDescriptor, TDescriptorDistance, tImageObjectDistanceFunction>, objectPointDescriptors, numberObjectPointDescriptors, imagePointDescriptors, maximalDescriptorDistance, objectPointDescriptorIndices, distances, 0u, 0u), 0u, (
unsigned int)(numberImagePointDescriptors));
594 determineUnguidedBruteForceMatchingsSubset<TImagePointDescriptor, TObjectPointDescriptor, TDescriptorDistance, tImageObjectDistanceFunction>(objectPointDescriptors, numberObjectPointDescriptors, imagePointDescriptors, maximalDescriptorDistance, objectPointDescriptorIndices, distances, 0u, (
unsigned int)(numberImagePointDescriptors));
598 template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
599 void 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)
601 ocean_assert(camera.
isValid());
602 ocean_assert(world_T_roughCamera.
isValid());
603 ocean_assert(objectPoints !=
nullptr);
604 ocean_assert(objectPointDescriptors !=
nullptr);
605 ocean_assert(imagePoints !=
nullptr);
606 ocean_assert(imagePointDescriptors !=
nullptr);
607 ocean_assert(objectPointDescriptorIndices !=
nullptr);
608 ocean_assert(maximalProjectionError >= 0);
610 if (worker && (numberObjectPoints >= 1000 || numberImagePoints >= 1000))
612 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));
616 determineGuidedBruteForceMatchingsSubset<TImagePointDescriptor, TObjectPointDescriptor, TDescriptorDistance, tImageObjectDistanceFunction>(&camera, &world_T_roughCamera, objectPoints, objectPointDescriptors, numberObjectPoints, imagePoints, imagePointDescriptors, maximalDescriptorDistance, maximalProjectionError, objectPointDescriptorIndices, 0u, (
unsigned int)(numberImagePoints));
620 template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
621 void 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)
623 ocean_assert(objectPointDescriptors !=
nullptr);
624 ocean_assert(imagePointDescriptors !=
nullptr);
626 for (
size_t imagePointIndex =
size_t(firstImagePointDescriptor); imagePointIndex < size_t(firstImagePointDescriptor + numberImagePointDescriptors); ++imagePointIndex)
628 const TImagePointDescriptor& imagePointDescriptor = imagePointDescriptors[imagePointIndex];
633 for (
size_t objectPointIndex = 0; objectPointIndex < numberObjectPointDescriptors; ++objectPointIndex)
635 const TDescriptorDistance distance = tImageObjectDistanceFunction(imagePointDescriptor, objectPointDescriptors[objectPointIndex]);
637 if (distance < bestDistance)
639 bestDistance = distance;
640 bestObjectPointIndex =
Index32(objectPointIndex);
644 if (bestDistance <= maximalDescriptorDistance)
646 objectPointDescriptorIndices[imagePointIndex] = bestObjectPointIndex;
648 if (distances !=
nullptr)
650 distances[imagePointIndex] = bestDistance;
655 objectPointDescriptorIndices[imagePointIndex] =
Index32(-1);
660 template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
661 void 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)
663 ocean_assert(camera !=
nullptr && camera->
isValid());
664 ocean_assert(world_T_roughCamera !=
nullptr && world_T_roughCamera->
isValid());
665 ocean_assert(objectPoints !=
nullptr);
666 ocean_assert(objectPointDescriptors !=
nullptr);
667 ocean_assert(imagePoints !=
nullptr);
668 ocean_assert(imagePointDescriptors !=
nullptr);
669 ocean_assert(maximalProjectionError >= 0);
675 for (
size_t imagePointIndex =
size_t(firstImagePoint); imagePointIndex < size_t(firstImagePoint + numberImagePoints); ++imagePointIndex)
677 const Vector2& imagePoint = imagePoints[imagePointIndex];
678 ocean_assert(camera->
isInside(imagePoint));
680 const TImagePointDescriptor& imagePointDescriptor = imagePointDescriptors[imagePointIndex];
685 for (
size_t objectPointIndex = 0; objectPointIndex < numberObjectPoints; ++objectPointIndex)
687 const TDescriptorDistance distance = tImageObjectDistanceFunction(imagePointDescriptor, objectPointDescriptors[objectPointIndex]);
689 if (distance < bestDistance)
691 const Vector3& objectPoint = objectPoints[objectPointIndex];
695 bestDistance = distance;
696 bestObjectPointIndex =
Index32(objectPointIndex);
701 if (bestDistance <= maximalDescriptorDistance)
703 objectPointDescriptorIndices[imagePointIndex] = bestObjectPointIndex;
707 objectPointDescriptorIndices[imagePointIndex] =
Index32(-1);
712 template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
713 void 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)
716 ocean_assert(imagePoints !=
nullptr && imagePointDescriptors !=
nullptr && numberImagePoints >= 1);
717 ocean_assert(objectPoints !=
nullptr && objectPointIds !=
nullptr);
719 ocean_assert(matchedImagePoints.empty());
720 ocean_assert(matchedObjectPoints.empty());
722 if (matchedObjectPointIds !=
nullptr)
724 matchedObjectPointIds->clear();
727 if (matchedImagePointIndices !=
nullptr)
729 matchedImagePointIndices->clear();
732 if (worker !=
nullptr)
735 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));
739 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));
743 template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
744 std::vector<TDescriptorDistance>
PoseEstimationT::determineDescriptorDistances(
const TObjectPointDescriptor* objectPointDescriptors,
const TImagePointDescriptor* imagePointDescriptors,
const Index32* objectPointDescriptorIndices,
const Index32* imagePointDescriptorIndices,
const size_t numberCorrespondences)
746 ocean_assert(objectPointDescriptors !=
nullptr);
747 ocean_assert(imagePointDescriptors !=
nullptr);
748 ocean_assert(objectPointDescriptorIndices !=
nullptr);
749 ocean_assert(imagePointDescriptorIndices !=
nullptr);
750 ocean_assert(numberCorrespondences >= 1);
752 std::vector<TDescriptorDistance> result;
753 result.reserve(numberCorrespondences);
755 for (
size_t n = 0; n < numberCorrespondences; ++n)
757 const Index32& objectPointDescriptorIndex = objectPointDescriptorIndices[n];
758 const Index32& imagePointDescriptorIndex = imagePointDescriptorIndices[n];
760 result.emplace_back(tImageObjectDistanceFunction(imagePointDescriptors[imagePointDescriptorIndex], objectPointDescriptors[objectPointDescriptorIndex]));
766 template <
typename TImagePo
intDescriptor,
typename TObjectPo
intDescriptor,
typename TDescriptorDistance, TDescriptorDistance(*tImageObjectDistanceFunction)(const TImagePo
intDescriptor&, const TObjectPo
intDescriptor&)>
767 void 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)
769 static_assert(tImageObjectDistanceFunction !=
nullptr);
771 ocean_assert(camera !=
nullptr && camera->
isValid());
772 ocean_assert(world_T_camera && world_T_camera->
isValid());
774 ocean_assert(imagePoints !=
nullptr && imagePointDescriptors !=
nullptr && objectPoints !=
nullptr);
775 ocean_assert(objectPointOctree !=
nullptr && objectPointIds !=
nullptr && objectPointDescriptorMap !=
nullptr);
777 ocean_assert(matchedImagePoints !=
nullptr);
778 ocean_assert(matchedObjectPoints !=
nullptr);
785 localMatchedImagePoints.reserve(numberImagePoints);
786 localMatchedObjectPoints.reserve(numberImagePoints);
787 localMatchedImagePointIndices.reserve(numberImagePoints);
788 localMatchedObjectPointIds.reserve(numberImagePoints);
794 std::vector<const Indices32*> leafs;
797 constexpr
Scalar maximalSqrProjectionError =
Scalar(20 * 20);
799 Geometry::Octree::ReusableData resuableData;
801 for (
unsigned int nImagePoint = firstImagePoint; nImagePoint < firstImagePoint + numberImagePoints; ++nImagePoint)
803 const Vector2& imagePoint = imagePoints[nImagePoint];
804 ocean_assert(camera->
isInside(imagePoint));
806 const TImagePointDescriptor& imagePointDescriptor = imagePointDescriptors[nImagePoint];
808 const Line3 ray = camera->
ray(imagePoint, *world_T_camera);
811 objectPointOctree->intersectingLeafs(ray, tanHalfAngle, leafs, resuableData);
818 for (
const Index32& objectPointIndex : *leaf)
820 const Vector3& objectPoint = objectPoints[objectPointIndex];
824 const Index32 objectPointId = objectPointIds[objectPointIndex];
826 ocean_assert(iObjectPointDescriptor != objectPointDescriptorMap->cend());
828 const TDescriptorDistance distance = tImageObjectDistanceFunction(imagePointDescriptor, iObjectPointDescriptor->second);
830 if (distance < bestDistance)
832 bestDistance = distance;
833 bestObjectPointIndex = objectPointIndex;
839 if (bestDistance <= maximalDescriptorDistance)
841 ocean_assert(bestObjectPointIndex !=
Index32(-1));
843 localMatchedImagePoints.emplace_back(imagePoint);
844 localMatchedObjectPoints.emplace_back(objectPoints[bestObjectPointIndex]);
846 localMatchedImagePointIndices.emplace_back(nImagePoint);
847 localMatchedObjectPointIds.emplace_back(objectPointIds[bestObjectPointIndex]);
853 matchedImagePoints->insert(matchedImagePoints->cend(), localMatchedImagePoints.cbegin(), localMatchedImagePoints.cend());
854 matchedObjectPoints->insert(matchedObjectPoints->cend(), localMatchedObjectPoints.cbegin(), localMatchedObjectPoints.cend());
856 if (matchedImagePointIndices !=
nullptr)
858 matchedImagePointIndices->insert(matchedImagePointIndices->cend(), localMatchedImagePointIndices.cbegin(), localMatchedImagePointIndices.cend());
861 if (matchedObjectPointIds !=
nullptr)
863 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: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
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:811
This class implements an accessor providing direct access to a constant array of elements.
Definition: Accessor.h:400
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)
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:70
This class implements a recursive lock object.
Definition: Lock.h:31
static MessageObject info()
Returns the message for information messages.
Definition: Messenger.h:1064
static constexpr T deg2rad(const T deg)
Converts deg to rad.
Definition: Numeric.h:3232
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:3244
This class implements an optional recursive scoped lock object locking the lock object only if it's d...
Definition: Lock.h:325
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:38
std::unordered_map< Index32, TDescriptor > UnorderedDescriptorMap
Definition of an unordered map mapping object point ids to descriptors.
Definition: PoseEstimationT.h:45
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:261
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:404
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:621
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:661
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:713
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:599
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:767
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:744
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:582
const T * data() const noexcept
Returns an pointer to the vector elements.
Definition: Vector2.h:722
This class implements a worker able to distribute function calls over different threads.
Definition: Worker.h:33
bool executeFunction(const Function &function, const unsigned int first, const unsigned int size, const unsigned int firstIndex=(unsigned int)(-1), const unsigned int sizeIndex=(unsigned int)(-1), const unsigned int minimalIterations=1u, const unsigned int threadIndex=(unsigned int)(-1))
Executes a callback function separable by two function parameters.
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:25
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
HomogenousMatrixT4< Scalar > HomogenousMatrix4
Definition of the HomogenousMatrix4 object, depending on the OCEAN_MATH_USE_SINGLE_PRECISION flag eit...
Definition: HomogenousMatrix4.h:37
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