RoCo Spring Competition - Scene Flow
July 27, 2026 · View on GitHub
This folder contains the dedicated scripts and configurations required to participate in the Scene Flow category of the RoCo Spring Competition.
Before proceeding, ensure you have completed the environment setup and dataset configuration outlined in the main README.md file.
Navigate to this directory in your terminal before running any scripts:
cd roco_spring_devkit/scene_flow/
Available Scripts
Three primary scripts are provided to manage your development workflow:
test.py: Generates the final output predictions required for competition submission.train.py: Handles model training or fine-tuning pipelines.validate.py: Evaluates your model locally and computes standard performance metrics.
test.py
Use this script to run inference on the competition test sets. For example, to generate outputs using the provided baseline RAFT-3D model:
python test.py --data.test_dataset spring-robust --model raft_3d_bilaplacian --ckpt_path laplacian --model.compute_disparity true --model.disparity_ckpt sceneflow --num_gpus -1 --save_viz
The resulting files will be saved to outputs/test/<model_and_checkpoint_name>.
Key Arguments Breakdown:
--data.test_dataset spring-robust: Samples from thespring-robusttest split are being used to generate the results. You can also check the section Adding a Custom Dataset to learn how to include other datasets.--model raft_3d_bilaplacian: Use the RAFT-3D-Laplacian scene flow model. Check the section Adding a Custom Model to learn how to add your own custom model.--ckpt_path laplacian: The path to the checkpoint to be used by the model. In this example, we use a custom name (laplacian) that is defined in thepretrained_checkpointsproperty of the RAFT-3D-Laplacian model. If you have a local or online checkpoint, replacelaplacianwith the path or the URL of the checkpoint you want to load.--model.compute_disparity: Set to true if you want to compute the disparity on-the-fly usingraft_stereo. If false, the disparity must be available in the dataset.--model.disparity_ckpt: If--model.compute_disparity true, then this sets the checkpoint to be used forraft_stereo.--num_gpus: Number of GPUs to use for inference,-1uses all the GPUs. To select specific GPUs, set the environmental variable, for exampleCUDA_VISIBLE_DEVICES=0,2,4 python test.py ....--save_viz: (Optional) Generates image visualizations of your disparity predictions. Helpful for visual sanity checks, but can be omitted to accelerate inference and conserve disk space.
Valid Entries for --data.test_dataset
springspring-robustkitti-2015
To find all available CLI options, run:
python test.py -h
train.py
This script provides a standardized framework for training or fine-tuning models using the devkit's datasets.
To fine-tune the default RAFT-3D model using the Spring dataset configuration:
python train.py --config models/raft_3d/configs/raft_3d-train-spring.yaml
- Outputs: Logs, telemetry, and model checkpoints are saved automatically inside the
ptlflow_logs/folder. - Customization: Training configurations are entirely managed via YAML files. To modify learning rates, batch sizes, or augmentations, create or adapt a configuration file. For an in-depth reference, see the PTLFlow Configuration Documentation.
validate.py
This helper script assesses your model's quality on target datasets containing ground-truth data, providing instant metric feedback (e.g., Abs).
To validate the RAFT-3D-Laplacian model on the Spring validation split:
python validate.py --data.val_dataset spring-val --model raft_3d_bilaplacian --ckpt_path laplacian --model.compute_disparity true --model.disparity_ckpt sceneflow --write_outputs
Outputs containing validation statistics will be written to outputs/validate/<model_and_checkpoint_name>.
Key Arguments Breakdown:
--data.val_dataset spring: Sets the validation target. You can validate on multiple datasets simultaneously by combining them with a+symbol (e.g.,--data.val_dataset kitti-2015+sintel-clean).--write_outputs: (Optional) Exports disparity files, heatmaps, and Abs visualizations for error diagnosis.
Valid Entries for --data.val_dataset
springsintel-cleansintel-finalkitti-2015
⚠️ Note:
spring-robustis not a valid entry for validation because it does not provide publicly accessible validation ground truths.
Submission Example
This is an example of generating and submitting scene flow results to the competition.
- Run the test script as in the example of test.py above. Suppose the results are saved to
./outputs/test/raft_3d_bilaplacian_laplacian/spring-robust
├── brightness
│ └── test
│ ├── 0003
│ │ ├── disp1_left
│ │ │ ├── disp1_left_0001.dsp5
│ │ │ ...
│ │ ├── disp1_right
│ │ ├── disp2_BW_left
│ │ ├── disp2_BW_right
│ │ ├── disp2_FW_left
│ │ ├── disp2_FW_right
│ │ ├── flow_BW_left
│ │ │ ├── flow_BW_left_0001.flo5
│ │ │ ...
│ │ ├── flow_BW_right
│ │ ├── flow_FW_left
│ │ └── flow_FW_right
│ ...
├── clean
├── contrast
├── [other corruption names]
...
- Use the Spring subsampling executables.
# Assuming the terminal is at /path/to/roco_spring_devkit/roco_spring_devkit/stereo/
# First, generate the submission to the main Spring benchmark using the "clean" results
/path/to/subsampling_executables/disp1_subsampling outputs/test/raft_3d_bilaplacian_laplacian/spring-robust/clean/test
# This will generate a file disp1_submission.hdf5
/path/to/subsampling_executables/disp2_subsampling outputs/test/raft_3d_bilaplacian_laplacian/spring-robust/clean/test
# This will generate a file disp2_submission.hdf5
/path/to/subsampling_executables/flow_subsampling outputs/test/raft_3d_bilaplacian_laplacian/spring-robust/clean/test
# This will generate a file flow_submission.hdf5
# Then generate the submission to the robustness benchmark
/path/to/subsampling_executables/disp1_robust_subsampling outputs/test/raft_3d_bilaplacian_laplacian/spring-robust/
# This will generate a file disp1_robustness.hdf5
/path/to/subsampling_executables/disp2_robust_subsampling outputs/test/raft_3d_bilaplacian_laplacian/spring-robust/
# This will generate a file disp2_robustness.hdf5
/path/to/subsampling_executables/flow_robust_subsampling outputs/test/raft_3d_bilaplacian_laplacian/spring-robust/
# This will generate a file flow_robustness.hdf5
- Submit the six respective
.hdf5files to the Spring benchmark website.
Adding a Custom Model
To introduce your own model design into the competition pipeline:
- Create a new directory under
roco_spring_devkit/scene_flow/models/<your_model_name>/. - Define your model architecture by inheriting from
roco_spring_devkit.scene_flow.models.base_model.base_modelBaseModel class.- Be sure to initialize the BaseModel by calling
super().__init__(
output_stride=<maximum stride of the model>,
loss_fn=<None or check the loss_fn instructions below>,
**kwargs
)
- Register your new architecture configuration inside your model initialization script.
- Import the
register_modelannotation:
- Import the
from roco_spring_devkit.common.utils.registry import register_model
- Annotate your class to register it. For example, if your model is called `MyCustomModel`:
@register_model
class MyCustomModel(BaseModel):
...
- Import your custom model in
__init__.pyto make it visible to the other scripts.
# In file roco_spring_devkit.scene_flow.models.__init__.py, add one extra import:
import roco_spring_devkit.scene_flow.models.<my_custom_model_folder_name>.<my_custom_model_file_name>
Model I/O
To interact with the existing scripts, your model should support the following I/O:
Input
The model's forward function must receive a dictionary as one of the first arguments. The input images are provided as the dictionary keys:
"images": A 5D tensor with shape [batch_size, 2, 3, height, width] containing the first and second left images. The second dimension corresponds to the number of input images, and the third to the number of image channels."images_right": A 5D tensor with shape [batch_size, 2, 3, height, width] containing the right images.
Output
Your model must output a dictionary with at least the following keys:
"disparities": A 5D tensor with shape [batch_size, 1, 1, height, width] containing the estimated disparity from the left to the right image."disparities_right": Similar to"disparities", but contains the estimated disparity from the right to the left image."disparities2": Similar to"disparities", but contains the estimated disparity at the second pair of images (at instant t + 1)."disparities2_right": Similar to"disparities2", but contains the estimated disparity at the second pair of images from the right to the left image."disparities2_b": Reverses the time order of the images, and treats the first image as the second and vice-versa. It could be the same result as in"disparities". However, if your model uses temporal information then it could be different."disparities2_b_right": Similar to"disparities2_b", but contains the estimated disparity from the right to the left image."disparities2_raw": A 5D tensor with shape [batch_size, 1, 1, height, width] containing the estimated disparity from the left to the right image at the second image pair. It is the equivalent of"disparities", but for the seconf image pair. It should be different from"disparities2"because"disparities2"should use temporal information to make it consistent with"disparities"."disparities2_raw_right": Similar to"disparities2_raw"but for the right to left disparity."flows": A 5D tensor with shape [batch_size, 1, 2, height, width] containing the estimated forwarded flow for the left camera (the"images"input). The second dimension corresponds to the number of output flows, and the third dimension to the x and y flow channels."flows_right": Similar to"flows", but contains the estimated forward flow of the"images_right"input."flows_b": Similar to"flows", but contains the estimated backward flow (from the second image to the first) of the"images"input."flows_b_right": Similar to"flows_b", but contains the estimated backward flow of the"images_right"input.
loss_fn
If you want to use the train.py script to train your model, you need to provide a function or a callable class to loss_fn during the initialization of your custom model. To work, it must support the following I/O.
Input
It must receive at least two dictionaries as the first two inputs.
- The first dictionary contains the
outputsof the model. - The second dictionary contains the
inputsof the model, such as the groundtruth information.
Output
The output must be either a single tensor containing the loss value or a dictionary. If the output is a dictionary, it must contain a key named loss whose value is a tensor containing the loss value.
Additional details about adding a model
For an explicit, step-by-step code walkthrough, please consult the PTLFlow Custom Model Guide.
Adding a Custom Dataset
If you want to train your models on additional external datasets, follow these steps:
- Define a class for your new dataset in
roco_spring_devkit.common.data.scene_flow_datasets.py. For example:
class MySceneFlowDataset(BaseSceneFlowDataset):
...
- The easiest way is to let your new class inherit from
BaseSceneFlowDatasetto let it handle the reading. However, you can also create your own full pipeline.- If inheriting from
BaseSceneFlowDataset, your class should fill the following lists:self.img_paths: Each element is a list with two elements, the paths to the first and second images of the left camera.self.img_r_paths: Each element is a list with two elements, the paths to the first and second images of the right camera.self.disp_paths: (Optional) Each element is a list with one element, the path to the groundtruth disparity between the left and right image.self.disp_r_paths: (Optional) Each element is a list with one element, the path to the groundtruth disparity between the right and left image.self.flow_paths: (Optional) Each element is a list with one element, the path to the groundtruth flow between the first and second image of the left camera.self.flow_b_paths: (Optional) Each element is a list with one element, the path to the groundtruth flow between the second and first image of the left camera.self.flow_r_paths: (Optional) Each element is a list with one element, the path to the groundtruth flow between the first and second image of the right camera.self.flow_b_r_paths: (Optional) Each element is a list with one element, the path to the groundtruth flow between the second and first image of the right camera.
- If inheriting from
- Add a new entry to
datasets.yaml.- For example, add
my_scene_flow: /path/to/my_scene_flow.
- For example, add
- Define a new loader in
roco_spring_devkit.common.data.scene_flow_datamodule.py.- Add one input argument to
SceneFlowDataModule. The argument must be calledmy_scene_flow_dataset_root_dir, wheremy_scene_flowis the same name defined indatasets.yaml. - Add the new argument as a class variable:
self.my_scene_flow_dataset_root_dir = my_scene_flow_dataset_root_dir. - Create a new class method called
- Add one input argument to
def _get_my_scene_flow_dataset(self, is_train: bool, *args: str):
...
This method should return an instance of MySceneFlowDataset.
You can find more layout instructions and boilerplate code requirements in the PTLFlow Custom Dataset Guide.