Stereo Calibration
Calibrate stereo camera pairs for three-component (3C) velocity measurements. Two detection methods available: Dotboard and ChArUco.
Overview
Stereo calibration computes the geometric relationship between two cameras viewing the same measurement plane. The stereo model contains intrinsic parameters for each camera and extrinsic parameters (rotation and translation) describing their relative geometry.
| Method | Best For | Target Required |
|---|---|---|
| Stereo Dotboard | Standard stereo PIV setups | Circular dot grid, 10-20 positions |
| Stereo ChArUco | Partial target visibility, oblique angles | ChArUco board, multiple positions |
Quality Metrics
After calibration, review these metrics to assess quality.
| Metric | Description | Target |
|---|---|---|
| Stereo RMS Error | Overall stereo reprojection error (pixels) | < 0.5 px |
| Cam1 / Cam2 RMS Error | Per-camera reprojection error (pixels) | < 0.5 px each |
| Relative Angle | Angle between camera optical axes (degrees) | 30-60 degrees typical |
| Baseline Distance | Physical camera separation (mm) | Verify against setup |
Stereo Model Outputs
Intrinsic Parameters (per camera)
- Camera Matrix: fx, fy (focal length), cx, cy (principal point)
- Distortion: 5 radial/tangential coefficients
Extrinsic Parameters
- Rotation Matrix (R): 3x3 rotation from Cam1 to Cam2
- Translation Vector (T): Baseline offset
- Rectification: R1, R2, P1, P2, Q matrices
Calibration Image Setup
Stereo calibration requires synchronised images from both cameras at each target position. Image settings are shared with planar calibration.
Directory Structure
camera_first (default)
├── Cam1/
│ └── calibration/
│ └── calib_001.tif
└── Cam2/
└── calibration/
└── calib_001.tif
calibration_first
└── calibration/
├── Cam1/
│ └── calib_001.tif
└── Cam2/
└── calib_001.tif
LaVision IM7 files can contain both stereo cameras in a single file. Set use_camera_subfolders: false and PIVTools will extract each camera frame automatically.
Each image index must show the target at the same position for both cameras. Misaligned images produce incorrect stereo geometry.
Stereo Dotboard
Both cameras are calibrated simultaneously using shared views of a circular dot grid at multiple target positions. Uses the same optimised detection algorithm as planar dotboard (histogram-based blob detection, cKDTree neighbour search, RANSAC filtering).
Parameters
| Parameter | Description | Default |
|---|---|---|
| camera_pair | Camera numbers forming the stereo pair | [1, 2] |
| pattern_cols | Horizontal dot count | 10 |
| pattern_rows | Vertical dot count | 10 |
| dot_spacing_mm | Physical spacing between dot centres (mm) | 12.22 |
| asymmetric | Asymmetric grid pattern | false |
| dt | Time between frames (seconds) | 0.0057553 |
GUI Workflow
- 1Configure calibration images (format, count, subfolder)
- 2Set camera pair (e.g. Camera 1 and Camera 2)
- 3Set grid parameters (cols, rows, dot spacing)
- 4Browse images to verify both camera views show the target
- 5Click "Generate Model" to compute stereo calibration
- 6Review stereo RMS error, relative angle, and baseline distance
- 7Click "Calibrate Vectors" to apply calibration to PIV data
- 8Click "Set as Active" to make this the active method
Output Directory
├── model/stereo_model.mat
├── indices/indexing_*.mat
└── figures/
Validation: Stereo validation checks that images exist for both cameras and reports the matching count (minimum of frames found in each camera).
Stereo ChArUco
Combines ArUco marker detection with stereo geometry computation. ArUco markers identify which corners are visible, so detection works with partial occlusion and oblique viewing angles.
Parameters
| Parameter | Description | Default |
|---|---|---|
| camera_pair | Camera numbers forming the stereo pair | [1, 2] |
| squares_h | Horizontal square count | 10 |
| squares_v | Vertical square count | 9 |
| square_size | Square size in metres | 0.03 |
| marker_ratio | Marker size relative to square | 0.5 |
| aruco_dict | ArUco dictionary type | DICT_4X4_1000 |
| min_corners | Minimum corners to accept a frame | 6 |
| dt | Time between frames (seconds) | 0.0057553 |
ArUco Dictionaries
Available dictionaries: DICT_4X4, DICT_5X5, DICT_6X6, DICT_7X7 -- each with 50, 100, 250, or 1000 markers.
GUI Workflow
Same as Stereo Dotboard: configure images, set camera pair and board parameters, generate model, review quality metrics, apply to vectors, and set as active.
Shared board parameters: ChArUco board settings (squares_h, squares_v, etc.) are read from the calibration.charuco section, shared with the planar ChArUco method.
3D Velocity Reconstruction
After computing the stereo model, use reconstruction to convert the 2D PIV velocity fields from each camera into 3D velocity vectors (u, v, w) in world coordinates.
Process
2D PIV (Cam 1)
ux, uy in image plane
2D PIV (Cam 2)
ux, uy in image plane
3D Velocity
ux, uy, uz in world coords
Requirements
- Valid stereo calibration model
- 2D PIV vectors from Camera 1
- 2D PIV vectors from Camera 2
- Matching grid coordinates between cameras
Output Variables
- ux: x-velocity (m/s)
- uy: y-velocity (m/s)
- uz: out-of-plane velocity (m/s)
- x, y: world coordinates (mm)
GUI Workflow
- 1Ensure a stereo model has been generated (Dotboard or ChArUco)
- 2Run PIV processing for both cameras
- 3Select data type (instantaneous or ensemble)
- 4Click "Reconstruct 3D" to start reconstruction
- 5View reconstructed vectors in the Vector Viewer with the Stereo data source
Output Directory
├── B00001.mat ... B0NNNN.mat
└── coordinates.mat
Note: Reconstruction quality depends on stereo calibration accuracy and proper overlap between the PIV fields from both cameras.
Self-Calibration (Wieneke 2005)
Self-calibration automatically detects and corrects laser-sheet misalignment in stereo PIV setups. The laser sheet may be offset from the calibration plane (Z-offset) or tilted relative to it. Self-calibration measures the disparity between camera views and iteratively refines the dewarping parameters until the residual disparity converges.
Algorithm Steps
- 1Dewarp both camera images to a common reference plane using the existing stereo model
- 2Cross-correlate Camera 1 vs Camera 2 (same time instant, different viewpoints)
- 3Extract the disparity field -- residual displacement between the two dewarped views
- 4Fit the disparity to a plane model, extracting Z-offset and tilt angles
- 5Update the dewarping maps and repeat until RMS disparity converges
Parameters
| Parameter | Description | Default |
|---|---|---|
| n_images | Number of image pairs used for disparity estimation | 20 |
| window_size | Correlation window size (pixels) | 64 |
| overlap | Window overlap percentage | 50.0 |
| convergence_threshold | RMS disparity convergence target (pixels) | 0.05 |
Output Parameters
Estimated Parameters
- z_offset: Laser sheet Z-offset (mm)
- tilt_x: Tilt about X-axis (radians)
- tilt_y: Tilt about Y-axis (radians)
Quality Metrics
- RMS disparity: Residual disparity (pixels)
- Iteration count: Number of refinement iterations
- Convergence status: Whether threshold was reached
GUI Workflow
- 1Complete stereo calibration (Dotboard or ChArUco)
- 2Open the Self-Calibration panel below the stereo calibration section
- 3Preview the dewarp alignment (red-cyan overlay shows before/after)
- 4Set number of images and window size
- 5Click "Run Self-Calibration" to start the iterative process
- 6Review convergence history and final RMS disparity
- 7Results are automatically saved to config and applied during reconstruction
Note: Self-calibration results are automatically applied during 3D reconstruction. The corrected dewarping maps account for the measured Z-offset and tilt, eliminating systematic errors caused by laser-sheet misalignment.
Stereo Ensemble PIV
Stereo ensemble PIV combines correlation-of-correlations with stereo reconstruction to estimate all three velocity components (U, V, W) and the full 3D Reynolds stress tensor (6 components) from time-averaged data.
Requires a stereo camera pair and uses the stereo_ensemble_piv config section (falls back to ensemble_piv for unset keys).
Outputs
| Output | Description |
|---|---|
| ux, uy, uz | Time-averaged 3D velocity (m/s) |
| UU, VV, WW | Normal Reynolds stresses |
| UV, UW, VW | Shear Reynolds stresses |
CLI Usage
Stereo calibration uses two CLI steps: detect targets to generate a stereo model, then apply-stereo to reconstruct 3D velocities.
Step 1: Generate Stereo Model
# Dotboard stereo detection
pivtools-cli detect-stereo-planar
# ChArUco stereo detection
pivtools-cli detect-stereo-charuco
# Process specific paths
pivtools-cli detect-stereo-planar -p 0,1Step 2: Reconstruct 3D Velocity
# Use active settings from config.yaml
pivtools-cli apply-stereo
# Specify camera pair explicitly
pivtools-cli apply-stereo --camera-pair 1,2
# Use charuco stereo model
pivtools-cli apply-stereo --method charuco
# Specific data type and runs
pivtools-cli apply-stereo -t instantaneous -r 1,2,3
# Process specific paths
pivtools-cli apply-stereo -p 0,1Step 3: Self-Calibration (Optional)
# Run self-calibration to correct laser-sheet misalignment
pivtools-cli self-calibrate --camera-pair 1,2 --method dotboard --n-images 20apply-stereo Options
| Flag | Description | Default |
|---|---|---|
| --method, -m | Stereo method: dotboard or charuco | From config |
| --camera-pair, -c | Camera pair as "1,2" | From config |
| --type-name, -t | Data type (instantaneous / ensemble) | instantaneous |
| --runs, -r | Comma-separated run numbers | All runs |
| --active-paths, -p | Comma-separated path indices | From config |
Complete Workflow
# 1. Generate stereo calibration model
pivtools-cli detect-stereo-planar # or detect-stereo-charuco
# 2. Run PIV processing for both cameras
pivtools-cli instantaneous
# 3. Reconstruct 3D velocities
pivtools-cli apply-stereo --camera-pair 1,2
# 4. Compute statistics on stereo data
pivtools-cli statistics --source-endpoint stereoComplete YAML Reference
calibration:
# Active method
active: stereo_dotboard # stereo_dotboard or stereo_charuco
piv_type: instantaneous
# Calibration image settings (shared)
image_format: calib_%03d.tif
num_images: 15
image_type: standard
zero_based_indexing: false
use_camera_subfolders: true
subfolder: calibration
camera_subfolders: ["Cam1", "Cam2"]
path_order: camera_first
# Stereo Dotboard
stereo_dotboard:
camera_pair: [1, 2]
pattern_cols: 10
pattern_rows: 10
dot_spacing_mm: 12.2222
asymmetric: false
dt: 0.0057553
stereo_model_type: dotboard
# Stereo ChArUco (board params from charuco section)
stereo_charuco:
camera_pair: [1, 2]
dt: 0.0057553
# ChArUco board parameters (used by both planar and stereo)
charuco:
squares_h: 10
squares_v: 9
square_size: 0.03
marker_ratio: 0.5
aruco_dict: DICT_4X4_1000
min_corners: 6
# Self-calibration (Wieneke 2005)
self_calibration:
z_offset: 0.0 # Laser sheet Z-offset (mm)
tilt_x: 0.0 # Tilt about X-axis (radians)
tilt_y: 0.0 # Tilt about Y-axis (radians)
method: dotboard # Calibration method used for stereo model
n_images: 20 # Image pairs for disparity estimation
window_size: 64 # Correlation window (pixels)
convergence_history: [] # Per-iteration RMS disparity values
# Stereo Ensemble PIV
stereo_ensemble_piv:
# Inherits all settings from ensemble_piv
# Override specific settings here if needed
window_size:
- [128, 128]
- [64, 64]
- [32, 32]GUI to YAML Field Mapping
| GUI Control | YAML Field | Values |
|---|---|---|
| Active Method | calibration.active | stereo_dotboard or stereo_charuco |
| Camera 1 | *.camera_pair[0] | Integer (1-based) |
| Camera 2 | *.camera_pair[1] | Integer (1-based) |
| Pattern Columns | stereo_dotboard.pattern_cols | Integer |
| Pattern Rows | stereo_dotboard.pattern_rows | Integer |
| Dot Spacing (mm) | stereo_dotboard.dot_spacing_mm | Float (mm) |
| Squares H | charuco.squares_h | Integer |
| Squares V | charuco.squares_v | Integer |
| Square Size | charuco.square_size | Float (metres) |
| ArUco Dictionary | charuco.aruco_dict | DICT_{4-7}X{4-7}_{50-1000} |
| dt | stereo_dotboard.dt / stereo_charuco.dt | Float (seconds) |
Next: Create Visualisation Videos
Visualise your calibrated velocity fields with animated videos.
Continue to Video Maker