Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ If you prefer to build the Docker image by yourself, Check [build-docker-image](

## 1. Data Preparation

Refer to [dataprocess/README.md](dataprocess/README.md) for dataset download instructions. Currently, we support **Argoverse 2**, **Waymo**, **nuScenes**, **ZOD** and **custom datasets** (more datasets will be added in the future).
Refer to [dataprocess/README.md](dataprocess/README.md) for dataset download instructions. Currently, we support **Argoverse 2**, **Waymo**, **nuScenes**, [**MAN-TruckScene**](https://github.com/TUMFTM/truckscenes-devkit), [**ZOD**](https://github.com/zenseact/zod) and **custom datasets** (more datasets will be added in the future).

After downloading, convert the raw data to `.h5` format for easy training, evaluation, and visualization. Follow the steps in [dataprocess/README.md#process](dataprocess/README.md#process).

Expand Down Expand Up @@ -337,6 +337,12 @@ If you find it useful, please cite our works:
year={2025},
journal={arXiv preprint arXiv:2503.00803},
}
@article{zhang2025deltaflow,
title={{DeltaFlow}: An Efficient Multi-frame Scene Flow Estimation Method},
author={Zhang, Qingwen and Zhu, Xiaomeng and Zhang, Yushan and Cai, Yixi and Andersson, Olov and Jensfelt, Patric},
year={2025},
journal={arXiv preprint arXiv:2508.17054},
}
```

And our excellent collaborators works contributed to this codebase also:
Expand Down
37 changes: 0 additions & 37 deletions assets/slurm/0_process.sh

This file was deleted.

44 changes: 44 additions & 0 deletions assets/slurm/data-process.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#!/bin/bash
#SBATCH -J dataprocess
#SBATCH -p berzelius-cpu
#SBATCH --cpus-per-task 64
#SBATCH --mem 128G
#SBATCH --mincpus=64
#SBATCH -t 2-00:00:00
#SBATCH --mail-type=END,FAIL
#SBATCH --mail-user=qingwen@kth.se
#SBATCH --output /proj/berzelius-2023-154/users/x_qinzh/OpenSceneFlow/logs/slurm/%J_data.out
#SBATCH --error /proj/berzelius-2023-154/users/x_qinzh/OpenSceneFlow/logs/slurm/%J_data.err

PYTHON=/proj/berzelius-2023-154/users/x_qinzh/mambaforge/envs/sftool/bin/python
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/proj/berzelius-2023-154/users/x_qinzh/mambaforge/lib
cd /proj/berzelius-2023-154/users/x_qinzh/OpenSceneFlow/
# export HYDRA_FULL_ERROR=1


# =============== Argoverse2
# $PYTHON dataprocess/extract_av2.py --nproc 64 \
# --av2_type sensor \
# --data_mode train \
# --argo_dir /proj/berzelius-2023-154/users/x_qinzh/av2 \
# --output_dir /proj/berzelius-2023-364/users/x_qinzh/data/av2/h5py

# $PYTHON dataprocess/extract_av2.py --nproc 64 \
# --av2_type sensor \
# --data_mode val \
# --argo_dir /proj/berzelius-2023-154/users/x_qinzh/av2 \
# --output_dir /proj/berzelius-2023-364/users/x_qinzh/data/av2/h5py \
# --mask_dir /proj/berzelius-2023-154/users/x_qinzh/av2/3d_scene_flow

# $PYTHON dataprocess/extract_av2.py --nproc 64 \
# --av2_type sensor \
# --data_mode test \
# --argo_dir /proj/berzelius-2023-154/users/x_qinzh/av2 \
# --output_dir /proj/berzelius-2023-364/users/x_qinzh/data/av2/h5py \
# --mask_dir /proj/berzelius-2023-154/users/x_qinzh/av2/3d_scene_flow

# =============== MAN-Truckscenes
$PYTHON dataprocess/extract_truckscenes.py --nproc 12 \
--data_dir /proj/berzelius-2023-364/users/x_qinzh/data/truckscenes/raw_data/trainval/man-truckscenes \
--mode v1.0-trainval \
--output_dir /proj/berzelius-2023-364/data/truckscenes/h5py
2 changes: 1 addition & 1 deletion assets/tests/hdbscan_speed.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

def vis(pc0, labels, title='HDBSCAN'):
# visualize
vis = MyVisualizer(view_file=f'{BASEF_DIR}/assets/view/av2.json', window_title=title)
vis = MyVisualizer(view_file=f'{BASEF_DIR}/assets/view/demo.json', window_title=title)
pcd = o3d.geometry.PointCloud()
num_points = pc0.shape[0]
pcd.points = o3d.utility.Vector3dVector(pc0)
Expand Down
19 changes: 0 additions & 19 deletions assets/view/av2.json

This file was deleted.

19 changes: 19 additions & 0 deletions assets/view/demo.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"class_name" : "ViewTrajectory",
"interval" : 29,
"is_loop" : false,
"trajectory" :
[
{
"boundingbox_max" : [ 215.05035400390625, 80.301795959472656, 34.890830993652344 ],
"boundingbox_min" : [ -211.76950073242188, -125.19444274902344, -4.2829980850219727 ],
"field_of_view" : 90.0,
"front" : [ -0.58999680455306347, -0.15524870408634167, 0.79233932787454509 ],
"lookat" : [ 9.9369846496341676, 13.322769196068615, -16.164870152242376 ],
"up" : [ 0.79499677526385637, 0.059685607254847638, 0.60367023746967163 ],
"zoom" : 0.17999999999999999
}
],
"version_major" : 1,
"version_minor" : 0
}
31 changes: 31 additions & 0 deletions conf/others/truckscenes.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@

[important]
height = 0 # ego height. since truckscene have multiple LiDARs, we set pc to ego-coord already.

# 整个雷点点云以自己为中心 分为多少个segment,每个segment又分成多少个bin
[segments]
r_min = 0.1 # minimum point distance. 感兴趣的区域
r_max = 100 # maximum point distance.
n_segments = 360 # number of radial segments.
n_bins = 160 # number of radial bins.


[ground]
# 直线的 slope 斜率,一个seg里拟合的线斜率
min_slope = 0.0 # minimum slope of a ground line. [T_m_small]
max_slope = 0.1 # maximum slope of a ground line. [T_m]
# 如果拟合点超过这个 long threshold,判断其 height 变化是否超过 max_long_height
long_threshold = 2.0 # Distance at which points are considered far from each other. [T_d_prev]
max_long_height = 0.3 # maximum height change to previous point in long line. [T_b]
# 如果没有超过 long threshold,判断现在拟合的点与fitline高度变化是否超过 max_start_height
max_start_height = 0.2 # Maximum heigh of starting line to be labelled ground.
# 最大的拟合误差,超过这个误差的点不会被加入 line 拟合
max_fit_error = 0.1 # maximum error of a point during line fit. [T_RMSE: will sqaure inside code.]

# 判断是否是地面点的时候,需要满足的条件:
max_dist_to_line = 0.2 # maximum vertical distance of point to line to be considered ground. [T_d_ground]
line_search_angle = 2.0 # How far to search for a line in angular direction [rad].

[general]
n_threads = 8 # number of threads for parallel processing.
verbose = false # if you don't want to see every output, set this to false.
2 changes: 1 addition & 1 deletion conf/ground/zod.toml → conf/others/zod.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ max_start_height = 0.2 # Maximum heigh of starting line to be labelled ground.
max_fit_error = 0.1 # maximum error of a point during line fit. [T_RMSE: will sqaure inside code.]

# 判断是否是地面点的时候,需要满足的条件:
max_dist_to_line = 0.2 # maximum vertical distance of point to line to be considered ground. [T_d_ground]
max_dist_to_line = 0.25 # maximum vertical distance of point to line to be considered ground. [T_d_ground]
line_search_angle = 2.0 # How far to search for a line in angular direction [rad].

[general]
Expand Down
50 changes: 47 additions & 3 deletions dataprocess/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ README for downloading and preprocessing the dataset. We includes waymo, argover
- [Download](#download): includes how to download the dataset.
- [Process](#process): run script to preprocess the dataset.

We've updated the process dataset for:
We've updated the process dataset for (Please cite the original dataset paper and involved work if you use them):

- [x] Argoverse 2.0: check [here](#argoverse-20). The process script Involved from [DeFlow](https://github.com/KTH-RPL/DeFlow).
- [x] Waymo: check [here](#waymo-dataset). The process script was involved from [SeFlow](https://github.com/KTH-RPL/SeFlow).
- [x] nuScenes: check [here](#nuscenes), The process script was involved from [DeltaFlow](https://github.com/Kin-Zhang/DeltaFlow).
- [x] ZOD (w/o gt): check [here](#zod-dataset). The process script was involved from [HiMo](https://kin-zhang.github.io/HiMo). (It could be a good first reference for users to extract other datasets in the future.)
- [ ] TruckScene: done coding, public after review. Will be involved later by another paper.
- [x] TruckScene: check [here](#truckscene). The process script was involved from [DoGFlow](https://github.com/ajinkyakhoche/DoGFlow).

If you want to **use all datasets above**, there is a **specific environment** in [envsftool.yaml](../envsftool.yaml) to install all the necessary packages. As Waymo package have different configuration and conflict with the main environment. Setup through the following command:

Expand Down Expand Up @@ -134,6 +134,46 @@ For HiMo, we only downloaded [drives-set](https://zod.zenseact.com/drives/) for

Please check the scripts: [dataprocess/extract_zod.py](./extract_zod.py) in detail, current we only process one scene while feel free to comment out for all scene etc.

### TruckScene

Please visit the [TruckScene dataset](https://brandportal.man/d/QSf8mPdU5Hgj/downloads#/-/dataset) page for privacy policy. You can download the dataset by following command:

```bash
# mini set, ~11G recommended for debugging purpose
cd /home/kin/data/truckscene/mini
wget https://man-truckscenes.s3.eu-central-1.amazonaws.com/release/mini/man-truckscenes_metadata_v1.0-mini.zip
wget https://man-truckscenes.s3.eu-central-1.amazonaws.com/release/mini/man-truckscenes_sensordata_v1.0-mini.zip
unzip "man-truckscenes_*.zip"

# full trainval set, ~630G
cd /home/kin/data/truckscene/trainval
wget https://man-truckscenes.s3.eu-central-1.amazonaws.com/release/trainval/man-truckscenes_metadata_v1.0-trainval.zip
wget https://man-truckscenes.s3.eu-central-1.amazonaws.com/release/trainval/man-truckscenes_sensordata01_v1.0-trainval.zip
wget https://man-truckscenes.s3.eu-central-1.amazonaws.com/release/trainval/man-truckscenes_sensordata02_v1.0-trainval.zip
wget https://man-truckscenes.s3.eu-central-1.amazonaws.com/release/trainval/man-truckscenes_sensordata03_v1.0-trainval.zip
wget https://man-truckscenes.s3.eu-central-1.amazonaws.com/release/trainval/man-truckscenes_sensordata04_v1.0-trainval.zip
wget https://man-truckscenes.s3.eu-central-1.amazonaws.com/release/trainval/man-truckscenes_sensordata05_v1.0-trainval.zip
wget https://man-truckscenes.s3.eu-central-1.amazonaws.com/release/trainval/man-truckscenes_sensordata06_v1.0-trainval.zip
wget https://man-truckscenes.s3.eu-central-1.amazonaws.com/release/trainval/man-truckscenes_sensordata07_v1.0-trainval.zip
unzip "man-truckscenes_*.zip"
```

Folder structure:
```
truckscene/
— samples/
— sweeps/
— v1.0-mini/
— v1.0-trainval/
```

#### Dataset frames

| Dataset | # Total Scene | # Total Frames |
| ------- | ------------- | -------------- |
| train | 524 | 101902 / 20380 (w. gt) |
| val | 75 | 14625 / 2925 (w. gt) |



## Process
Expand All @@ -144,8 +184,9 @@ This directory contains the scripts to preprocess the datasets into `.h5` files.
- `extract_nus.py`: Process the datasets in nuScenes.
- `extract_waymo.py`: Process the datasets in Waymo.
- `extract_zod.py`: Process the datasets in ZOD.
- `extract_truckscene.py`: Process the datasets in TruckScene.

Example Running command:
Example Running command, you can also check our [slurm data-process script](../assets/slurm/data-process.sh) for more details.:
```bash
# av2:
python dataprocess/extract_av2.py --av2_type sensor --data_mode train --argo_dir /home/kin/data/av2 --output_dir /home/kin/data/av2/h5py
Expand All @@ -155,6 +196,9 @@ python dataprocess/extract_waymo.py --mode train --flow_data_dir /home/kin/data/

# nus:
python dataprocess/extract_nus.py --mode v1.0-trainval --output_dir /home/kin/data/nus/h5py/full --nproc 24

# truckscene:
python dataprocess/extract_truckscene.py --data_dir /home/kin/data/man-truckscenes --mode v1.0-mini --output_dir /home/kin/data/nus/h5py
```


Expand Down
32 changes: 17 additions & 15 deletions dataprocess/extract_nus.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import multiprocessing
from pathlib import Path
from multiprocessing import Pool, current_process
from typing import Optional, Final
from typing import Optional
from tqdm import tqdm
import numpy as np
import fire, time, h5py
Expand Down Expand Up @@ -69,10 +69,13 @@ def _load_points_from_file(filename: str) -> np.ndarray:
pc = pc.reshape((-1, 5))[:, :4]
return pc

def get_pose(nusc, sweep_data):
# pose from lidar to world
ego2lidar = nusc.get('calibrated_sensor', sweep_data['calibrated_sensor_token'])
world2ego = nusc.get('ego_pose', sweep_data['ego_pose_token'])
def get_pose(data_fn, sweep_data, w2stf=True):
world2ego = data_fn.get('ego_pose', sweep_data['ego_pose_token'])
# without considering the sensor to ego transform, we will do it outside if multiple sensors are used.
if not w2stf:
return transform_matrix(world2ego['translation'], Quaternion(world2ego['rotation'])).astype(np.float64)

ego2lidar = data_fn.get('calibrated_sensor', sweep_data['calibrated_sensor_token'])
ego2lidar_np = transform_matrix(ego2lidar['translation'], Quaternion(ego2lidar['rotation']))
world2ego_np = transform_matrix(world2ego['translation'], Quaternion(world2ego['rotation']))
return np.dot(world2ego_np, ego2lidar_np)
Expand All @@ -85,13 +88,13 @@ def if_annotated_frame(sample_ann_dict, ts0):
break
return gt_flow_flag

def _resample_data(nusc, sample_data, sample_ann_dict, resample2frequency=10):
def _resample_data(nusc, sample_data, sample_ann_dict, datafrequency=20, resample2frequency=10):
"""
NOTE(Qingwen) - 2025-05-18:
We always want to start from the first GT frame, and then resample the data! So we have as many GT frames as possible...
"""
sweep_data_lst, timestamps_lst = [], []
skipFrame = int(20 / resample2frequency) # since nuscenes sweep at 20Hz, we want to resample to 10Hz
skipFrame = int(datafrequency / resample2frequency) # since nuscenes sweep at 20Hz, we want to resample to 10Hz
cnt = 0

# Find the first GT frame
Expand Down Expand Up @@ -268,18 +271,17 @@ def proc(x, ignore_current_process=False):
pos = 1
process_log(*x, n=pos)

def process_logs(nusc_mode, data_dir: Path, scene_list: list, output_dir: Path, nproc: int):
"""Compute sceneflow for all logs in the dataset. Logs are processed in parallel.
Args:
data_dir: Argoverse 2.0 directory
output_dir: Output directory.
def process_logs(data_mode, data_dir: Path, scene_list: list, output_dir: Path, nproc: int):
"""

Compute sceneflow for all logs in the dataset.
Logs are processed in parallel.
"""

if not (data_dir).exists():
print(f'{data_dir} not found')
return

args = sorted([(nusc_mode, data_dir, scene_num_id, output_dir) for scene_num_id in range(len(scene_list))])
args = sorted([(data_mode, data_dir, scene_num_id, output_dir) for scene_num_id in range(len(scene_list))])
print(f'Using {nproc} processes')

# # for debug
Expand All @@ -295,7 +297,7 @@ def process_logs(nusc_mode, data_dir: Path, scene_list: list, output_dir: Path,
res = list(tqdm(p.imap_unordered(proc, args), total=len(scene_list), ncols=100))

def main(
data_dir: str = "/home/kin/data/nus/v1.0",
data_dir: str = "/home/kin/data/nus/raw",
mode: str = "v1.0-mini",
output_dir: str ="/home/kin/data/nus/h5py/demo",
nproc: int = (multiprocessing.cpu_count() - 1),
Expand Down
Loading