Skip to content

vocab_tree_builder always builds a 128-d index, so trees can't be trained on LoMa / ALIKED descriptors #4918

Closed

Description

@YonatanSimson

Describe the bug
vocab_tree_builder always builds a 128-dimensional visual index, whatever descriptors are in the database. With LoMa-B features (256-d) it loads every descriptor and then aborts:

visual_index.cc:435 Check failed: descriptors.data.cols() == kDescDim (256 vs. 128)

So a vocabulary tree can't be trained on LoMa (or any non-128-d) features.

To Reproduce

  1. Build COLMAP with ONNX.
  2. colmap feature_extractor --database_path db.db --image_path images --FeatureExtraction.type LOMA_B
  3. colmap vocab_tree_builder --database_path db.db --vocab_tree_path tree.bin --num_visual_words 4096
  4. See the error above, raised from FaissVisualIndex<128, 64>::Build.

Expected behavior
The tree is built with the descriptors' own dimension (256 → embedding 64 for LoMa-B), as for SIFT, and can then be used by vocab_tree_matcher.

Screenshots
N/A

Environment:

  • OS: Ubuntu 22.04 (WSL2), CUDA 12.9, RTX 5090
  • COLMAP Version: 4.2.0 (be5e291) and 4.2.1 (bd1fcf6); the same code is in main at 9371f7b
  • Capture Device: GoPro HERO13 Black (any images reproduce it)

Additional context
src/colmap/exe/vocab_tree.cc:65 calls retrieval::VisualIndex::Create() with no arguments. It therefore gets the defaults desc_dim = 128, embedding_dim = 64 (visual_index.h:83). The rest of the pipeline already handles other sizes:

  • Create() implements 256/64 and 32/16.
  • Trees store their descriptor size, embedding size and feature type, and Read() restores them.
  • vocab_tree_matcher checks the feature type.
  • A pretrained LoMa-B tree is shipped.

Only the builder is stuck at 128.

Suggested fix: size the index from the loaded descriptors.

const int desc_dim = descriptors.data.cols();
const int embedding_dim = desc_dim == 32 ? 16 : 64; // the pairs Create() implements
auto visual_index = retrieval::VisualIndex::Create(desc_dim, embedding_dim);

An optional --embedding_dim (0 = derive) would cover dimension/embedding pairs added later. SIFT is unchanged (128 → 64). With this patch on 4.2.1, a per-scan LoMa-B tree builds (Descriptor dimension 256 (LOMA_B), embedding dimension 64, 4096 words), and matching and global_mapper run normally. Happy to open a PR.

Activity

  1. added a commit that references this issue on Oct 30, 2026
    ce2b5ab
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions