The Problem
Multi-view 3D reconstruction pipelines assume every input image is a valid view of the scene. In practice, users feed in blurry frames, extreme close-ups, or images of a different scene entirely. These outlier views corrupt the reconstruction. RobustVGGT detects and rejects those outlier views automatically, without fine-tuning, by exploiting an emergent property of Visual Geometry Grounded Transformers (VGGT).
What This Does
RobustVGGT is a research prototype demonstrating that VGGT's attention mechanism produces measurable "confidence" signals that separate valid views from outliers. The core logic lives in robust_vggt.py (the CLI entry point) and vggt/dependency/, which handles distortion, projection, and tracking. The vggt/models/aggregator.py file manages frame attention across views.
The repo provides demo inference only. Evaluation and visualization code are marked as not-yet-implemented in the README. The model weights are not bundled; the code loads a pretrained VGGT checkpoint at runtime.
How It Is Wired
Execution starts at main in robust_vggt.py:589, which reaches 18 functions. The shortest path to external side effects is main -> run_demo, which creates an output directory (self.pair_out_dir.mkdir). The pipeline loads images from --image-dir, runs them through the VGGT backbone, and applies a rejection threshold (--rej-thresh, default 0.5) to filter outlier views.
The most-connected modules are vggt/layers/__init__ (imported by 3 modules, imports 5) and vggt/layers/block (3/4). vggt/models/aggregator and vggt/models/vggt each have high instability (0.8) — they depend on many modules but few depend on them, so changes there ripple outward. apply_distortion is called from 4 places and is the most reused geometry function; prepare_tokens_with_masks and DinoVisionTransformer are also called from 4 places each.
There are no circular dependencies (0 modules in cycles), which keeps the import graph clean. The call graph shows 157 internal edges; changing apply_distortion or safe_empty_cache (called from 7 places in _forward_once) breaks the most downstream code.
The wiring for evaluation, visualization, and model weight downloading is not mapped — the repo does not include those code paths yet.
How To Use It
Setup (from README, verified against requirements.txt):
conda create -n robust_vggt python=3.10
conda activate robust_vggt
pip install torch==2.5.1 torchvision==0.20.1 torchaudio==2.5.1 --index-url https://download.pytorch.org/whl/cu121
pip install -r requirements.txt
Running:
python robust_vggt.py --image-dir examples/trevi
python robust_vggt.py --image-dir examples/notredame --rej-thresh 0.3
Configuration is via CLI flags only; there is no config file. The examples/ directory contains two test image sets (trevi, notredame) with 12–14 images each.
Real-World Use
A photogrammetry pipeline ingests 50 tourist photos of a monument. Three are close-ups of a sign, two are motion-blurred. RobustVGGT runs as a pre-filter:
# Conceptually: reject outliers before feeding the reconstruction backend
image_dir = "user_photos/"
accepted_views = run_robust_vggt(image_dir, rejection_threshold=0.4)
reconstruction_backend(accepted_views)
This replaces manual curation or brittle SIFT-based outlier filtering. The trade-off: rejection is binary, not weighted, so borderline views are either fully kept or fully dropped.
Code Health & Issues
Static analysis (not opinion) found 13 issues across 6 kinds:
- High - Deep nesting (x7) —
vggt/heads/track_head.py,vggt/layers/attention.py,robust_vggt.py; max indentation depth 12, control flow is hard to follow. - High - Duplicated code (x21 files) — 341 repeated 6-line blocks across
vggt/dependency/andvggt/heads/; DRY extraction needed. - Medium - File handle without context manager —
vggt/utils/load_fn.py;open()not wrapped inwith. - Medium - Broad exception handling (x2) —
robust_vggt.py,vggt/dependency/np_to_pycolmap.py; bareexceptswallows errors. - Medium - High branching density —
vggt/utils/load_fn.py; 43 branch points over 150 lines. - Low - TODO/FIXME markers (x3) —
vggt/dependency/track_predict.py.
SDLC gaps: no tests, no CI, no LICENSE, no lockfile. The missing LICENSE is the most urgent — with no license, all rights are reserved, which blocks legal reuse in client work.
The Bottom Line
Solid research prototype with a clean import graph and a clear, simple entry point. The lack of tests, CI, and a license makes it unsuitable for production without hardening. Use it if you need outlier-view rejection in a VGGT-based pipeline and can tolerate a research-grade codebase.