unzip, then copy each file to:

May 22, 2026 · View on GitHub

ERASOR2



Video   •   Install   •   How to Run   •   Paper   •   Contact Us

ERASOR2 demo
ERASOR2 comparison

ROS-free, instance-aware static map building


:package: Installation

# 1. Build (one cmake call, no ROS/catkin).
cmake -B build -S . && cmake --build build -j

# 2. Conda env for the Python preprocessors + evaluator.
conda env create -f scripts/environment.yml   # creates env "erasor2"
conda activate erasor2

See USAGE.md for the full dependency list and per-distro notes.


SemanticKITTI Setup

Download SemanticKITTI so the sequence folders live under <kitti_dir>/dataset/sequences. For example, the benchmark tree should look like this:

<kitti_dir>/                         # e.g., /home/<user id>/datasets/kitti
└── dataset/
    ├── poses/
    └── sequences/
        ├── 00/
        │   ├── velodyne/
        │   ├── labels/
        │   ├── **poses_suma_optim.txt** (important)
        │   └── times.txt
        ├── 01/
        ├── 02/
        ├── ...
        └── 10/

ERASOR2 uses SuMa poses for evaluation. Download the pose archive and place each poses_suma_optim.txt inside its matching sequence directory:

wget -O suma_poses_for_erasor_eval.zip "https://www.dropbox.com/scl/fi/9q3b1b9npsst1zjawgou3/suma_poses_for_erasor_eval.zip?rlkey=vx4igm68iuo3eobpolgq4tblg&st=yt1ola9b&dl=0"
# unzip, then copy each file to:
# <kitti_dir>/dataset/sequences/<seq>/poses_suma_optim.txt

For each benchmark config in config/erasor2/seq_{00,01,02,05,07}.yaml, set dataloader.abs_data_dir to <kitti_dir>/dataset/sequences and dataloader.abs_save_dir to your ERASOR2 output directory.


:rocket: How to Run

# 3. Generate per-frame Patchwork ground + HDBSCAN instance labels
#    for seqs 00, 01, 02, 05, 07 in one shot.
scripts/generate_labels.sh /path/to/kitti

# 4. Edit config/erasor2/seq_{00,01,02,05,07}.yaml to point at your
#    kitti and output directories, then run the full benchmark.
python scripts/run_benchmark.py

scripts/run_benchmark.py invokes run_pipeline.py for each yaml (mapgen → run_erasor2 → evaluate.py), then prints a single consolidated PR / RR / F1 table. See USAGE.md for further explanation — per-step breakdown, path-editing conventions, visualizer, YAML reference, and HeLiPR / HeLiMOS setup.


:bar_chart: Headline numbers

Some reproduced numbers may differ slightly from the paper after the ROS-free refactor, but the overall performance remains consistent with the reported HDBSCAN-based results. Because this implementation uses HDBSCAN for instance segmentation, compare against the HDBSCAN rows in Table III of the paper.

SeqFramesPR [%] ( paper\color{#c026d3}\textsf{paper} / ours\color{#0969da}\textsf{ours} )RR [%] ( paper\color{#c026d3}\textsf{paper} / ours\color{#0969da}\textsf{ours} )F1 ( paper\color{#c026d3}\textsf{paper} / ours\color{#0969da}\textsf{ours} )
004390 – 453098.649\color{#c026d3}98.649 / 98.654\color{#0969da}\mathbf{98.654}98.582\color{#c026d3}\mathbf{98.582} / 98.454\color{#0969da}98.4540.986\color{#c026d3}\mathbf{0.986} / 0.9855\color{#0969da}0.9855
01150 – 25093.554\color{#c026d3}93.554 / 95.743\color{#0969da}\mathbf{95.743}94.951\color{#c026d3}\mathbf{94.951} / 94.027\color{#0969da}94.0270.943\color{#c026d3}0.943 / 0.9488\color{#0969da}\mathbf{0.9488}
02860 – 95098.339\color{#c026d3}98.339 / 99.196\color{#0969da}\mathbf{99.196}99.709\color{#c026d3}99.709 / 99.902\color{#0969da}\mathbf{99.902}0.990\color{#c026d3}0.990 / 0.9955\color{#0969da}\mathbf{0.9955}
052350 – 267097.473\color{#c026d3}97.473 / 97.670\color{#0969da}\mathbf{97.670}99.113\color{#c026d3}\mathbf{99.113} / 98.412\color{#0969da}98.4120.983\color{#c026d3}\mathbf{0.983} / 0.9804\color{#0969da}0.9804
07630 – 82098.767\color{#c026d3}\mathbf{98.767} / 96.135\color{#0969da}96.13598.800\color{#c026d3}98.800 / 98.989\color{#0969da}\mathbf{98.989}0.988\color{#c026d3}\mathbf{0.988} / 0.9754\color{#0969da}0.9754

Magenta\color{#c026d3}\textsf{Magenta} = paper (Table III, HDBSCAN row), blue\color{#0969da}\textsf{blue} = our re-run. Bold marks the higher value per cell.

ERASOR2 reproduces within run-to-run noise (mean |ΔF1| = 0.006). Higher is better on all three metrics:

  • PR (Preservation Rate) measures how much true static structure remains after dynamic-object removal.
  • RR (Rejection Rate) measures how much dynamic structure is correctly rejected from the static map.
  • F1 is the harmonic mean of PR and RR, giving one balanced score when preservation and rejection both matter.

:books: Citation

If you use this code in academic work, please cite the ERASOR / ERASOR2 papers.

@article{lim2025erasor2,
  title   = {{ERASOR2}: Instance-Aware Robust 3D Mapping of the Static World in Dynamic Scenes},
  author  = {Lim, Hyungtae and others},
  journal = {IEEE Robotics and Automation Letters},
  year    = {2025}
}
@article{lim2021erasor,
  title   = {{ERASOR}: Egocentric Ratio of Pseudo Occupancy-based Dynamic Object Removal for Static 3D Point Cloud Map Building},
  author  = {Lim, Hyungtae and Hwang, Sungwon and Myung, Hyun},
  journal = {IEEE Robotics and Automation Letters},
  volume  = {6},
  number  = {2},
  pages   = {2272--2279},
  year    = {2021}
}
@inproceedings{lim2024helimos,
  title     = {{HeLiMOS: A dataset for moving object segmentation in 3D point clouds from heterogeneous LiDAR sensors}},
  author    = {Lim, Hyungtae and Jang, Seoyeon and Mersch, Benedikt and Behley, Jens and Myung, Hyun and Stachniss, Cyrill},
  booktitle = {2024 IEEE/RSJ International Conference on Intelligent Robots and Systems (IROS)},
  pages     = {14087--14094},
  year      = {2024}
}