From a679d9298d1c555a0ccf8b4b2092ea49f611addd Mon Sep 17 00:00:00 2001 From: Paul-Edouard Sarlin Date: Mon, 19 Feb 2024 10:26:15 +0100 Subject: [PATCH] Perfrom triangulation in the IncrementalMapperController --- src/colmap/controllers/incremental_mapper.cc | 37 ++++++ src/colmap/controllers/incremental_mapper.h | 3 + src/colmap/exe/sfm.cc | 131 ++++--------------- src/colmap/exe/sfm.h | 2 +- src/colmap/sfm/incremental_mapper.cc | 19 ++- src/colmap/sfm/incremental_mapper.h | 3 +- 6 files changed, 73 insertions(+), 122 deletions(-) diff --git a/src/colmap/controllers/incremental_mapper.cc b/src/colmap/controllers/incremental_mapper.cc index 15bae3246d..1588baa69f 100644 --- a/src/colmap/controllers/incremental_mapper.cc +++ b/src/colmap/controllers/incremental_mapper.cc @@ -44,6 +44,7 @@ void IterativeGlobalRefinement(const IncrementalMapperOptions& options, mapper_options, options.GlobalBundleAdjustment(), options.Triangulation()); + mapper.FilterImages(mapper_options); } void ExtractColors(const std::string& image_path, @@ -292,6 +293,7 @@ IncrementalMapperController::InitializeReconstruction( LOG(INFO) << "Global bundle adjustment"; mapper.AdjustGlobalBundle(mapper_options, options_->GlobalBundleAdjustment()); + reconstruction.Normalize(); mapper.FilterPoints(mapper_options); mapper.FilterImages(mapper_options); @@ -535,4 +537,39 @@ void IncrementalMapperController::Reconstruct( } } +void IncrementalMapperController::TriangulateReconstruction( + const std::shared_ptr& reconstruction) { + THROW_CHECK(LoadDatabase()); + IncrementalMapper mapper(database_cache_); + mapper.BeginReconstruction(reconstruction); + + LOG(INFO) << "Iterative triangulation"; + const std::vector& reg_image_ids = reconstruction->RegImageIds(); + for (size_t i = 0; i < reg_image_ids.size(); ++i) { + const image_t image_id = reg_image_ids[i]; + const auto& image = reconstruction->Image(image_id); + + LOG(INFO) << StringPrintf("Triangulating image #%d (%d)", image_id, i); + const size_t num_existing_points3D = image.NumPoints3D(); + LOG(INFO) << "=> Image sees " << num_existing_points3D << " / " + << image.NumObservations() << " points"; + + mapper.TriangulateImage(options_->Triangulation(), image_id); + VLOG(1) << "=> Triangulated " + << (image.NumPoints3D() - num_existing_points3D) << " points"; + } + + LOG(INFO) << "Retriangulation and Global bundle adjustment"; + mapper.IterativeGlobalRefinement(options_->ba_global_max_refinements, + options_->ba_global_max_refinement_change, + options_->Mapper(), + options_->GlobalBundleAdjustment(), + options_->Triangulation(), + /*normalize_reconstruction=*/false); + mapper.EndReconstruction(/*discard=*/false); + + LOG(INFO) << "Extracting colors"; + reconstruction->ExtractColorsForAllImages(image_path_); +} + } // namespace colmap diff --git a/src/colmap/controllers/incremental_mapper.h b/src/colmap/controllers/incremental_mapper.h index 24b0b5313c..0206d30bc3 100644 --- a/src/colmap/controllers/incremental_mapper.h +++ b/src/colmap/controllers/incremental_mapper.h @@ -162,6 +162,9 @@ class IncrementalMapperController : public BaseController { void Run(); + void TriangulateReconstruction( + const std::shared_ptr& reconstruction); + private: bool LoadDatabase(); void Reconstruct(const IncrementalMapper::Options& init_mapper_options); diff --git a/src/colmap/exe/sfm.cc b/src/colmap/exe/sfm.cc index cbd399a729..dbae480ff5 100644 --- a/src/colmap/exe/sfm.cc +++ b/src/colmap/exe/sfm.cc @@ -405,16 +405,17 @@ int RunPointTriangulator(int argc, char** argv) { auto reconstruction = std::make_shared(); reconstruction->Read(input_path); - return RunPointTriangulatorImpl(reconstruction, - *options.database_path, - *options.image_path, - output_path, - *options.mapper, - clear_points, - refine_intrinsics); + RunPointTriangulatorImpl(reconstruction, + *options.database_path, + *options.image_path, + output_path, + *options.mapper, + clear_points, + refine_intrinsics); + return EXIT_SUCCESS; } -int RunPointTriangulatorImpl( +void RunPointTriangulatorImpl( const std::shared_ptr& reconstruction, const std::string& database_path, const std::string& image_path, @@ -422,113 +423,25 @@ int RunPointTriangulatorImpl( const IncrementalMapperOptions& options, const bool clear_points, const bool refine_intrinsics) { - PrintHeading1("Loading database"); - - std::shared_ptr database_cache; - - { - Timer timer; - timer.Start(); - const Database database(database_path); - const size_t min_num_matches = static_cast(options.min_num_matches); - database_cache = DatabaseCache::Create(database, - min_num_matches, - options.ignore_watermarks, - options.image_names); - - if (clear_points) { - reconstruction->DeleteAllPoints2DAndPoints3D(); - reconstruction->TranscribeImageIdsToDatabase(database); - } - - timer.PrintMinutes(); - } - THROW_CHECK_GE(reconstruction->NumRegImages(), 2) << "Need at least two images for triangulation"; - - IncrementalMapper mapper(database_cache); - mapper.BeginReconstruction(reconstruction); - - ////////////////////////////////////////////////////////////////////////////// - // Triangulation - ////////////////////////////////////////////////////////////////////////////// - - const auto tri_options = options.Triangulation(); - const auto mapper_options = options.Mapper(); - - const std::vector& reg_image_ids = reconstruction->RegImageIds(); - - for (size_t i = 0; i < reg_image_ids.size(); ++i) { - const image_t image_id = reg_image_ids[i]; - const auto& image = reconstruction->Image(image_id); - - PrintHeading1(StringPrintf("Triangulating image #%d (%d)", image_id, i)); - - const size_t num_existing_points3D = image.NumPoints3D(); - - LOG(INFO) << "=> Image sees " << num_existing_points3D << " / " - << image.NumObservations() << " points"; - - mapper.TriangulateImage(tri_options, image_id); - - LOG(INFO) << "=> Triangulated " - << (image.NumPoints3D() - num_existing_points3D) << " points"; - } - - ////////////////////////////////////////////////////////////////////////////// - // Retriangulation - ////////////////////////////////////////////////////////////////////////////// - - PrintHeading1("Retriangulation"); - - mapper.CompleteAndMergeTracks(tri_options); - - ////////////////////////////////////////////////////////////////////////////// - // Bundle adjustment - ////////////////////////////////////////////////////////////////////////////// - - auto ba_options = options.GlobalBundleAdjustment(); - ba_options.refine_focal_length = refine_intrinsics; - ba_options.refine_principal_point = false; - ba_options.refine_extra_params = refine_intrinsics; - ba_options.refine_extrinsics = false; - - // Configure bundle adjustment. - BundleAdjustmentConfig ba_config; - for (const image_t image_id : reg_image_ids) { - ba_config.AddImage(image_id); - } - - for (int i = 0; i < options.ba_global_max_refinements; ++i) { - // Avoid degeneracies in bundle adjustment. - reconstruction->FilterObservationsWithNegativeDepth(); - - const size_t num_observations = reconstruction->ComputeNumObservations(); - - PrintHeading1("Bundle adjustment"); - BundleAdjuster bundle_adjuster(ba_options, ba_config); - THROW_CHECK(bundle_adjuster.Solve(reconstruction.get())); - - size_t num_changed_observations = 0; - num_changed_observations += mapper.CompleteAndMergeTracks(tri_options); - num_changed_observations += mapper.FilterPoints(mapper_options); - const double changed = - static_cast(num_changed_observations) / num_observations; - LOG(INFO) << StringPrintf("=> Changed observations: %.6f", changed); - if (changed < options.ba_global_max_refinement_change) { - break; - } + if (clear_points) { + const Database database(database_path); + reconstruction->DeleteAllPoints2DAndPoints3D(); + reconstruction->TranscribeImageIdsToDatabase(database); } - PrintHeading1("Extracting colors"); - reconstruction->ExtractColorsForAllImages(image_path); - - mapper.EndReconstruction(/*discard=*/false); + auto options_tmp = std::make_shared(options); + options_tmp->fix_existing_images = true; + options_tmp->ba_refine_focal_length = refine_intrinsics; + options_tmp->ba_refine_principal_point = false; + options_tmp->ba_refine_extra_params = refine_intrinsics; + auto reconstruction_manager = std::make_shared(); + IncrementalMapperController mapper( + options_tmp, image_path, database_path, reconstruction_manager); + mapper.TriangulateReconstruction(reconstruction); reconstruction->Write(output_path); - - return EXIT_SUCCESS; } namespace { diff --git a/src/colmap/exe/sfm.h b/src/colmap/exe/sfm.h index bc95ed2628..fd8314fb70 100644 --- a/src/colmap/exe/sfm.h +++ b/src/colmap/exe/sfm.h @@ -34,7 +34,7 @@ namespace colmap { -int RunPointTriangulatorImpl( +void RunPointTriangulatorImpl( const std::shared_ptr& reconstruction, const std::string& database_path, const std::string& image_path, diff --git a/src/colmap/sfm/incremental_mapper.cc b/src/colmap/sfm/incremental_mapper.cc index 00b31d13f6..e48899874b 100644 --- a/src/colmap/sfm/incremental_mapper.cc +++ b/src/colmap/sfm/incremental_mapper.cc @@ -732,15 +732,7 @@ bool IncrementalMapper::AdjustGlobalBundle( // Run bundle adjustment. BundleAdjuster bundle_adjuster(ba_options_tmp, ba_config); - if (!bundle_adjuster.Solve(reconstruction_.get())) { - return false; - } - - // Normalize scene for numerical stability and - // to avoid large scale changes in viewer. - reconstruction_->Normalize(); - - return true; + return bundle_adjuster.Solve(reconstruction_.get()); } void IncrementalMapper::IterativeLocalRefinement( @@ -781,12 +773,18 @@ void IncrementalMapper::IterativeGlobalRefinement( const double max_refinement_change, const Options& options, const BundleAdjustmentOptions& ba_options, - const IncrementalTriangulator::Options& tri_options) { + const IncrementalTriangulator::Options& tri_options, + const bool normalize_reconstruction) { CompleteAndMergeTracks(tri_options); VLOG(1) << "=> Retriangulated observations: " << Retriangulate(tri_options); for (int i = 0; i < max_num_refinements; ++i) { const size_t num_observations = reconstruction_->ComputeNumObservations(); AdjustGlobalBundle(options, ba_options); + if (normalize_reconstruction) { + // Normalize scene for numerical stability and + // to avoid large scale changes in the viewer. + reconstruction_->Normalize(); + } size_t num_changed_observations = CompleteAndMergeTracks(tri_options); num_changed_observations += FilterPoints(options); const double changed = @@ -798,7 +796,6 @@ void IncrementalMapper::IterativeGlobalRefinement( break; } } - FilterImages(options); } size_t IncrementalMapper::FilterImages(const Options& options) { diff --git a/src/colmap/sfm/incremental_mapper.h b/src/colmap/sfm/incremental_mapper.h index d2ef030b37..b61343e21e 100644 --- a/src/colmap/sfm/incremental_mapper.h +++ b/src/colmap/sfm/incremental_mapper.h @@ -235,7 +235,8 @@ class IncrementalMapper { double max_refinement_change, const Options& options, const BundleAdjustmentOptions& ba_options, - const IncrementalTriangulator::Options& tri_options); + const IncrementalTriangulator::Options& tri_options, + bool normalize_reconstruction = true); // Filter images and point observations. size_t FilterImages(const Options& options);