Skip to content

Partition on a globally verified view graph - #1135

Draft
kathirgounder wants to merge 1 commit into
borglab:masterfrom
kathirgounder:verified-view-graph
Draft

kathirgounder wants to merge 1 commit into
borglab:masterfrom
kathirgounder:verified-view-graph

Conversation

@kathirgounder

@kathirgounder kathirgounder commented Sep 1, 2026 •

Copy link
Copy Markdown
Collaborator

Stacked on #1134 (the inline-frontend PR — its commit appears here until it merges; review the last commit only).

What

The hierarchical pipeline currently partitions the retrieval graph: METIS carves clusters along MegaLoc-similarity edges, many of which have no verifiable two-view geometry. This PR runs the frontend (correspondence generation + two-view estimation) once over the full retrieval graph, up front, and hands everything downstream — partitioning, per-cluster reconstruction, merging — the verified subgraph (edges where TwoViewResult.valid()).

  1. scene_optimizer.verify_visibility_graph (module function, tested): runs the frontend over all retrieval edges and returns padded per-image keypoints + verified correspondence indices per surviving edge. Dispatches on pool size — multiple workers fan out via create_v_corr_idxs_futures (only lean per-chunk sub-dicts are gathered); a single worker runs inline in the main process (no scheduler↔worker comm surface for a multi-hour run to trip over). Every run_2view call warms the two-view cache, so per-cluster frontends afterwards are cache hits.
  2. Always on when verifiable — no flag. Any cluster optimizer exposing correspondence_generator + two_view_estimator (ClusterMVO, ClusterVGGTWithFrontend, incl. Cacher-wrapped) gets the verified graph. Frontend-less optimizers (ClusterVGGT, AnySplat, FastVGGT — pure feedforward) have no two-view stage to verify with and keep the retrieval graph; that's capability detection, not an A/B switch.
  3. Global correspondences reused per cluster. ClusterContext gains global_v_corr_idxs_dict / global_keypoints; ClusterVGGTWithFrontend builds each cluster's 2D tracks by subsetting them to the cluster's edges (eagerly, main process) instead of re-running the per-cluster frontend, which would recompute the identical per-edge result serially across overlapping clusters. Data-driven: no globals in the context (optimizer used standalone) → the traditional per-cluster frontend runs, unchanged.
  4. runner.py: Dask comm timeouts 30s → 300s (connect + tcp). Separate bug fix that this PR makes load-bearing: bulk image loads and the in-process frontend stall the client event loop past the 30s defaults, closing comms mid-run (CommClosedError / "lost dependencies") on large single-node scenes.
  5. Golden phototourism config (vggt_sift_frontend_megaloc_phototourism.yaml): retrieval now over-generates (num_matched 15→100, min_score 0.5→0.15) because verification supplies the precision; METIS sizes up (30/70); ColmapSIFT@8192 + PoseLib LO-RANSAC@2px + inlier support 30/0.15 — the peak verifier stack the paper numbers used. Calibration/BA-prior keys are deliberately untouched (next PRs).

Tests

Review focus

  • scene_optimizer.py: the capability check (getattr for correspondence_generator/two_view_estimator — the Cacher forwards public attrs) and the to_context plumbing.
  • cluster_vggt_with_frontend.py: the reuse branch skips _build_frontend_output_graphs (two-view viz/metrics) — per-edge results are identical to the per-cluster frontend, so nothing else changes downstream.
  • Behavior change sign-off: classic Multiview configs now also partition on their verified graph (same frontend, run once globally; per-cluster passes cache-hit).

Context

Series landing the ECCV'26 SFM-DL hierarchical-SfM pipeline (research branch vggt-verified-pipeline, tag eccv2026-sfmdl-research) into mapping-vggt. Previous: #1134. Next: calibration arbitration (EXIF passthrough with model-focal fallback).

🤖 Generated with Claude Code

Run the frontend (correspondence generation + two-view estimation) once over
the full retrieval graph, up front, and hand everything downstream --
partitioning, per-cluster reconstruction, merging -- the VERIFIED subgraph
(edges where TwoViewResult.valid()). METIS no longer carves clusters along
retrieval-similarity edges that have no verifiable geometry.

- scene_optimizer.verify_visibility_graph: the verification pass. Dispatches
  on pool size: multiple workers fan out via create_v_corr_idxs_futures (only
  lean per-chunk sub-dicts gathered); one worker runs inline in the main
  process (no scheduler<->worker comm surface over a multi-hour run). Always
  on for optimizers exposing a two-view frontend; pure-feedforward optimizers
  (ClusterVGGT / AnySplat) have nothing to verify with and keep the retrieval
  graph. On IMC Brussels (234 imgs) the verified arm measured AUC@3 0.697 vs
  0.675 with +11 cameras over the retrieval-graph baseline.
- ClusterContext.global_v_corr_idxs_dict / global_keypoints: the global
  frontend products, reused per cluster. ClusterVGGTWithFrontend subsets them
  to the cluster's edges and builds its 2D tracks eagerly instead of
  re-running the per-cluster frontend (identical per-edge result, recomputed
  serially across overlapping clusters otherwise). Data-driven: without them
  the traditional per-cluster frontend runs unchanged.
- runner.py: Dask comm timeouts 30s -> 300s (connect/tcp). Bulk image loads
  and the in-process frontend stall the client event loop past the defaults,
  closing comms mid-run (CommClosedError / "lost dependencies").
- Golden phototourism config: retrieval over-generates (num_matched 100,
  min_score 0.15) since verification supplies the precision; METIS 30/70;
  ColmapSIFT@8192 + PoseLib LO-RANSAC@2px + inlier support 30/0.15.

Tests: inline and fan-out arms produce identical keypoints + verified graph;
only estimator-validated edges survive.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants