Image Pre-Processing
Build filter stacks to improve correlation quality. Test interactively with side-by-side raw vs. processed comparison.
Overview
Filters are applied sequentially from top to bottom. Temporal filters should precede spatial filters. All changes auto-save to config.yaml.
Temporal Filters
Operate across multiple frames (batches) to remove persistent features.
time-- Subtract local minimum across batchpod-- SVD-based background removal (Mendez et al.)
Spatial Filters
Operate per-frame via cv2. Median kernels that cv2 cannot express -- larger than 5, or anisotropic -- fall back to scipy.ndimage.
- Smoothing: gaussian, median
- Normalisation: norm, norm2, maxnorm, meannorm, ssmin
- Contrast/correction: lmax, invert, clahe
Gain Normalisation
Laser pulse energy drifts between frames, and the A and B pulses of a pair are rarely perfectly matched. Gain normalisation removes both at source, before anything else touches the images.
This is not a filters: entry. It is a separate switch under preprocessing: and runs at the head of the pipeline, ahead of pixel masking and every filter you configure.
PIVTools compares each frame against the per-camera ensemble mean image over unmasked pixels, fits a single gain by least squares, and divides it out:
Because the reference is the ensemble mean, the pipeline has to run twice: once to build the mean, once to apply the correction. That costs two extra full reads of the dataset per camera per run, which is the main reason it is off by default.
Gain normalisation or meannorm? Both address brightness variation, but at different levels. meannorm divides each frame by its own spatial mean, so it cannot tell a genuinely brighter flow field from a stronger laser pulse. Gain normalisation regresses against a common reference, which separates the two. Use gain normalisation when pulse energy is the problem, and meannorm when you want a cheap per-frame levelling without paying for the extra passes.
Temporal Filters
Require batch processing. Set batch size via the Batch Size input (appears when temporal filters are in the stack). Frame A and Frame B channels are processed independently.
| Filter | Parameters | Algorithm | Removes |
|---|---|---|---|
| time | None | Subtract per-pixel minimum over batch | Static backgrounds, reflections |
| pod | eps_auto_psi, eps_auto_sigma (both 0.01) | SVD decomposition; auto-detect noise threshold; subtract signal modes | Coherent structures, time-varying backgrounds |
Spatial Filters
Applied per-frame. Filters run in the order you list them, so spatial and temporal filters can be interleaved -- running temporal filters first is a recommendation, not something the pipeline enforces. Kernel sizes are auto-adjusted to be odd.
| Filter | Parameters | Description |
|---|---|---|
| gaussian | size: [7, 7], sigma: 1.0 | FIR Gaussian blur (matches MATLAB fspecial). Reduces high-frequency noise. |
| median | size: [5, 5] ([h, w]) | Median filter. Removes salt-and-pepper noise, preserves edges. |
| norm | size: [7, 7], max_gain: 1.0 | Local contrast normalisation: subtract the sliding minimum, divide by the local range. |
| norm2 | size: [7, 7], max_gain: 1.0 | Smoothed range normalisation: box-smooths the min and max envelopes before normalising (less sensitive to single-pixel noise than norm). |
| maxnorm | size: [7, 7], max_gain: 1.0 | Background normalisation: divide by a smoothed local minimum to equalise illumination gradients. |
| meannorm | (none) | Divide each frame by its own spatial mean intensity. Equalises pair-to-pair brightness (laser energy drift); recommended first step for ensemble processing. Global gain only -- within-frame illumination variation is the job of norm/norm2/maxnorm. |
| ssmin | size: [7, 7] | Sliding-minimum background subtraction: median-smooth, take the local minimum, box-smooth, subtract, clip to >= 0. |
| lmax | size: [7, 7] | Morphological dilation (local maximum). Enhances bright features. |
| invert | (none) | Invert intensities per frame: output = frame max - input. |
| clahe | clip_limit: 2.0, tile_grid_size: [8, 8] | Contrast-limited adaptive histogram equalisation (OpenCV). |
GUI Workflow
The ImagePairViewer displays raw and processed images side-by-side with synchronised zoom/pan.
Workflow
- Add filters from the dropdown. They appear as expandable cards in the filter stack.
- Configure parameters for each filter. Reorder with up/down arrows, remove with delete.
- Click Test Filters to apply the stack to the current frame (or batch for temporal filters).
- Compare raw vs. processed. Zoom into regions of interest.
- Use playback controls to verify consistency across frames.
Spatial-only stacks
Near-instant results -- only the current frame is processed.
With temporal filters
Processes the full batch. Progress indicator shown during computation.
Recommended order: Temporal filters first (time, pod) for background removal, then spatial filters for noise reduction and contrast enhancement.
YAML Reference
filters:
# Temporal (require batch processing)
- type: time
- type: pod
# Spatial (per-frame, order matters)
- type: gaussian
size: [7, 7] # [int, int]: kernel [h, w]
sigma: 1.0 # float: std dev in pixels
- type: median
size: [5, 5] # [int, int]: kernel [h, w]
- type: norm
size: [7, 7]
max_gain: 1.0 # float: max normalisation gain
- type: norm2
size: [7, 7]
max_gain: 1.0
- type: maxnorm
size: [7, 7]
max_gain: 1.0
- type: meannorm # no parameters (divide frame by its spatial mean)
- type: ssmin
size: [7, 7]
- type: lmax
size: [7, 7]
- type: invert # no parameters (output = frame max - input)
- type: clahe
clip_limit: 2.0
tile_grid_size: [8, 8]
batches:
size: 30 # Frames per batch (for temporal filters)Parameter Quick Reference
| Filter | Type | Parameter | Default |
|---|---|---|---|
| time | Temporal | (none) | - |
| pod | Temporal | eps_auto_psi, eps_auto_sigma | 0.01, 0.01 |
| gaussian | Spatial | size, sigma | [7,7], 1.0 |
| median | Spatial | size | [5, 5] |
| norm | Spatial | size, max_gain | [7,7], 1.0 |
| norm2 | Spatial | size, max_gain | [7,7], 1.0 |
| maxnorm | Spatial | size, max_gain | [7,7], 1.0 |
| meannorm | Spatial | (none) | - |
| ssmin | Spatial | size | [7, 7] |
| lmax | Spatial | size | [7, 7] |
| invert | Spatial | (none) | - |
| clahe | Spatial | clip_limit, tile_grid_size | 2.0, [8,8] |
Next: PIV Processing
Configure cross-correlation parameters for vector field computation.
Continue to PIV Processing