{"id":50778295,"url":"https://github.com/colmap/gluemap","last_synced_at":"2026-06-12T01:30:24.273Z","repository":{"id":360384432,"uuid":"1189324420","full_name":"colmap/gluemap","owner":"colmap","description":"GLUEMAP: Global Structure-from-Motion Meets Feedforward Reconstruction","archived":false,"fork":false,"pushed_at":"2026-05-26T08:09:10.000Z","size":4428,"stargazers_count":8,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-26T08:26:40.279Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://lpanaf.github.io/cvpr26_gluemap/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/colmap.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-23T07:51:22.000Z","updated_at":"2026-05-26T08:12:20.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/colmap/gluemap","commit_stats":null,"previous_names":["colmap/gluemap"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/colmap/gluemap","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/colmap%2Fgluemap","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/colmap%2Fgluemap/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/colmap%2Fgluemap/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/colmap%2Fgluemap/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/colmap","download_url":"https://codeload.github.com/colmap/gluemap/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/colmap%2Fgluemap/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34225350,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-11T02:00:06.485Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-12T01:30:20.899Z","updated_at":"2026-06-12T01:30:24.211Z","avatar_url":"https://github.com/colmap.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# GLUEMAP: Global Structure-from-Motion Meets Feedforward Reconstruction\n[Project page](https://lpanaf.github.io/cvpr26_gluemap/) | [Paper](https://arxiv.org/abs/2605.26103)\n---\n\n## About\n\nGLUEMAP is the first Structure-from-Motion pipeline to integrate\nfeed-forward reconstruction backbones into a global SfM framework.\nIt takes a collection of images as input and outputs a COLMAP sparse reconstruction. \nIt matches the scalability and accuracy of traditional SfM pipelines while inheriting the local robustness of a feed-forward backbone.\nIt pairs their resilience on hard local geometry (low overlap, repetitive structures, weak texture) with the accuracy, global consistency, and large-scene tractability that classical SfM provides.\n\nThe pipeline comprises:\n\n1. **Retrieval** — SALAD global descriptors build the image neighbor graph.\n2. **Two-view inference (optional)** — Doppelgangers++ (MAST3R-based) estimates covisibility of pairs. Can be skipped via `skip_doppelgangers` when the scene has no repetitive structure or when a quick result is preferred (see [Configuration](#configuration)).\n3. **Multi-view inference** — a configurable backbone (Pi3 / Pi3X / VGGT / MapAnything) estimates poses and geometry in local star configurations.\n4. **Global mapping** — rotation averaging, intrinsics averaging,\n   similarity averaging, and global bundle adjustment fuse the local solutions.\n5. **Refinement** — SIFT track snapping with iterative augmented bundle adjustment.\n\nThe orchestrator is [gluemap/controllers/gluemap_impl.py](gluemap/controllers/gluemap_impl.py).\n\nIf you use this project for your research, please cite\n\n```\n@inproceedings{pan2026gluemap,\n    author={Pan, Linfei and Sch\\\"{o}nberger, Johannes Lutz and Pollefeys, Marc},\n    title={Global Structure-from-Motion Meets Feedforward Reconstruction},\n    booktitle={Conference on Computer Vision and Pattern Recognition (CVPR)},\n    year={2026},\n}\n```\n\n\n## Getting Started\n\nGLUEMAP is a Python package with a C++/pybind11 extension (`pygluemap`)\nthat links against Ceres, Eigen, Boost, and OpenMP, plus several\nfeed-forward models vendored as git submodules.\n\n```bash\ngit clone https://github.com/colmap/gluemap.git\ncd gluemap\ngit submodule update --init --recursive\n\n# In a Python ≥ 3.10 environment with Ceres / Eigen / METIS / Boost / OpenMP available:\nCMAKE_PREFIX_PATH=$CONDA_PREFIX pip install -e .\n```\n\nFor the reproducible conda/micromamba recipe (pinned versions, CUDA\nnotes, libstdc++ ABI troubleshooting), see [INSTALL.md](INSTALL.md).\n\nThe default config expects four model checkpoints under `checkpoints/`\n(Pi3, SALAD, VGGSfM tracker, Doppelgangers++). Download commands are in\n[INSTALL.md §4](INSTALL.md#4-download-model-checkpoints).\n\nVerify the install:\n\n```bash\npython -c \"import gluemap; import pygluemap; print(pygluemap.__file__)\"\ngluemap-demo --help\n```\n\n## Usage\n\n### Single image collection\n\n```bash\ngluemap-demo \\\n    --config configs/example.yaml \\\n    --images_path /path/to/images \\\n    --intrinsics_mode SHARED \\\n    --write_path results/\n```\n\nThe reconstruction is written under `--write_path` in COLMAP format.\n\n### Multi-sequence\n\nWhen `--images_path` holds several video sequences of the same scene as\nsibling subfolders (e.g. LAMAR's `ios*` sequences), enable multi-sequence\nmode and supply a regex that selects the subfolders to process:\n\n```bash\ngluemap-demo \\\n    --config configs/example.yaml \\\n    --images_path /path/to/scene \\\n    --subfolder_regex '^ios' \\\n    --is_multi_sequence \\\n    --intrinsics_mode PER_CAMERA \\\n    --write_path results/\n```\n\nThis auto-enables sequential pairing within each subfolder.\n\n### Multi-GPU\n\nTwo-view and star-inference stages parallelize across ranks via\n`init_distributed()` in [gluemap/utils/gpu.py](gluemap/utils/gpu.py).\nGlobal mapping and refinement run on rank 0 only. Launch with\n`torchrun --nproc_per_node=N gluemap-demo ...` (or set `RANK` /\n`WORLD_SIZE` manually).\n\n### Benchmarks\n\n`gluemap-benchmark` runs a config-driven sweep over multiple datasets\n(see [configs/lamar.yaml](configs/lamar.yaml) for the LAMAR layout).\n\n## Configuration\n\nConfigs live in [configs/](configs/) and inherit shared defaults from\n[configs/base.yaml](configs/base.yaml) via `_base_:`. CLI flags override\nconfig values, so anything in `base.yaml` can be tweaked without editing\nthe file.\n\nThe most-touched knobs:\n\n| Key | Description |\n|---|---|\n| `images_path` / `write_path` | Input directory / output directory. |\n| `chosen_model` | Multi-view backbone: `pi3` (default), `pi3x`, `vggt`, `map_anything`. |\n| `path_feedforward` | Checkpoint for the chosen multi-view model. |\n| `path_retrieval` / `path_tracker` / `path_dg` | SALAD / VGGSfM / Doppelgangers++ checkpoints. |\n| `camera_model` | COLMAP camera model (default `SIMPLE_PINHOLE`). |\n| `intrinsics_mode` | Intrinsics-bucketing strategy: `SHARED` (one camera per unique image shape, default), `PER_FOLDER` (one camera per `(dirname, shape)` pair), or `PER_CAMERA` (one camera per image). |\n| `num_neighbors` | Neighbors per image in the retrieval graph (default `100`). |\n| `is_sequential` / `sample_frequency` | Use temporal pairing for ordered video; subsample every Nth frame. |\n| `is_multi_sequence` / `subfolder_regex` | Process several sibling sequences into a single reconstruction. |\n| `rerun_from` | Resume from `retrieval`, `twoview`, or `star` to skip earlier stages. |\n| `coarse_only` | Stop after global mapping; skip the refinement stage. |\n| `skip_doppelgangers` | Skip the Doppelgangers++ two-view disambiguator and treat all retrieval pairs as valid. Useful when the scene has no repetitive structure or for a quick first result. Default `false`. |\n\nSee [configs/base.yaml](configs/base.yaml) for the complete surface and\ndefault values.\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eChoosing a backbone\u003c/b\u003e\u003c/summary\u003e\n\n`chosen_model` selects the multi-view star-inference model. Each\nbackbone needs its own `path_feedforward` checkpoint:\n\n- **`pi3`** — Pi3, default; `checkpoints/pi3.safetensors`.\n- **`pi3x`** — Pi3X variant; same Pi3 checkpoint family.\n- **`vggt`** — Facebook VGGT-1B; download `model.pt` from\n  HuggingFace `facebook/VGGT-1B`.\n- **`map_anything`** — Facebook MapAnything; set\n  `path_feedforward: facebook/map-anything` (HF repo id, not a file path).\n\nDispatch lives in [gluemap/utils/model_loader.py](gluemap/utils/model_loader.py).\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eAdding a custom backbone\u003c/b\u003e\u003c/summary\u003e\n\nTo plug in a different multi-view model, add a wrapper under\n[gluemap/ff_inference/](gluemap/ff_inference/) that inherits the\n`LocalInference` abstract base class from\n[gluemap/ff_inference/local_inference.py](gluemap/ff_inference/local_inference.py)\nand implements `predict(batch: dict) -\u003e dict`.\n\nThe contract:\n\n- **Input** `batch[\"images\"]` of shape `(B, N, 3, H, W)`. Subclasses may\n  read additional keys.\n- **Output** dict with at minimum `depth`, `depth_conf`, `extrinsics`,\n  `intrinsics`.\n\nUse the existing wrappers as references:\n\n- [gluemap/ff_inference/pi3_inference.py](gluemap/ff_inference/pi3_inference.py)\n- [gluemap/ff_inference/vggt_inference.py](gluemap/ff_inference/vggt_inference.py)\n- [gluemap/ff_inference/mapanything_inference.py](gluemap/ff_inference/mapanything_inference.py)\n\nThen register the new wrapper in `create_local_inference()` in\n[local_inference.py](gluemap/ff_inference/local_inference.py) so it\ndispatches on the `chosen_model` string set in your config.\n\n\u003e **Note:** the input image size and patch size are fixed in\n\u003e [gluemap/datasets/star.py](gluemap/datasets/star.py) (`image_size=518`,\n\u003e `patch_size=14`), matching the Pi3/DINOv2-style encoders used by the\n\u003e default backbones. If your custom backbone uses a different encoder\n\u003e (e.g. DINOv3, which uses a patch size of 16), update `self.patch_size`\n\u003e (and `self.image_size` if needed) accordingly so the preprocessed\n\u003e images align with the encoder's patch grid.\n\n\u003c/details\u003e\n\n## Acknowledgments\n\nGLUEMAP stands on a stack of upstream feed-forward and geometry models:\n\n- [COLMAP](https://github.com/colmap/colmap) — output format and broader SfM ecosystem\n- [Doppelgangers++](https://github.com/doppelgangers25/doppelgangers-plusplus) — two-view disambiguator (with MAST3R / DUSt3R / CroCo)\n- [SALAD](https://github.com/serizba/salad) — DINO-based image retrieval\n- [VGGSfM](https://github.com/facebookresearch/vggsfm) — point tracker\n- [LightGlue](https://github.com/cvg/LightGlue) — feature extractor\n\nMulti-view feedforward backbones:\n- [Pi3](https://github.com/yyfz/Pi3) — multi-view pose estimation\n- [VGGT](https://github.com/facebookresearch/vggt) — multi-view geometry transformer\n- [MapAnything](https://github.com/facebookresearch/map-anything) — feed-forward 3D mapping\n\n## Support\n\nPlease, use GitHub Discussions at https://github.com/colmap/gluemap/discussions\nfor questions and the GitHub issue tracker at https://github.com/colmap/gluemap\nfor bug reports, feature requests/additions, etc.\n\n## Contribution\n\nContributions (bug reports, bug fixes, improvements, etc.) are very welcome and\nshould be submitted in the form of new issues and/or pull requests on GitHub.\n\n## License\n\nGLUEMAP is licensed under the new BSD license. Note that this text refers\nonly to the license for GLUEMAP itself, independent of its thirdparty\ndependencies, which are separately licensed. Building GLUEMAP with these\ndependencies may affect the resulting GLUEMAP license.\n\n    Copyright (c), ETH Zurich.\n    All rights reserved.\n\n    Redistribution and use in source and binary forms, with or without\n    modification, are permitted provided that the following conditions are met:\n\n        * Redistributions of source code must retain the above copyright\n          notice, this list of conditions and the following disclaimer.\n\n        * Redistributions in binary form must reproduce the above copyright\n          notice, this list of conditions and the following disclaimer in the\n          documentation and/or other materials provided with the distribution.\n\n        * Neither the name of ETH Zurich nor the names of its contributors\n          may be used to endorse or promote products derived from this\n          software without specific prior written permission.\n\n    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n    ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE\n    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n    POSSIBILITY OF SUCH DAMAGE.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcolmap%2Fgluemap","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcolmap%2Fgluemap","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcolmap%2Fgluemap/lists"}