MCPcopy Create free account
hub / github.com/colmap/colmap / MergeReconstructions

Function MergeReconstructions

src/colmap/estimators/alignment.cc:474–549  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

472} // namespace
473
474bool MergeReconstructions(const double max_reproj_error,
475 const Reconstruction& src_reconstruction,
476 Reconstruction& tgt_reconstruction) {
477 Sim3d tgt_from_src;
478 if (!AlignReconstructionsViaReprojections(src_reconstruction,
479 tgt_reconstruction,
480 /*min_inlier_observations=*/0.3,
481 max_reproj_error,
482 &tgt_from_src)) {
483 return false;
484 }
485
486 // Find common and missing images in the two reconstructions.
487 std::unordered_set<image_t> common_image_ids;
488 common_image_ids.reserve(src_reconstruction.NumRegImages());
489 std::unordered_set<image_t> missing_image_ids;
490 missing_image_ids.reserve(src_reconstruction.NumRegImages());
491 for (const image_t image_id : src_reconstruction.RegImageIds()) {
492 if (tgt_reconstruction.ExistsImage(image_id)) {
493 common_image_ids.insert(image_id);
494 } else {
495 missing_image_ids.insert(image_id);
496 }
497 }
498
499 // Register the missing images in this src_reconstruction.
500 for (const auto image_id : missing_image_ids) {
501 CopyRegisteredImage(
502 image_id, tgt_from_src, src_reconstruction, tgt_reconstruction);
503 }
504
505 // Merge the two point clouds using the following two rules:
506 // - copy points to this src_reconstruction with non-conflicting tracks,
507 // i.e. points that do not have an already triangulated observation
508 // in this src_reconstruction.
509 // - merge tracks that are unambiguous, i.e. only merge points in the two
510 // reconstructions if they have a one-to-one mapping.
511 // Note that in both cases no cheirality or reprojection test is performed.
512
513 for (const auto& [_, point3D] : src_reconstruction.Points3D()) {
514 Track new_track;
515 Track old_track;
516 std::unordered_set<point3D_t> old_point3D_ids;
517 for (const auto& track_el : point3D.track.Elements()) {
518 if (common_image_ids.count(track_el.image_id) > 0) {
519 const auto& point2D = tgt_reconstruction.Image(track_el.image_id)
520 .Point2D(track_el.point2D_idx);
521 if (point2D.HasPoint3D()) {
522 old_track.AddElement(track_el);
523 old_point3D_ids.insert(point2D.point3D_id);
524 } else {
525 new_track.AddElement(track_el);
526 }
527 } else if (missing_image_ids.count(track_el.image_id) > 0) {
528 tgt_reconstruction.Image(track_el.image_id)
529 .ResetPoint3DForPoint2D(track_el.point2D_idx);
530 new_track.AddElement(track_el);
531 }

Callers 2

TESTFunction · 0.85

Calls 14

CopyRegisteredImageFunction · 0.85
NumRegImagesMethod · 0.80
RegImageIdsMethod · 0.80
AddElementMethod · 0.80
LengthMethod · 0.80
sizeMethod · 0.80
ExistsImageMethod · 0.45
ImageMethod · 0.45
HasPoint3DMethod · 0.45
AddPoint3DMethod · 0.45

Tested by 1

TESTFunction · 0.68