PIV Processing

Configure multi-pass cross-correlation for instantaneous frame-pair or ensemble correlation averaging analysis.

Overview

PIVTools supports two distinct processing modes, each suited for different experimental scenarios. Choose the mode that best matches your analysis requirements.

Instantaneous PIV

Processes individual frame pairs to produce velocity fields for each time step. Ideal for time-resolved analysis and turbulent flow statistics.

Per-frame velocity vectors
Temporal statistics (mean, RMS, Reynolds stresses)
Live progress preview during processing
Peak finder algorithm selection

Ensemble PIV

Averages correlation planes across all frame pairs before peak detection. Produces high-fidelity mean flow fields with reduced noise.

Mean flow field only (no individual frames)
Higher spatial resolution with single mode
Resume processing from saved passes
Diagnostic plane storage for inspection

When to Use Each Mode

Use Instantaneous when:

  • You need time-resolved velocity data
  • Computing turbulence statistics
  • Analysing unsteady/transient flows
  • Good particle seeding density

Use Ensemble when:

  • Only mean flow is needed
  • Low particle seeding density
  • Maximum spatial resolution required
  • Noisy or challenging image conditions

Window Configuration

Both processing modes use multi-pass refinement with configurable interrogation windows. Each pass uses the results of the previous pass to improve vector accuracy.

Multi-Pass Strategy

  • Window Size: The interrogation window dimensions in pixels [Height, Width]. Larger windows capture more particles but reduce spatial resolution.
  • Overlap: Percentage of window overlap between adjacent vectors. 50% overlap doubles the vector grid density.
  • Store Flag: Toggle to save intermediate pass results. The final pass is always stored.
  • Pass Order: Processing starts with large windows and progressively refines to smaller windows for accuracy.

Rectangular (Non-Square) Windows

The Height and Width of interrogation windows can be specified independently, allowing for rectangular (non-square) windows. Window size uses row-major convention: [Height, Width] where Height is the vertical (Y) dimension and Width is the horizontal (X) dimension.

When to use rectangular windows:
  • Flow predominantly in one direction
  • Anisotropic particle seeding density
  • Higher spatial resolution needed in one direction
  • Matching window shape to expected displacement
Example configurations:
  • [64, 64] — Square window (standard)
  • [32, 64] — Wide window (horizontal flow)
  • [64, 32] — Tall window (vertical flow)
  • [32, 128] — Wide: large X displacement, high Y resolution
Key considerations:
  • Dimension order: Always [Height, Width] — Height is vertical (Y), Width is horizontal (X)
  • Grid density: More vectors in the direction with the smaller dimension
  • Displacement limits: First pass allows displacements up to window_size/2 in each direction
  • Overlap: Applied as percentage of each dimension independently
Instantaneous

Window Setup

Configure passes in the GUI using the pass table. Each row represents one refinement pass.

Height (Y)
Width (X)
Overlap %
Store
Actions
Pass #
128
128
50
Pass 1
64
64
50
Pass 2
32
32
50
Pass 3
Add Pass
config.yaml
instantaneous_piv: window_size: # Format: [Height, Width] in pixels - [128, 128] # Pass 1: Large windows for initial estimate - [64, 64] # Pass 2: Medium refinement - [32, 32] # Pass 3: Final high-resolution overlap: - 50 # 50% overlap for all passes - 50 - 50 runs: - 3 # Save final pass (pass 3)
Ensemble

Window Setup with Pass Types

Ensemble mode adds a Type column to select between standard and single correlation modes.

Height (Y)
Width (X)
Overlap %
Type
Store
Actions
Pass
128
128
50
Standard
1
64
64
50
Standard
2
16
16
50
Single
3
Standard (std)

Both Frame A and Frame B use identical window weighting. Standard cross-correlation at the specified window size.

Single

Asymmetric weighting for higher spatial resolution. Requires sum_window configuration. See next section for details.

config.yaml
ensemble_piv: window_size: # Format: [Height, Width] in pixels - [128, 128] # Pass 1: Standard mode - [64, 64] # Pass 2: Standard mode - [16, 16] # Pass 3: Single mode (high resolution) overlap: - 50 - 50 - 50 type: - std # Standard correlation - std # Standard correlation - single # Single-pixel accumulation runs: - 3 # Save final pass

Single Mode & Sum Window

Ensemble-Only Feature

When any pass uses "single" type, the Sum Window configuration appears. This enables a powerful technique for achieving higher spatial resolution while maintaining FFT efficiency.

How Single Mode Works

Single mode uses asymmetric window weighting between Frame A and Frame B:

Frame A: "singlepix"

Small window (e.g., 4×4) centered within the larger sum_window (16×16). Only the central 4×4 region has weight = 1, surrounding pixels = 0. This concentrates the measurement on a small spatial region.

Frame B: "bsingle"

Full sum_window (16×16) with uniform weight = 1 everywhere. Captures particles across the entire correlation domain, providing robust statistics for peak detection.

Example: window_size [4, 4] with sum_window [16, 16]

The correlation is computed at 16×16 resolution, but the effective measurement is concentrated at the central 4×4 region. This gives you the spatial resolution of a 4×4 window with the peak-fitting accuracy of a 16×16 correlation plane.

  • Higher spatial resolution: Effective measurement concentrated at small window size
  • FFT efficiency: Correlation computed at sum_window size (16×16 FFT, not 4×4)
  • Better peak definition: Larger correlation plane improves sub-pixel fitting accuracy
  • Ensemble robustness: Averaging reduces noise while maintaining resolution
Validation Requirement

The sum_window must be greater than or equal to the window_size for all single-type passes. For example, if window_size is [16, 16], sum_window must be at least [16, 16].

config.yaml
ensemble_piv: window_size: # Format: [Height, Width] in pixels - [16, 16] # Small window for single mode type: - single # Enables sum_window sum_window: # Format: [Height, Width] in pixels - 64 # Sum window height (Y) - 64 # Sum window width (X)

Camera Selection

Select which cameras to process. This is particularly useful for multi-camera setups where you want to process specific views independently.

Camera Selector

The GUI displays numbered chips for each available camera. Click to toggle selection. At least one camera must be selected.

Cameras to Process:
1
2
3

Click to select/deselect cameras

config.yaml
paths: camera_count: 3 # Total cameras available camera_numbers: # Cameras to process - 1 # Only process camera 1

Peak Finding

Instantaneous PIV Only: Peak finder algorithm selection is available in the Advanced PIV Settings. Ensemble PIV uses gauss6 by default for optimal accuracy with averaged correlation planes.

The peak finder algorithm determines how sub-pixel displacement is extracted from the correlation peak. Higher parameter counts provide better accuracy but require more computation.

gauss3
3-Parameter Gaussian

Fastest. Basic Gaussian fit for quick processing.

Speed: FastestAccuracy: Good
gauss4
4-Parameter Gaussian

Adds amplitude parameter. Better peak detection.

Speed: FastAccuracy: Better
gauss5
5-Parameter Gaussian

Includes elliptical shape. Good for anisotropic flows.

Speed: ModerateAccuracy: High
gauss6
6-Parameter Gaussian

Full 2D Gaussian with rotation. Maximum accuracy.

Speed: SlowestAccuracy: Highest
config.yaml
instantaneous_piv: peak_finder: gauss3 # Options: gauss3, gauss4, gauss5, gauss6

Ensemble-Specific Options

Ensemble PIV Only: These options are available in the collapsible "Ensemble Options" panel.

store_planes

Store Correlation Planes

Saves the auto-correlation (AA, BB) and cross-correlation (AB) planes to planes_pass_N.mat files. Useful for manual inspection of correlation quality or debugging.

Warning: Enabling this creates large output files. Use only when debugging or inspecting correlation quality.

save_diagnostics

Save Diagnostics

Saves debug information to a filters/ subdirectory:

  • Peak fitting inputs and outputs
  • Warped images for each pass
  • Filter application results (first batch, first pair)
resume_from_pass

Resume From Pass

Continue processing from existing results. Enter the pass number (1-based) to resume from.

Use Case: Adding a Finer Pass

If you've completed passes 1-3 with window sizes [128, 64, 32] and want to add a pass 4 at 16×16: set resume_from_pass: 4 to skip re-processing passes 1-3. Requires an existing ensemble_result.mat in the output directory.

Set to 0 for a fresh start (default).

config.yaml
ensemble_piv: store_planes: false # Save AA, BB, AB correlation planes save_diagnostics: false # Save debug images and data resume_from_pass: 0 # 0 = fresh start, N = resume from pass N

Performance Settings

Configure parallel processing resources. These settings affect both instantaneous and ensemble modes. Access via the "Performance & Compute Settings" collapsible panel.

SettingDescriptionDefault
omp_threadsOpenMP threads per worker for parallelized operations2
dask_workers_per_nodeNumber of parallel Dask workers (typically = CPU cores)4
dask_threads_per_workerThreads each Dask worker can use1
dask_memory_limitRAM allocation per worker (e.g., "3GB", "4GB")3GB
filter_worker_countWorkers dedicated to preprocessing filters1

Filter Worker Count

The filter worker enables overlapped processing: while correlation workers process the current batch, the filter worker can preprocess the next batch.

  • Set to 1 for temporal filters (time, POD) to avoid memory issues
  • Set to 2+ for spatial-only filters for better throughput
config.yaml
processing: omp_threads: 2 dask_workers_per_node: 4 dask_threads_per_worker: 1 dask_memory_limit: 3GB filter_worker_count: 1 auto_compute_params: false # Set true to auto-detect optimal values

Outlier Detection

Identify and mark spurious vectors for replacement. Multiple detection methods can be chained together. Enable/disable via the toggle in the "Outlier Detection" collapsible panel.

peak_mag
Peak Magnitude

Rejects vectors with weak correlation peaks below threshold.

threshold=0.3Minimum peak magnitude

Typically used in instantaneous only

median_2d
Median-Based

Compares each vector to the median of its 8 neighbors.

epsilon=0.2Regularization term
threshold=2.0Normalised residual threshold

Good for local outlier detection

sigma
Standard Deviation

Statistical outlier based on neighbor standard deviation.

sigma_threshold=2.0Std dev multiplier

Best for Gaussian-distributed errors

Different YAML Paths

Instantaneous and Ensemble use separate configuration sections. This allows different outlier detection strategies for each mode.

Instantaneous
config.yaml
outlier_detection: enabled: true methods: - type: peak_mag threshold: 0.3 - type: median_2d epsilon: 0.2 threshold: 2
Ensemble
config.yaml
ensemble_outlier_detection: enabled: true methods: - type: median_2d epsilon: 0.2 threshold: 2

Infilling Methods

Replace outlier vectors (marked as NaN) with interpolated values. Infilling occurs in two phases:

Mid-Pass Infilling

Applied between multi-pass iterations. Always enabled to ensure smooth predictor fields for window deformation.

Final-Pass Infilling

Applied to the output after the last pass. Optional—can be disabled if you prefer to keep NaN markers.

local_median
Local Median

Fast, simple infilling using the median of neighboring vectors.

ksize=3Kernel size (3×3, 5×5, etc.)

Best for: Quick infilling, small gaps

biharmonic
Biharmonic Inpainting

Smooth PDE-based interpolation that respects local flow gradients.

Best for: High-quality results, larger gaps

knn
K-Nearest Neighbors

Distance-weighted regression using nearby valid vectors.

n_neighbors=32Number of neighbors
weights=distanceWeighting scheme

Best for: Sparse data, irregular gaps

Instantaneous
config.yaml
infilling: mid_pass: method: biharmonic parameters: ksize: 3 final_pass: enabled: true method: biharmonic parameters: ksize: 3
Ensemble
config.yaml
ensemble_infilling: mid_pass: method: biharmonic parameters: ksize: 3 final_pass: enabled: true method: biharmonic parameters: ksize: 3

Running PIV

Start processing from the Run PIV card. Both modes share common controls but differ in feedback display. You can process multiple datasets sequentially by selecting them in the path list.

Batch Processing Multiple Paths

When you have configured multiple source/base path pairs in Image Configuration, the Run PIV card displays a list with checkboxes to select which datasets to process.

2 of 3 path(s) selectedSelect AllClear All
  • Check/uncheck paths to include or exclude them from processing
  • Selected paths are processed sequentially in order
  • Use 'Select All' or 'Clear All' links for quick selection
  • Same PIV settings (windows, overlap, etc.) apply to all selected paths

Overwrite Confirmation

If output data already exists for the selected paths, a confirmation dialog appears asking whether to clear existing data and recompute. This prevents accidental overwrites of completed processing runs.

Output Data Already Exists

Output data already exists for the selected paths. Would you like to clear the existing data and recompute?

CancelClear and Recompute

Controls

1

Select Paths to Process

Check the datasets you want to process. At least one must be selected.

2

Click "Run PIV"

Starts processing. Button disabled while running or if no paths selected.

3

Cancel (if needed)

Stops processing gracefully. Partial results may be saved.

Instantaneous Feedback

  • Progress bar with percentage complete
  • Live status image preview of processed frames
  • Variable selector (ux, uy, nan_mask, peak_mag)
  • Colormap and contrast controls
  • Console output with real-time logs

Live Preview: As each frame pair is processed, you can view the resulting velocity field in real-time. Select which variable to display and adjust colormap settings to inspect data quality during processing.

Ensemble Feedback

  • Simple status indicator (Processing.../Complete)
  • Console output with pass progress
  • No preview image (correlation accumulation)
  • Batch progress shown in console logs

No Live Preview: Ensemble processing accumulates correlation planes across all frames before peak detection. Vectors are only extracted once all images are processed, so there are no interim frame results to display.

Console Output (Both Modes)

Both instantaneous and ensemble PIV display real-time console logs. Toggle visibility with the "Show/Hide Console Logs" button.

PIV Console OutputLive
[INFO] Starting PIV processing for 3 paths
[INFO] Processing path 1/3: experiment_01
[INFO] Pass 1/3: Window 128x128, Overlap 50%
[INFO]   Batch 1/4 complete (25 pairs)
[INFO]   Batch 2/4 complete (25 pairs)
[INFO]   Batch 3/4 complete (25 pairs)
[INFO]   Batch 4/4 complete (25 pairs)
[INFO] Pass 1 complete. Starting Pass 2...
[INFO] Pass 2/3: Window 64x64, Overlap 50%
Instantaneous logs show:
  • • Frame pair progress (e.g., "Processing pair 45/100")
  • • Batch completion status
  • • Pass transitions
  • • Outlier detection and infilling stats
Ensemble logs show:
  • • Batch accumulation progress
  • • Correlation plane updates
  • • Pass completion and transition
  • • Final peak extraction status

Why the Preview Difference?

Instantaneous PIV produces a complete velocity field for each frame pair as it processes, enabling real-time visualisation. Ensemble PIV accumulates correlation data across all frames and only extracts the final averaged velocity field at the end—there simply are no intermediate results to preview. Use the console logs to monitor ensemble progress.

config.yaml
# Enable instantaneous mode processing: instantaneous: true ensemble: false # OR enable ensemble mode processing: instantaneous: false ensemble: true

Complete YAML Reference

Below is a complete reference of all PIV-related configuration options.

YAML PathInst.Ens.Description
*_piv.window_sizeList of [Height, Width] window sizes per pass
*_piv.overlapOverlap percentages per pass
*_piv.runsPasses to save (1-based list)
ensemble_piv.typePass types: std or single
ensemble_piv.sum_windowSum window for single mode [Height, Width]
ensemble_piv.store_planesSave correlation planes
ensemble_piv.save_diagnosticsSave debug information
ensemble_piv.resume_from_passResume from pass N (0=fresh)
instantaneous_piv.peak_finderPeak algorithm: gauss3-6
outlier_detection.*Instantaneous outlier config
ensemble_outlier_detection.*Ensemble outlier config
infilling.*Instantaneous infilling config
ensemble_infilling.*Ensemble infilling config
processing.instantaneousEnable instantaneous mode
processing.ensembleEnable ensemble mode
config.yaml
# Complete PIV Configuration Example # =================================== # Note: Window sizes use [Height, Width] format (row-major convention) # Height = vertical (Y), Width = horizontal (X) # Processing mode (choose one) processing: instantaneous: true # Frame-pair mode ensemble: false # Correlation averaging mode backend: cpu # cpu or gpu omp_threads: 2 dask_workers_per_node: 4 dask_threads_per_worker: 1 dask_memory_limit: 3GB filter_worker_count: 1 # Instantaneous PIV settings instantaneous_piv: window_size: # [Height, Width] in pixels - [128, 128] # Square windows - [64, 64] - [32, 32] # For rectangular: [32, 64] = 32px tall × 64px wide overlap: - 50 - 50 - 50 runs: - 3 peak_finder: gauss3 # Ensemble PIV settings ensemble_piv: window_size: # [Height, Width] in pixels - [128, 128] - [64, 64] - [16, 16] overlap: - 50 - 50 - 50 type: - std - std - single runs: - 3 sum_window: # [Height, Width] for single mode - 64 - 64 store_planes: false save_diagnostics: false resume_from_pass: 0 # Outlier detection (instantaneous) outlier_detection: enabled: true methods: - type: peak_mag threshold: 0.3 - type: median_2d epsilon: 0.2 threshold: 2 # Outlier detection (ensemble) ensemble_outlier_detection: enabled: true methods: - type: median_2d epsilon: 0.2 threshold: 2 # Infilling (instantaneous) infilling: mid_pass: method: biharmonic parameters: ksize: 3 final_pass: enabled: true method: biharmonic parameters: ksize: 3 # Infilling (ensemble) ensemble_infilling: mid_pass: method: biharmonic parameters: ksize: 3 final_pass: enabled: true method: biharmonic parameters: ksize: 3

Command Line Usage

PIVTools can be run from the command line using the pivtools-cli tool. This is useful for batch processing, scripting, and integration with other workflows.

Basic Commands

Initialise a workspace

Creates a default config.yaml in the current directory.

Terminal
# Initialise with default config pivtools-cli init # Overwrite existing config pivtools-cli init --force
Run PIV analysis

Use separate commands for instantaneous (per-frame) or ensemble (time-averaged) PIV. Both use settings from config.yaml.

Terminal
# Run instantaneous PIV (per-frame) pivtools-cli instantaneous # Run ensemble PIV (time-averaged correlation) pivtools-cli ensemble # Process specific paths only pivtools-cli instantaneous -p 0,1

Post-Processing Commands

CommandDescription
pivtools-cli detect-planarGenerate camera model from dot/circle grid
pivtools-cli detect-charucoGenerate camera model from ChArUco board
pivtools-cli apply-calibrationApply calibration to vectors (pixels to m/s)
pivtools-cli transformApply geometric transforms (flip, rotate) to vector fields
pivtools-cli mergeMerge multi-camera vector fields using Hanning blend
pivtools-cli statisticsCompute mean velocity, Reynolds stresses, TKE, vorticity
pivtools-cli videoCreate visualisation videos from PIV data
Terminal
# Full workflow example pivtools-cli init # Create config # ... edit config.yaml to set paths, PIV settings ... pivtools-cli detect-planar # Generate camera model pivtools-cli instantaneous # Run PIV pivtools-cli apply-calibration # Calibrate vectors pivtools-cli statistics --camera 1 # Compute stats pivtools-cli video --variable ux --fps 30 # Create video

Common Options

Camera Selection
Terminal
# Process specific camera pivtools-cli apply-calibration --camera 1 # Process all cameras (default) pivtools-cli apply-calibration
Data Type
Terminal
# Process instantaneous data pivtools-cli statistics -t instantaneous # Process ensemble data pivtools-cli statistics -t ensemble

Active Paths from Config

The CLI uses the paths.active_paths setting from config.yaml to determine which datasets to process. All selected paths are processed sequentially.

config.yaml
# In config.yaml: paths: source_paths: - /data/run_001/images - /data/run_002/images - /data/run_003/images base_paths: - /data/run_001/results - /data/run_002/results - /data/run_003/results active_paths: - 0 # Process run_001 - 2 # Process run_003 # run_002 (index 1) is skipped
Get Help
Terminal
# List all commands pivtools-cli --help # Get help for a specific command pivtools-cli instantaneous --help pivtools-cli apply-calibration --help pivtools-cli video --help

Path Override with --active-paths

All commands support the --active-paths or -p flag to override the active_paths from config.yaml.

Terminal
# Process only path index 0 pivtools-cli instantaneous -p 0 # Process paths 0 and 2 pivtools-cli apply-calibration -p 0,2 # All post-processing commands support -p pivtools-cli statistics -p 0,1 pivtools-cli video -p 0

Need to Calibrate?

Convert pixel displacements to physical velocities with calibration.

Back to Quick Start