8000 Do triangulation in the IncrementalMapperController by sarlinpe · Pull Request #2429 · colmap/colmap · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Do triangulation in the IncrementalMapperController #2429

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions src/colmap/controllers/incremental_mapper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -535,4 +537,39 @@ void IncrementalMapperController::Reconstruct(
}
}

void IncrementalMapperController::TriangulateReconstruction(
const std::shared_ptr<Reconstruction>& reconstruction) {
THROW_CHECK(LoadDatabase());
IncrementalMapper mapper(database_cache_);
mapper.BeginReconstruction(reconstruction);

LOG(INFO) << "Iterative triangulation";
const std::vector<image_t>& 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
3 changes: 3 additions & 0 deletions src/colmap/controllers/incremental_mapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,9 @@ class IncrementalMapperController : public BaseController {

void Run();

void TriangulateReconstruction(
const std::shared_ptr<Reconstruction>& reconstruction);

private:
bool LoadDatabase();
void Reconstruct(const IncrementalMapper::Options& init_mapper_options);
Expand Down
131 changes: 22 additions & 109 deletions src/colmap/exe/sfm.cc
Original file line number Diff line number Diff line change
Expand Up @@ -415,130 +415,43 @@ int RunPointTriangulator(int argc, char** argv) {
auto reconstruction = std::make_shared<Reconstruction>();
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>& reconstruction,
const std::string& database_path,
const std::string& image_path,
const std::string& output_path,
const IncrementalMapperOptions& options,
const bool clear_points,
const bool refine_intrinsics) {
PrintHeading1("Loading database");

std::shared_ptr<DatabaseCache> database_cache;

{
Timer timer;
timer.Start();
const Database database(database_path);
const size_t min_num_matches = static_cast<size_t>(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<image_t>& 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<double>(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<IncrementalMapperOptions>(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<ReconstructionManager>();
IncrementalMapperController mapper(
options_tmp, image_path, database_path, reconstruction_manager);
mapper.TriangulateReconstruction(reconstruction);
reconstruction->Write(output_path);

return EXIT_SUCCESS;
}

namespace {
Expand Down
2 changes: 1 addition & 1 deletion src/colmap/exe/sfm.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@

namespace colmap {

int RunPointTriangulatorImpl(
void RunPointTriangulatorImpl(
const std::shared_ptr<Reconstruction>& reconstruction,
const std::string& database_path,
const std::string& image_path,
Expand Down
19 changes: 8 additions & 11 deletions src/colmap/sfm/incremental_mapper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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 =
Expand All @@ -798,7 +796,6 @@ void IncrementalMapper::IterativeGlobalRefinement(
break;
}
}
FilterImages(options);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We now lost the ability to remove degenerate images here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved it to the parent scope so it doesn't get called when triangulating only

mapper.FilterImages(mapper_options);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, thx

}

size_t IncrementalMapper::FilterImages(const Options& options) {
Expand Down
3 changes: 2 additions & 1 deletion src/colmap/sfm/incremental_mapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
0