### Build C++ Example with System TensorRT Source: https://github.com/xiandaguo/openstereo/blob/v2/deploy/README.md Build the C++ deployment example using CMake and Make, assuming TensorRT is installed as a system library. ```bash cd /deploy/cpp mkdir build && cd build cmake .. && make ``` -------------------------------- ### Build C++ Example with TensorRT and CUDA Architecture Source: https://github.com/xiandaguo/openstereo/blob/v2/deploy/README.md Build the C++ deployment example, specifying both the TensorRT installation path and the CUDA architecture for compilation. ```bash cmake -DTENSORRT_ROOT= -DCMAKE_CUDA_ARCHITECTURES= .. && make ``` -------------------------------- ### Install Project Dependencies Source: https://github.com/xiandaguo/openstereo/blob/v2/docs/0.get_started.md Install all other project dependencies listed in the requirements.txt file using pip. ```bash pip install -r requirements.txt ``` -------------------------------- ### Install C++ Dependencies Source: https://github.com/xiandaguo/openstereo/blob/v2/deploy/README.md Install necessary system libraries for C++ deployment, including YAML-CPP and OpenCV. ```bash apt-get update apt-get install libyaml-cpp-dev libopencv-dev python3-opencv ``` -------------------------------- ### Install FoundationStereo Environment Source: https://github.com/xiandaguo/openstereo/blob/v2/docs/prepare_foundationstereo.md Use these commands to create and activate the conda environment for FoundationStereo and install the flash-attn package. ```bash 1. conda env create -f [environment.yml](https://github.com/NVlabs/FoundationStereo/blob/master/environment.yml) 2. conda run -n foundation_stereo pip install flash-attn 3. conda activate foundation_stereo ``` -------------------------------- ### Build C++ Example with TensorRT Tar Package Source: https://github.com/xiandaguo/openstereo/blob/v2/deploy/README.md Build the C++ deployment example using CMake and Make, specifying the path to a downloaded TensorRT tar package. ```bash cmake -DTENSORRT_ROOT= .. && make ``` -------------------------------- ### Train Model with Single GPU Source: https://github.com/xiandaguo/openstereo/blob/v2/docs/0.get_started.md Start training a model using a single GPU with the specified configuration file. ```bash python tools/train.py --cfg_file cfgs/lightstereo/lightstereo_s_sceneflow.yaml ``` -------------------------------- ### Dataset Path Configuration Example Source: https://context7.com/xiandaguo/openstereo/llms.txt Python code snippet defining the dataset path configuration. This file needs to be updated to point to the local dataset locations before training. ```python ``` -------------------------------- ### YAML Configuration Example for LightStereo Source: https://context7.com/xiandaguo/openstereo/llms.txt A complete YAML configuration file for the LightStereo model, defining dataset paths, transformations, model architecture, optimization settings, and evaluation metrics. This file drives the entire training and evaluation pipeline. ```yaml # cfgs/lightstereo/lightstereo_l_sceneflow.yaml — complete working example DATA_CONFIG: DATA_INFOS: - DATASET: SceneFlowDataset DATA_SPLIT: TRAINING: ./data/SceneFlow/sceneflow_finalpass_train.txt EVALUATING: ./data/SceneFlow/sceneflow_finalpass_test.txt TESTING: ./data/SceneFlow/sceneflow_finalpass_test.txt RETURN_RIGHT_DISP: false DATA_TRANSFORM: TRAINING: - { NAME: RandomCrop, SIZE: [320, 736], Y_JITTER: false } - { NAME: TransposeImage } - { NAME: ToTensor } - { NAME: NormalizeImage, MEAN: [0.485, 0.456, 0.406], STD: [0.229, 0.224, 0.225] } EVALUATING: - { NAME: RightTopPad, SIZE: [544, 960] } - { NAME: TransposeImage } - { NAME: ToTensor } - { NAME: NormalizeImage, MEAN: [0.485, 0.456, 0.406], STD: [0.229, 0.224, 0.225] } MODEL: NAME: LightStereo # must match key in stereo/modeling/__init__.py MAX_DISP: 192 EXPANSE_RATIO: 8 AGGREGATION_BLOCKS: [8, 16, 32] LEFT_ATT: true FIND_UNUSED_PARAMETERS: false CKPT: -1 # -1 = fresh start; N = resume from epoch N PRETRAINED_MODEL: '' # path to pretrained weights for fine-tuning OPTIMIZATION: BATCH_SIZE_PER_GPU: 8 FREEZE_BN: false SYNC_BN: true AMP: true # enable float16 Auto Mixed Precision NUM_EPOCHS: 90 OPTIMIZER: NAME: AdamW LR: &lr 0.0008 WEIGHT_DECAY: 1.0e-05 EPS: 1.0e-08 SCHEDULER: NAME: OneCycleLR MAX_LR: *lr PCT_START: 0.01 ON_EPOCH: false # step per iteration, not per epoch CLIP_GRAD: TYPE: value CLIP_VALUE: 0.1 EVALUATOR: BATCH_SIZE_PER_GPU: 12 MAX_DISP: 192 METRIC: - d1_all # KITTI D1 metric (%) - epe # End-Point Error (pixels) - thres_1 # % pixels with |error| > 1px - thres_2 # % pixels with |error| > 2px - thres_3 # % pixels with |error| > 3px TRAINER: EVAL_INTERVAL: 1 # evaluate every N epochs CKPT_SAVE_INTERVAL: 1 MAX_CKPT_SAVE_NUM: 30 LOGGER_ITER_INTERVAL: 10 TRAIN_VISUALIZATION: true EVAL_VISUALIZATION: true ``` -------------------------------- ### Install PyTorch with CUDA Support Source: https://github.com/xiandaguo/openstereo/blob/v2/docs/0.get_started.md Install PyTorch version 1.13.1 with torchvision and torchaudio, including CUDA 11.7 support, using Anaconda. ```bash conda install pytorch==1.13.1 torchvision==0.14.1 torchaudio==0.13.1 pytorch-cuda=11.7 -c pytorch -c nvidia ``` -------------------------------- ### Define Custom Trainer for PSMNet Source: https://github.com/xiandaguo/openstereo/blob/v2/docs/5.advanced_usages.md Inherit from TrainerTemplate to create a custom trainer. This example shows how to initialize the PSMNet model within a custom trainer class. ```python from stereo.modeling.trainer_template import TrainerTemplate from .psmnet import PSMNet __all__ = { 'PSMNet': PSMNet, } class Trainer(TrainerTemplate): def __init__(self, args, cfgs, local_rank, global_rank, logger, tb_writer): model = __all__[cfgs.MODEL.NAME](cfgs.MODEL) super().__init__(args, cfgs, local_rank, global_rank, logger, tb_writer, model) ``` -------------------------------- ### Save and Load Model Checkpoints Source: https://context7.com/xiandaguo/openstereo/llms.txt Utilities for saving and loading model checkpoints, supporting single-GPU and DDP, and various checkpoint formats. Ensure correct parameters like `is_dist` and `strict` are set based on your training setup. ```python from stereo.utils.common_utils import save_checkpoint, load_params_from_file import torch # --- Saving --- save_checkpoint( model=model, # nn.Module or DDP-wrapped module optimizer=optimizer, scheduler=scheduler, scaler=scaler, # GradScaler for AMP is_dist=True, # True if DDP, saves model.module.state_dict() epoch=42, filename='./output/ckpt/checkpoint_epoch_42.pth' ) # Saves: {'epoch': 42, 'model_state': ..., 'optimizer_state': ..., # 'scheduler_state': ..., 'scaler_state': ...} # --- Loading --- logger = ... load_params_from_file( model=model, filename='./output/ckpt/checkpoint_epoch_42.pth', device='cuda:0', dist_mode=False, logger=logger, strict=False # False = partial loading (skips shape mismatches) ) # Handles OpenStereo checkpoints: key 'model_state' # Handles FoundationStereo style: key 'model' # Handles MonSter style: raw state_dict (no wrapper key) # Handles DDP checkpoints: strips 'module.' prefix automatically # Logs: unused weights (shape mismatch) and not-updated weights (missing keys) ``` -------------------------------- ### Generate KITTI Submission Files Source: https://context7.com/xiandaguo/openstereo/llms.txt Use `test_kitti.py` to generate disparity PNG files in the KITTI submission format. These files are scaled by 256 and are suitable for upload to the online leaderboard. Two examples are provided for KITTI15 and KITTI12. ```bash # Generate KITTI15 submission files python tools/test_kitti.py \ --pretrained_model output/KittiDataset/PSMNet/psmnet_kitti15/default/ckpt/checkpoint_epoch_0.pth \ --data_cfg_file cfgs/kitti15_eval.yaml ``` ```bash # Generate KITTI12 submission files python tools/test_kitti.py \ --pretrained_model output/KittiDataset/LightStereo/lightstereo_l_kitti/default/ckpt/checkpoint_epoch_49.pth \ --data_cfg_file cfgs/kitti12_eval.yaml ``` -------------------------------- ### Train FoundationStereo on SceneFlow Source: https://github.com/xiandaguo/openstereo/blob/v2/docs/prepare_foundationstereo.md Launch the training process for FoundationStereo on the SceneFlow dataset using distributed training. Ensure CUDA_VISIBLE_DEVICES is set correctly. ```bash export CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 torchrun --nnodes=1 --nproc_per_node=8 --rdzv_backend=c10d --rdzv_endpoint=localhost:23456 tools/train.py --dist_mode --cfg_file cfgs/foundationstereo/foundationstereo_sceneflow ``` -------------------------------- ### Export Script Help Source: https://github.com/xiandaguo/openstereo/blob/v2/deploy/README.md Display help information for the model export script to understand all available options. ```bash python deploy/export.py -h ``` -------------------------------- ### Instantiate and Use LightStereo Model Source: https://context7.com/xiandaguo/openstereo/llms.txt Instantiate the LightStereo model with a configuration dictionary and move it to CUDA. The model can be used for inference in evaluation mode or for training, where it returns auxiliary outputs for loss calculation. ```python import torch from easydict import EasyDict from stereo.modeling.models.lightstereo.lightstereo import LightStereo model_cfg = EasyDict({ 'MAX_DISP': 192, 'LEFT_ATT': True, 'AGGREGATION_BLOCKS': [8, 16, 32], 'EXPANSE_RATIO': 8, 'BACKBONE': 'MobileNetv2', # default if not specified }) model = LightStereo(model_cfg).cuda() # Inference model.eval() with torch.no_grad(): batch = { 'left': torch.randn(1, 3, 544, 960).cuda(), # normalized 'right': torch.randn(1, 3, 544, 960).cuda(), } output = model(batch) # output['disp_pred']: torch.Tensor [1, 1, 544, 960] — final disparity # Training forward pass (returns auxiliary outputs for loss) model.train() batch_train = { 'left': torch.randn(2, 3, 320, 736).cuda(), 'right': torch.randn(2, 3, 320, 736).cuda(), 'disp': torch.rand(2, 320, 736).cuda() * 192, # ground truth } preds = model(batch_train) # preds['disp_pred']: [2, 1, 320, 736] # preds['disp_4']: [2, 1, 320, 736] (low-res auxiliary) loss, loss_info = model.get_loss(preds, batch_train) # loss_info = {'scalar/train/loss_disp': 1.23} — used by TensorBoard writer loss.backward() ``` -------------------------------- ### LightStereo Model Usage Source: https://context7.com/xiandaguo/openstereo/llms.txt Demonstrates how to instantiate, perform inference with, and train the LightStereo model, including its standard forward and get_loss interfaces. ```APIDOC ## LightStereo Model ### Description One of OpenStereo's own models (ICRA 2025), implementing efficient 2D cost aggregation with a channel-boost backbone. Demonstrates the standard `forward` / `get_loss` interface. ### Instantiation ```python import torch from easydict import EasyDict from stereo.modeling.models.lightstereo.lightstereo import LightStereo model_cfg = EasyDict({ 'MAX_DISP': 192, 'LEFT_ATT': True, 'AGGREGATION_BLOCKS': [8, 16, 32], 'EXPANSE_RATIO': 8, 'BACKBONE': 'MobileNetv2', }) model = LightStereo(model_cfg).cuda() ``` ### Inference ```python model.eval() with torch.no_grad(): batch = { 'left': torch.randn(1, 3, 544, 960).cuda(), # normalized 'right': torch.randn(1, 3, 544, 960).cuda(), } output = model(batch) # output['disp_pred']: torch.Tensor [1, 1, 544, 960] — final disparity ``` ### Training Forward Pass ```python model.train() batch_train = { 'left': torch.randn(2, 3, 320, 736).cuda(), 'right': torch.randn(2, 3, 320, 736).cuda(), 'disp': torch.rand(2, 320, 736).cuda() * 192, # ground truth } preds = model(batch_train) # preds['disp_pred']: [2, 1, 320, 736] # preds['disp_4']: [2, 1, 320, 736] (low-res auxiliary) loss, loss_info = model.get_loss(preds, batch_train) # loss_info = {'scalar/train/loss_disp': 1.23} — used by TensorBoard writer loss.backward() ``` ``` -------------------------------- ### Build Dynamic Transform Pipelines from Configuration Source: https://context7.com/xiandaguo/openstereo/llms.txt Dynamically constructs augmentation and preprocessing pipelines for datasets using `build_transform_by_cfg`. Accepts a list of EasyDict configurations specifying transform names and parameters. ```python from stereo.datasets.dataset_template import DatasetTemplate, build_transform_by_cfg from easydict import EasyDict # Dynamically build a transform pipeline from config transform_config = [ EasyDict({'NAME': 'RandomCrop', 'SIZE': [320, 736], 'Y_JITTER': False}), EasyDict({'NAME': 'TransposeImage'}) EasyDict({'NAME': 'ToTensor'}), EasyDict({'NAME': 'NormalizeImage', 'MEAN': [0.485, 0.456, 0.406], 'STD': [0.229, 0.224, 0.225]}), ] transform = build_transform_by_cfg(transform_config) ``` -------------------------------- ### Utility Functions Source: https://context7.com/xiandaguo/openstereo/llms.txt Provides core utilities for configuration loading, logger creation, random seed fixing, and TensorBoard integration. ```APIDOC ## Utility Functions ### Description Core utilities for config loading, logger creation, random seed fixing, and TensorBoard integration. ### Load YAML Config ```python from stereo.utils.common_utils import config_loader from easydict import EasyDict cfgs = EasyDict(config_loader('cfgs/lightstereo/lightstereo_l_sceneflow.yaml')) print(cfgs.MODEL.NAME) # 'LightStereo' print(cfgs.OPTIMIZATION.AMP) # True ``` ### Set Random Seed ```python from stereo.utils.common_utils import set_random_seed set_random_seed(seed=42) # Sets: random, numpy, torch manual seeds + cudnn.deterministic=True, benchmark=False ``` ### Create Logger ```python from stereo.utils.common_utils import create_logger import logging logger = create_logger(log_file='./output/train.log', rank=0) logger.info('Training started') # 2024-01-01 12:00:00 INFO Training started ``` ### Log Configurations ```python from stereo.utils.common_utils import log_configs from easydict import EasyDict # Assuming cfgs is loaded as shown in 'Load YAML Config' # cfgs = EasyDict(config_loader('cfgs/lightstereo/lightstereo_l_sceneflow.yaml')) # logger = create_logger(log_file='./output/train.log', rank=0) log_configs(cfgs, logger=logger) # 2024-01-01 12:00:00 INFO ----------- DATA_CONFIG ----------- # 2024-01-01 12:00:00 INFO cfgs.DATA_CONFIG.DATA_INFOS: [...] # ... ``` ``` -------------------------------- ### Evaluate FoundationStereo Model Source: https://github.com/xiandaguo/openstereo/blob/v2/docs/prepare_foundationstereo.md Run the evaluation script for FoundationStereo using specified configuration and pre-trained model paths. ```bash python tools/eval.py --cfg_file cfgs/foundationstereo/foundationstereo_sceneflow --eval_data_cfg_file cfgs/sceneflow_eval.yaml --pretrained_model your_pretrained_ckpt_path ``` -------------------------------- ### Multi-GPU Training on Single Node Source: https://github.com/xiandaguo/openstereo/blob/v2/docs/0.get_started.md Configure and launch multi-GPU training on a single node using torchrun. Ensure CUDA_VISIBLE_DEVICES is set appropriately. ```bash export CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 torchrun --nnodes=1 --nproc_per_node=8 --rdzv_backend=c10d --rdzv_endpoint=localhost:23456 tools/train.py --dist_mode --cfg_file cfgs/lightstereo/lightstereo_s_sceneflow.yaml ``` -------------------------------- ### Create Conda Environment Source: https://github.com/xiandaguo/openstereo/blob/v2/docs/0.get_started.md Create a new conda environment named 'openstereo' with Python 3.8. ```bash conda create -n openstereo python=3.8 ``` -------------------------------- ### Implement Custom Dataset with DatasetTemplate Source: https://context7.com/xiandaguo/openstereo/llms.txt Extend DatasetTemplate to create a custom dataset by overriding __init__ and __getitem__. Ensure data paths are correctly joined and images are loaded and converted to NumPy arrays. The transform method is applied to the sample before returning. ```python from stereo.datasets.dataset_template import DatasetTemplate import numpy as np from PIL import Image import os class MyCustomDataset(DatasetTemplate): def __init__(self, data_info, data_cfg, mode='training'): super().__init__(data_info, data_cfg, mode) def __getitem__(self, idx): # self.data_list[idx] = line from split .txt file split by spaces item = self.data_list[idx] left_path = os.path.join(self.root, item[0]) right_path = os.path.join(self.root, item[1]) disp_path = os.path.join(self.root, item[2]) left = np.array(Image.open(left_path).convert('RGB'), dtype=np.float32) right = np.array(Image.open(right_path).convert('RGB'), dtype=np.float32) disp = np.array(Image.open(disp_path), dtype=np.float32) / 256.0 sample = {'left': left, 'right': right, 'disp': disp} return self.transform(sample) # applies transforms defined in YAML ``` -------------------------------- ### Train a Model with OpenStereo Source: https://context7.com/xiandaguo/openstereo/llms.txt Use `tools/train.py` to train stereo matching models. Supports single-GPU, multi-GPU DDP, and resuming from checkpoints. Configuration is managed via YAML files. ```bash python tools/train.py --cfg_file cfgs/lightstereo/lightstereo_l_sceneflow.yaml ``` ```bash export CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 torchrun \ --nnodes=1 \ --nproc_per_node=8 \ --rdzv_backend=c10d \ --rdzv_endpoint=localhost:23456 \ tools/train.py \ --dist_mode \ --fix_random_seed \ --cfg_file cfgs/lightstereo/lightstereo_l_sceneflow.yaml \ --save_root_dir ./output \ --extra_tag experiment_v1 ``` ```bash # In cfgs/lightstereo/lightstereo_l_sceneflow.yaml, set: CKPT: 10 python tools/train.py --cfg_file cfgs/lightstereo/lightstereo_l_sceneflow.yaml ``` -------------------------------- ### Submit to KITTI Leaderboard Source: https://github.com/xiandaguo/openstereo/blob/v2/docs/0.get_started.md Generate test results for submission to the KITTI leaderboard. Specify the path to your trained model and the appropriate configuration file. ```bash python tools/test_kitti.py --pretrained_model Your_model_path --cfg_file cfgs/kitti12_eval.yaml python tools/test_kitti.py --pretrained_model Your_model_path --cfg_file cfgs/kitti15_eval.yaml ``` -------------------------------- ### Infer with LightStereo Source: https://context7.com/xiandaguo/openstereo/llms.txt Run inference using the LightStereo model. Specify paths to configuration, input images, and pretrained weights. The output is a colorized disparity map. ```bash python tools/infer.py \ --cfg_file cfgs/lightstereo/lightstereo_l_sceneflow.yaml \ --left_img_path /data/kitti/left/000001_10.png \ --right_img_path /data/kitti/right/000001_10.png \ --pretrained_model /path/to/lightstereo_l.pth \ --savename ./kitti_disp.png ``` -------------------------------- ### Configure Data Paths Source: https://context7.com/xiandaguo/openstereo/llms.txt Define local storage paths for various stereo datasets. Modify these paths to match your system's directory structure. ```python DATA_PATH_DICT = { 'SceneFlowDataset': '/data/SceneFlow', 'FlyingThings3DSubsetDataset': '/data/SceneFlow', 'KittiDataset12': '/data/stereo/kitti12', 'KittiDataset15': '/data/stereo/kitti15', 'DrivingDataset': '/data/DrivingStereo', 'MiddleburyDataset': '/data/stereo/Middlebury', 'ETH3DDataset': '/data/stereo/eth3d', 'ArgoverseDataset': '/data/stereo/argoverse', 'CREStereoDataset': '/data/stereo/CREStereoData', 'FallingThingsDataset': '/data/stereo/FallingThings', 'InStereo2KDataset': '/data/stereo/InStereo2K', 'SintelDataset': '/data/stereo/Sintel', 'TartanAirDataset': '/data/stereo/tartanair', 'SpringDataset': '/data/stereo/spring', 'VirtualKitti2Dataset': '/data/stereo/virtualkitti2', 'UnrealStereo4KDataset': '/data/stereo/UnrealStereo4K', 'CarlaDataset': '/data/stereo/StereoFromCarlaV2', 'FoundationStereoDataset': '/data/stereo/foundationstereo', 'DynamicReplicaDataset': '/data/stereo/dynamic_stereo', } ``` -------------------------------- ### Build NMRF-Stereo Operators Source: https://github.com/xiandaguo/openstereo/blob/v2/docs/0.get_started.md Build the deformable attention and superpixel-guided disparity downsample operators required for NMRF-Stereo training/evaluation. Ensure you are in the correct directory before running. ```bash cd stereo/modeling/models/nmrf/ops && sh make.sh && cd .. ``` -------------------------------- ### Generalization Evaluation Source: https://github.com/xiandaguo/openstereo/blob/v2/docs/0.get_started.md Perform generalization evaluation on various benchmark datasets like ETH3D, Middlebury, and KITTI. Ensure the correct evaluation data config file and pre-trained model path are provided. ```bash python tools/eval.py --cfg_file cfgs/lightstereo/lightstereo_s_sceneflow.yaml --eval_data_cfg_file cfgs/eth3d_eval.yaml --pretrained_model your_pretrained_ckpt_path python tools/eval.py --cfg_file cfgs/lightstereo/lightstereo_s_sceneflow.yaml --eval_data_cfg_file cfgs/middlebury_eval.yaml --pretrained_model your_pretrained_ckpt_path python tools/eval.py --cfg_file cfgs/lightstereo/lightstereo_s_sceneflow.yaml --eval_data_cfg_file cfgs/kitti15_eval.yaml --pretrained_model your_pretrained_ckpt_path python tools/eval.py --cfg_file cfgs/lightstereo/lightstereo_s_sceneflow.yaml --eval_data_cfg_file cfgs/kitti12_eval.yaml --pretrained_model your_pretrained_ckpt_path python tools/eval.py --cfg_file cfgs/lightstereo/lightstereo_s_sceneflow.yaml --eval_data_cfg_file cfgs/driving_eval.yaml --pretrained_model your_pretrained_ckpt_path ``` -------------------------------- ### Clone the OpenStereo Repository Source: https://github.com/xiandaguo/openstereo/blob/v2/docs/0.get_started.md Clone the OpenStereo repository from GitHub to your local machine. ```bash https://github.com/XiandaGuo/OpenStereo ``` -------------------------------- ### Evaluate a Pretrained Model with OpenStereo Source: https://context7.com/xiandaguo/openstereo/llms.txt Use `tools/eval.py` to evaluate trained stereo matching models on various datasets. Supports DDP evaluation and overriding dataset configurations. ```bash python tools/eval.py \ --cfg_file cfgs/lightstereo/lightstereo_l_sceneflow.yaml \ --pretrained_model ./output/SceneFlowDataset/LightStereo/lightstereo_l_sceneflow/default/ckpt/checkpoint_epoch_89.pth ``` ```bash python tools/eval.py \ --cfg_file cfgs/lightstereo/lightstereo_l_sceneflow.yaml \ --eval_data_cfg_file cfgs/kitti15_eval.yaml \ --pretrained_model ./output/SceneFlowDataset/LightStereo/lightstereo_l_sceneflow/default/ckpt/checkpoint_epoch_89.pth ``` ```bash python tools/eval.py \ --cfg_file cfgs/lightstereo/lightstereo_l_sceneflow.yaml \ --eval_data_cfg_file cfgs/eth3d_eval.yaml \ --pretrained_model /path/to/checkpoint.pth ``` ```bash python tools/eval.py \ --cfg_file cfgs/lightstereo/lightstereo_l_sceneflow.yaml \ --eval_data_cfg_file cfgs/middlebury_eval.yaml \ --pretrained_model /path/to/checkpoint.pth ``` ```bash python tools/eval.py \ --cfg_file cfgs/nmrf/nmrf_swint_sceneflow_uniform.yaml \ --eval_data_cfg_file cfgs/nmrf/kitti12_eval_nmrf.yaml \ --pretrained_model /path/to/StereoAnything-NMRF_swinT.bin ``` -------------------------------- ### Create Custom Model Trainer Source: https://github.com/xiandaguo/openstereo/blob/v2/docs/4.how_to_create_your_model.md Create a trainer class by inheriting from TrainerTemplate. Instantiate your custom model and pass it to the superclass constructor. Register your model in the __all__ dictionary. ```python from stereo.modeling.trainer_template import TrainerTemplate from .newmodel import newmodel __all__ = { 'newmodel': newmodel, } class Trainer(TrainerTemplate): def __init__(self, args, cfgs, local_rank, global_rank, logger, tb_writer): model = __all__[cfgs.MODEL.NAME](cfgs.MODEL) super().__init__(args, cfgs, local_rank, global_rank, logger, tb_writer, model) ``` -------------------------------- ### Create a Rank-Aware Logger Source: https://context7.com/xiandaguo/openstereo/llms.txt Create a logger instance using create_logger, which supports distributed training by logging only on rank 0. Specify a log file path and the current process rank. Log messages can be written using standard logger methods. ```python from stereo.utils.common_utils import ( config_loader, set_random_seed, create_logger, log_configs ) from easydict import EasyDict import logging # Create a rank-aware logger (only rank 0 logs at INFO level) logger = create_logger(log_file='./output/train.log', rank=0) logger.info('Training started') # 2024-01-01 12:00:00 INFO Training started ``` -------------------------------- ### Load Configuration with config_loader Source: https://context7.com/xiandaguo/openstereo/llms.txt Load YAML configuration files into EasyDict objects using config_loader. This utility is useful for managing model and training parameters. Access configuration values using dot notation. ```python from stereo.utils.common_utils import ( config_loader, set_random_seed, create_logger, log_configs ) from easydict import EasyDict # Load YAML config into EasyDict cfgs = EasyDict(config_loader('cfgs/lightstereo/lightstereo_l_sceneflow.yaml')) print(cfgs.MODEL.NAME) # 'LightStereo' print(cfgs.OPTIMIZATION.AMP) # True ``` -------------------------------- ### Custom Model Implementation Source: https://context7.com/xiandaguo/openstereo/llms.txt Integrate new models by implementing an nn.Module subclass and a corresponding Trainer class. The `forward` method should return predictions, and `get_loss` calculates the training loss. ```python # stereo/modeling/models/mymodel/mymodel.py import torch.nn as nn import torch.nn.functional as F class MyModel(nn.Module): def __init__(self, cfgs): super().__init__() self.max_disp = cfgs.MAX_DISP # build your layers here def forward(self, input_data): # input_data['left']: [B, 3, H, W] float32 normalized tensor # input_data['right']: [B, 3, H, W] float32 normalized tensor left = input_data['left'] right = input_data['right'] disp_pred = ... # shape: [B, 1, H, W] result = {'disp_pred': disp_pred} if self.training: result['disp_aux'] = ... # optional auxiliary output for loss return result def get_loss(self, model_preds, input_data): disp_gt = input_data['disp'].unsqueeze(1) # [B, 1, H, W] disp_pred = model_preds['disp_pred'] # [B, 1, H, W] mask = (disp_gt < self.max_disp) & (disp_gt > 0) loss = F.smooth_l1_loss(disp_pred[mask], disp_gt[mask], reduction='mean') loss_info = {'scalar/train/loss_disp': loss.item()} return loss, loss_info ``` ```python # stereo/modeling/models/mymodel/trainer.py from stereo.modeling.trainer_template import TrainerTemplate from .mymodel import MyModel __all__ = {'MyModel': MyModel} class Trainer(TrainerTemplate): def __init__(self, args, cfgs, local_rank, global_rank, logger, tb_writer): model = __all__[cfgs.MODEL.NAME](cfgs.MODEL) super().__init__(args, cfgs, local_rank, global_rank, logger, tb_writer, model) ``` ```python # Register in stereo/modeling/__init__.py: from .models.mymodel.trainer import Trainer as MyModelTrainer __all__['MyModel'] = MyModelTrainer ``` ```yaml # Config YAML: # MODEL: # NAME: MyModel # MAX_DISP: 192 # CUSTOM_PARAM: value ``` -------------------------------- ### Build Trainer Factory Source: https://context7.com/xiandaguo/openstereo/llms.txt Instantiate the correct Trainer class for a given model name using the registry. This factory function configures and returns a trainer ready for training or evaluation. ```python # stereo/modeling/__init__.py from stereo.modeling import build_trainer from stereo.utils import common_utils from easydict import EasyDict # Load config cfgs = EasyDict(common_utils.config_loader('cfgs/psmnet/psmnet_sceneflow.yaml')) # Supported MODEL.NAME values and their trainers: # 'PSMNet' -> PSMNetTrainer # 'IGEV' -> IGEVTrainer # 'IGEVPP' -> IGEVPPTrainer # 'IGEVRT' -> IGEVRTTrainer # 'LightStereo' -> LightStereoTrainer # 'StereoBaseGRU' -> StereoBaseGRUTrainer # 'FoundationStereo' -> FoundationStereoTrainer # 'FastFoundationStereo' -> FastFoundationStereoTrainer # 'MonSter' -> MonsterTrainer # 'GwcNet' -> GwcNetTrainer # 'FADNet' -> FADNetTrainer # 'CoExNet' -> CoExTrainer # 'CFNet' -> CFNetTrainer # 'CasGwcNet' -> CasStereoTrainer # 'CasPSMNet' -> CasStereoTrainer # 'MSNet2D' / 'MSNet3D'-> MSNetTrainer # 'STTR' -> STTRTrainer import logging, torch logger = logging.getLogger(__name__) trainer = build_trainer(args, cfgs, local_rank=0, global_rank=0, logger=logger, tb_writer=None) # trainer.model — the nn.Module # trainer.train(epoch, tbar) # trainer.evaluate(current_epoch) # trainer.save_ckpt(epoch) ``` -------------------------------- ### Log Configuration Tree Source: https://context7.com/xiandaguo/openstereo/llms.txt Log the entire configuration tree using log_configs, which is helpful for debugging and understanding the active settings. This function takes the configuration object and a logger instance as input. ```python from stereo.utils.common_utils import ( config_loader, set_random_seed, create_logger, log_configs ) from easydict import EasyDict import logging # Log entire config tree log_configs(cfgs, logger=logger) # 2024-01-01 12:00:00 INFO ----------- DATA_CONFIG ----------- # 2024-01-01 12:00:00 INFO cfgs.DATA_CONFIG.DATA_INFOS: [...] ``` -------------------------------- ### Write TensorBoard Logs Source: https://context7.com/xiandaguo/openstereo/llms.txt Use this utility to write scalar data to TensorBoard for monitoring training progress. Ensure SummaryWriter is initialized. ```python from stereo.utils.common_utils import write_tensorboard from torch.utils.tensorboard import SummaryWriter tb_writer = SummaryWriter('./output/tensorboard') tb_info = { 'scalar/train/loss_disp': torch.tensor(0.456), 'scalar/train/lr': torch.tensor(0.0008), } write_tensorboard(tb_writer, tb_info, step=1000) ``` -------------------------------- ### Run Inference on an Image Pair with OpenStereo Source: https://context7.com/xiandaguo/openstereo/llms.txt Use `tools/infer.py` to run a trained model on a stereo image pair and generate a colorized disparity map. Evaluation transforms are applied automatically based on the config. ```bash python tools/infer.py \ --cfg_file cfgs/psmnet/psmnet_sceneflow.yaml \ --left_img_path /data/stereo/left.png \ --right_img_path /data/stereo/right.png \ --pretrained_model /path/to/psmnet_checkpoint.pth \ --savename ./disparity_output.png ``` -------------------------------- ### Export ONNX Model Source: https://github.com/xiandaguo/openstereo/blob/v2/deploy/README.md Use this script to convert model checkpoints to ONNX format. Specify the configuration, weights, device, and desired optimizations. ```bash python deploy/export.py --config cfgs/psmnet/psmnet_kitti15.yaml --weights output/KittiDataset/PSMNet/psmnet_kitti15/default/ckpt/checkpoint_epoch_0.pth --device 0 --simplify --half --include onnx ```