From 0a4faee3db88dde8b8ebdf0aff7a5c4ddabcd890 Mon Sep 17 00:00:00 2001 From: pmoulon Date: Tue, 7 May 2019 12:56:00 -0700 Subject: [PATCH] Set lambda twist p3p solver (ECCV 2018) as default p3p solver #1500 - add resection::SolverType::P3P_NORDBERG_ECCV18 to the SfM_Localizer - set resection::SolverType::P3P_NORDBERG_ECCV18 as the default p3p solver for sequential SfM v1, v2 and the image localization client. --- .../pipelines/localization/SfM_Localizer.cpp | 30 +++++++++++++++++++ .../pipelines/sequential/sequential_SfM.cpp | 4 +-- .../pipelines/sequential/sequential_SfM2.cpp | 6 ++-- .../Localization/main_SfM_Localization.cpp | 2 +- 4 files changed, 36 insertions(+), 6 deletions(-) diff --git a/src/openMVG/sfm/pipelines/localization/SfM_Localizer.cpp b/src/openMVG/sfm/pipelines/localization/SfM_Localizer.cpp index 2de6080137..c0a3060a6d 100644 --- a/src/openMVG/sfm/pipelines/localization/SfM_Localizer.cpp +++ b/src/openMVG/sfm/pipelines/localization/SfM_Localizer.cpp @@ -166,6 +166,36 @@ namespace sfm { resection_data.error_max = ACRansacOut.first; } break; + case resection::SolverType::P3P_NORDBERG_ECCV18: + { + if (!optional_intrinsics) + { + std::cerr << "Intrinsic data is required for P3P solvers." << std::endl; + return false; + } + //-- + // Since the intrinsic data is known, compute only the pose + using SolverType = openMVG::euclidean_resection::P3PSolver_Nordberg; + MINIMUM_SAMPLES = SolverType::MINIMUM_SAMPLES; + + using KernelType = + ACKernelAdaptorResection_Intrinsics< + SolverType, + Mat34>; + + KernelType kernel(resection_data.pt2D, resection_data.pt3D, optional_intrinsics); + // Robust estimation of the pose matrix and its precision + const auto ACRansacOut = + openMVG::robust::ACRANSAC(kernel, + resection_data.vec_inliers, + resection_data.max_iteration, + &P, + dPrecision, + true); + // Update the upper bound precision of the model found by AC-RANSAC + resection_data.error_max = ACRansacOut.first; + } + break; case resection::SolverType::P3P_KE_CVPR17: { if (!optional_intrinsics) diff --git a/src/openMVG/sfm/pipelines/sequential/sequential_SfM.cpp b/src/openMVG/sfm/pipelines/sequential/sequential_SfM.cpp index 1e3eecc5f7..f720da9f1b 100644 --- a/src/openMVG/sfm/pipelines/sequential/sequential_SfM.cpp +++ b/src/openMVG/sfm/pipelines/sequential/sequential_SfM.cpp @@ -439,7 +439,7 @@ bool SequentialSfMReconstructionEngine::AutomaticInitialPairChoice(Pair & initia tracks::submapTrack::const_iterator iter = iterT->second.begin(); const Vec2 featI = features_provider_->feats_per_view[I][iter->second].coords().cast(); const Vec2 featJ = features_provider_->feats_per_view[J][(++iter)->second].coords().cast(); - vec_angles.push_back(AngleBetweenRay(pose_I, cam_I, pose_J, cam_J, + vec_angles.push_back(AngleBetweenRay(pose_I, cam_I, pose_J, cam_J, cam_I->get_ud_pixel(featI), cam_J->get_ud_pixel(featJ))); } // Compute the median triangulation angle @@ -944,7 +944,7 @@ bool SequentialSfMReconstructionEngine::Resection(const uint32_t viewIndex) geometry::Pose3 pose; const bool bResection = sfm::SfM_Localizer::Localize ( - optional_intrinsic ? resection::SolverType::P3P_KE_CVPR17 : resection::SolverType::DLT_6POINTS, + optional_intrinsic ? resection::SolverType::P3P_NORDBERG_ECCV18 : resection::SolverType::DLT_6POINTS, {view_I->ui_width, view_I->ui_height}, optional_intrinsic.get(), resection_data, diff --git a/src/openMVG/sfm/pipelines/sequential/sequential_SfM2.cpp b/src/openMVG/sfm/pipelines/sequential/sequential_SfM2.cpp index f6027bb908..bbbf0c1251 100644 --- a/src/openMVG/sfm/pipelines/sequential/sequential_SfM2.cpp +++ b/src/openMVG/sfm/pipelines/sequential/sequential_SfM2.cpp @@ -151,7 +151,7 @@ bool SequentialSfMReconstructionEngine2::Process() { // First the camera with the most of 2D-3D overlap are added then we add // ones with lower confidence. const std::array track_inlier_ratios = {0.2, 0.0}; - for (auto track_inlier_ratio = track_inlier_ratios.cbegin(); + for (auto track_inlier_ratio = track_inlier_ratios.cbegin(); track_inlier_ratio < track_inlier_ratios.cend(); ++track_inlier_ratio) { IndexT pose_before = sfm_data_.GetPoses().size(); @@ -177,7 +177,7 @@ bool SequentialSfMReconstructionEngine2::Process() { if (pose_before >= pose_after) break; pose_before = sfm_data_.GetPoses().size(); - // Since we have augmented our set of poses we can reset our track inlier ratio iterator + // Since we have augmented our set of poses we can reset our track inlier ratio iterator track_inlier_ratio = track_inlier_ratios.cbegin(); } } @@ -395,7 +395,7 @@ bool SequentialSfMReconstructionEngine2::AddingMissingView geometry::Pose3 pose; const bool bResection = sfm::SfM_Localizer::Localize ( - intrinsic ? resection::SolverType::P3P_KE_CVPR17 : resection::SolverType::DLT_6POINTS, + intrinsic ? resection::SolverType::P3P_NORDBERG_ECCV18 : resection::SolverType::DLT_6POINTS, {view->ui_width, view->ui_height}, intrinsic ? intrinsic.get() : nullptr, resection_data, diff --git a/src/software/Localization/main_SfM_Localization.cpp b/src/software/Localization/main_SfM_Localization.cpp index 128d8fa7ee..debf700162 100644 --- a/src/software/Localization/main_SfM_Localization.cpp +++ b/src/software/Localization/main_SfM_Localization.cpp @@ -382,7 +382,7 @@ int main(int argc, char **argv) // Try to localize the image in the database thanks to its regions if (!localizer.Localize( - optional_intrinsic ? resection::SolverType::P3P_KE_CVPR17 : resection::SolverType::DLT_6POINTS, + optional_intrinsic ? resection::SolverType::P3P_NORDBERG_ECCV18 : resection::SolverType::DLT_6POINTS, {imageGray.Width(), imageGray.Height()}, optional_intrinsic.get(), *(query_regions.get()),