Using PIVlab from the command line

Everything you do in the PIVlab window can also be done in a MATLAB script with the functions of the pivlab package. They use exactly the same code as the GUI, so a script and the GUI give identical results for identical settings. Every function works with only its required inputs and then uses the PIVlab defaults.

The workflow in ten lines

imgs = pivlab.readImages("Example_data/Jet_*.jpg", "pairwise");   % select and pair images
imgs = pivlab.preprocess(imgs);                                    % CLAHE + intensity stretch
res  = pivlab.analyze(imgs);                                       % PIV analysis
res  = pivlab.filter(res);                                         % remove outliers, interpolate
res  = pivlab.toMetric(res, DeltaT=0.001, PxPerMeter=1234);        % m and m/s
[res, vort] = pivlab.derive(res, "vorticity");                     % derived quantities
m    = pivlab.temporal(res, "mean");                               % temporal mean
pivlab.display(m, Overlay="magnitude");                            % figure like in the GUI
pivlab.saveSession(res, "analysis.mat");                           % open it in the GUI later

The PIVlab folder must be on the MATLAB path (addpath it, or start PIVlab once). Type help pivlab for an overview and help pivlab.analyze (etc.) for all options of a step. Complete examples are in Example_scripts/PIVlab_api_*.m.

The functions

FunctionWhat it doesGUI equivalent
pivlab.readImages(source, sequencing)File pattern, folder or file list; sequencing "pairwise", "timeresolved" or "reference". Multi-page TIFFs, .b16 and pco.panda double images work as in the GUI.Import images
pivlab.preprocess(imgs, ...)CLAHE, high-pass, intensity capping, Wiener filter, intensity limits, background removal (Background="mean" / "min"), region of interest (Roi), mask (Mask) and camera calibration (Camera, see below).Image settings
pivlab.getImage(imgs, k)One image, pre-processed exactly as it goes into the analysis.Apply and preview
pivlab.analyze(imgs, ...)FFT window deformation (default), ensemble, DCC or optical flow; window sizes, passes, robustness, uncertainty, parallel processing.PIV settings + Analyze
pivlab.filter(res, ...)Standard deviation filter, normalized median test, velocity limits, correlation / notch / image-based filters, second-peak substitution, interpolation.Vector validation
pivlab.toMetric(res, ...)Calibration with DeltaT and PxPerMeter (or ReferenceDistance), origin and axis directions.Calibration
pivlab.derive(res, quantity)Vorticity, magnitude, u, v, divergence, Q criterion, shear, strain, direction, LIC, correlation, uncertainty; optional spatial / temporal smoothing.Derive parameters
pivlab.temporal(res, op)Mean, standard deviation, sum, TKE (also phase averages with Frames={...}).Temporal statistics
pivlab.display(res, ...)Vectors on the particle image or on a transparent colour map with colour bar, all options of the plot settings.Plot appearance
pivlab.defaults(), pivlab.loadSettings(file)Default settings, or the settings of a settings file or session (detected automatically).Load settings
pivlab.loadSession(file), pivlab.saveSession(res, file)Results of a session; save results as a session that opens in the GUI.Load / save session
pivlab.stereo(imgs, boards, board, ...)Stereo-PIV of two cameras: stereo calibration, disparity correction, PIV of both cameras, U, V and W (see below).Stereo-PIV panel + Analyze

The result struct

res holds all image pairs; the third dimension of the arrays is the pair.

FieldContent
res.x, res.yvector positions (px, or m after toMetric)
res.u, res.vvelocities in res.units (filtered after pivlab.filter, smoothed after a smoothed pivlab.derive)
res.u_raw, res.v_rawunfiltered PIV result
res.typevector1 = valid, 2 = removed/interpolated, 3 = second correlation peak, 0 = masked
res.correlation_mapcorrelation coefficient of every vector
res.derivedmaps computed by pivlab.derive, e.g. res.derived.vorticity
res.pxthe same data in pixel units, as PIVlab stores it internally

You can change values in res.u / res.v by hand, e.g. res.u(res.u > 10) = NaN;. The next pivlab.* function takes the changed values over (all other values stay exactly as computed). pivlab.filter always starts again from the unfiltered data (res.u_raw), so change res.u_raw if the filter should use your values. Adding or removing vectors or frames is not possible; use the Pairs option of pivlab.analyze or Frames of pivlab.temporal.

Useful options

Settings

Name=value arguments change single settings. To reuse a complete configuration, pass a settings struct: from pivlab.defaults (then edit it), or from a file saved in the GUI.

s = pivlab.loadSettings("my_session.mat");       % session or settings file
imgs = pivlab.preprocess(pivlab.readImages("D:\run1\*.tif", "pairwise"), Settings=s);
res  = pivlab.analyze(imgs, Settings=s, Parallel=true);
res  = pivlab.filter(res, Settings=s);
res  = pivlab.toMetric(res, Settings=s);         % calibration of the session

Camera calibration (lens undistortion, rectification)

Make the camera calibration in the PIVlab window (Camera calibration & rectification): there you see the detected markers and the corrected images. A script then uses the result with the Camera option of pivlab.preprocess:

imgs = pivlab.readImages("D:\run1\*.tif", "pairwise");
% undistortion and rectification exactly as in a session
imgs = pivlab.preprocess(imgs, Camera="my_session.mat");
% or: undistortion from a file saved with "Save camera parameters"
imgs = pivlab.preprocess(imgs, Camera="camera_calibration.mat");
OptionValues
CameraA PIVlab session: lens undistortion and rectification exactly as they were used in the session. A camera calibration file saved with Save camera parameters: lens undistortion only. A cameraParameters object (Computer Vision Toolbox). "none" switches the undistortion off.
CameraView"valid" (cut away black borders), "same" (same size as the input image) or "full" (include black borders). Default: as in the session, else "valid".
Rectificationfalse switches the rectification of a session off; a 2-D transformation (e.g. projtform2d) rectifies the undistorted images with it. Default: as in the session.

All following steps use the corrected images: Roi and Mask refer to them, imgs.imageSize is their size, and pivlab.getImage shows them. pivlab.loadSession restores the camera calibration of a session, and pivlab.saveSession saves it, so the GUI opens the session with the same corrected images.

Stereo-PIV

pivlab.stereo does what the Stereo-PIV panel and Analyze do in the GUI. It needs the images and the lens calibration of both cameras, one image of the ChArUco board in the light sheet per camera, and the board definition:

imgs{1} = pivlab.preprocess(pivlab.readImages("D:\run1\cam1\*.tif", "pairwise"), Camera="lens_cam1.mat");
imgs{2} = pivlab.preprocess(pivlab.readImages("D:\run1\cam2\*.tif", "pairwise"), Camera="lens_cam2.mat");
board = struct('PatternDims',[23 24], 'CheckerSize',10, 'MarkerSize',7, ...
    'MarkerFamily',"DICT_4X4_1000", 'OriginCheckerColor',"black");    % sizes in mm
res = pivlab.stereo(imgs, {"board_cam1.tif", "board_cam2.tif"}, board);
res = pivlab.filter(res);                 % validates both cameras, then U, V, W again
res = pivlab.toMetric(res, DeltaT=0.001); % the scale comes from the stereo calibration
pivlab.display(res, Overlay="w");

A complete example: Example_scripts/PIVlab_api_stereo.m, with the synthetic stereo recording of a free jet in Example_data/stereo_free_jet.

Why pre-processing does not create new images

pivlab.preprocess only stores the settings (and computes the background image if requested). The filters are applied to every pair inside pivlab.analyze, exactly like the GUI does it, so long image series need no extra memory or disk space. pivlab.getImage shows a pre-processed image.

Requirements MATLAB R2021a or newer and the Image Processing Toolbox (as for the GUI). The Parallel Computing Toolbox is optional (Parallel=true).