Scalable Feature Matching via State Space Modeling and Sparse Correlation (CVPR 2026 Highlight ⭐)

June 9, 2026 · View on GitHub

Choo Sin Wai, Bo Li*
* corresponding author

SLiM means Salient Lightweight Matching
When we submitted the paper, we not yet have an official abbreviation. Following a reviewer’s suggestion, we later decided to abbreviate our method as SLiM. However, since the paper title cannot be changed after rebuttal, the final title does not include “SLiM”.

Paper   Youtube

CVPR 2026 poster
Figure 1: CVPR 2026 poster.

Method pipeline
Figure 2: Method pipeline.

Comparison
Figure 3: Accuracy-efficiency tradeoff comparison on MegaDepth.

📰 News

  • 🎉🎉🎉 [2026.02] Our paper is accepted to CVPR 2026.
  • 🎉🎉🎉 [2026.04] Our paper is selected as a CVPR 2026 Highlight.

✅ TODO

ToDosStatus
Installation Guides✅ Available
Pre-trained Models✅ Available
Training & testing Code✅ Available

⚙️ Installation and environment setup

1. 🗂️ Dataset Setup (thanks to LoFTR for the guides)

1.1 📥 Download dataset indices

  • Download the dataset indices (filename: data.7z) from this Google Drive or Baidu Netdisk [password: 22w1].
  • Unzip them and place them under the project root as follows:
SLiM
└── data
     ├── megadepth
     │   └── index
     │        ├── scene_info_0.1_0.7
     │        ├── scene_info_val_1500
     │        └── trainvaltest_list
     └── scannet
          ├── index
          │   ├── intrinsics.npz
          │   ├── scene_data
          │   └── statistics.json
          └── test
               └── scenexxxx_xx (100 scenes here)

1.2 📦 Download dataset

1.2.1 🏔️ MegaDepth

Similar to LoFTR, we use depth maps provided in the original MegaDepth dataset as well as undistorted images, corresponding camera intrinsics and extrinsics preprocessed by D2-Net. You can download them separately from the following links:

  • MegaDepth undistorted images and processed depths
    • Note that we only use depth maps.
    • Path of the downloaded data will be referred to as /path/to/megadepth
  • D2-Net preprocessed images
    • Images are undistorted manually in D2-Net since the undistorted images from MegaDepth do not come with corresponding intrinsics.
    • Path of the downloaded data will be referred to as /path/to/megadepth_d2net
1.2.2 🏢 ScanNet
  • Download the dataset following the official guide: ScanNet, and use the Python-exported data.

We symlink the datasets into the data directory under the project root.

# scannet
# -- # train dataset
ln -s /path/to/scannet_train/* /path/to/SLiM/data/scannet/train

# megadepth
# -- # train and test dataset (train and test share the same dataset)
ln -sv /path/to/megadepth/phoenix /path/to/megadepth_d2net/Undistorted_SfM /path/to/SLiM/data/megadepth/train
ln -sv /path/to/megadepth/phoenix /path/to/megadepth_d2net/Undistorted_SfM /path/to/SLiM/data/megadepth/test

1.4 🧱 Final data structure

SLiM
└── data
      ├── megadepth
      │   ├── index
      │   │   ├── scene_info_0.1_0.7
      │   │   ├── scene_info_val_1500
      │   │   └── trainvaltest_list
      │   ├── test
      │   │   ├── phoenix
      │   │   └── Undistorted_SfM
      │   └── train
      │       ├── phoenix
      │       └── Undistorted_SfM
      └── scannet
          ├── index
          │   ├── intrinsics.npz
          │   ├── scene_data
          │   └── statistics.json
          ├── test
               └── scenexxxx_xx (100 scenes here)
          └── train
               └── scenexxxx_xx (1513 scenes here)

2. 🧰 Environment Setup

We have tested the following environment on Ubuntu 22.04.

  • CUDA version does not have to be identical to ours, but make sure:
    • Your NVIDIA driver supports the CUDA version used by your PyTorch build (i.e., driver capability should be >= PyTorch CUDA version).
    • The PyTorch CUDA version should match the CUDA toolkit you compile against in the environment.
  • CUDA toolkit choice
    • If your system already has a compatible cuda-toolkit, you can use the system installation.
    • Otherwise, install cuda-toolkit inside the conda environment (as shown below) and use it for compilation.
  • GCC/G++ compatibility
    • gcc/g++ must be compatible with the CUDA toolkit version you use.
    • If your system gcc/g++ can compile CUDA extensions successfully, you do not need to install gcc/g++ in conda.
conda create -n slim -y python=3.10
conda activate slim

# torch = 2.1.1+cu118
pip install torch==2.1.1 torchvision==0.16.1 torchaudio==2.1.1 --index-url https://download.pytorch.org/whl/cu118\

# mamba and causal-conv1d package, check mamba github page if installation/build fails
conda install cuda-toolkit==11.8 -c nvidia/label/cuda-11.8.0
pip install causal-conv1d==1.2.1 # try --no-build-isolation if installation failed
pip install mamba-ssm==2.2.2 # try --no-build-isolation if installation failed

# other dependencies: pytorch-lightning, albumentation, yacs etc.
pip install -r requirements.txt

# selective scan from vmamba
#     force use conda gcc and g++ (=11)
conda install -c conda-forge -y gcc_linux-64=11 gxx_linux-64=11
export CC="$CONDA_PREFIX/bin/x86_64-conda-linux-gnu-gcc"
export CXX="$CONDA_PREFIX/bin/x86_64-conda-linux-gnu-g++"
#     force use conda cuda
export CUDA_HOME="$CONDA_PREFIX"
export PATH="$CUDA_HOME/bin:$PATH"
export LD_LIBRARY_PATH="$CUDA_HOME/lib:$CUDA_HOME/lib64:$LD_LIBRARY_PATH"
#     compilation takes time, please wait patiently
cd src/backbone/vssm/kernels/selective_scan
pip install . --no-build-isolation
cd ../../../../../

📦 Pretrained model

The pretrained model is provided at: ckpt/megadepth_19epochs.ckpt

🏋️ Training

Train on indoor or outdoor datasets. --device specifies which GPU(s) to use (e.g., 0,1,2 for GPUs 0–2; also accept 8 to use the first 8 GPUs). Example usage: --device 0,1,2,3 or --device 4.

# Indoor train
python train.py --config_name indoor_train --device {device indices}
# Outdoor train
python train.py --config_name outdoor_train --device {device indices}

Optional: run the process in the background and redirect stdout to a log file:

nohup python train.py --config_name indoor_train --device 0,1,2 > indoor_train.log &

🧪 Testing

Test on indoor or outdoor datasets. --device follows the same convention as training.

# Indoor test
python test.py --config_name indoor_test --device {device indices}
# Outdoor test
python test.py --config_name outdoor_test --device {device indices}

Optional: run the process in the background and redirect stdout to a log file:

nohup python test.py --config_name indoor_test --device 0,1,2 > indoor_test.log &

📚 Citation

@inproceedings{choo2026slim,
  title={Scalable Feature Matching via State Space Modeling and Sparse Correlation},
  author={Choo, Sin Wai and Li, Bo},
  booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR)},
  year={2026}
}