dpivsoft.stereo_DPIV

dpivsoft.stereo_DPIV.rgb2gray(item)[source]

Return item as a 2-D float grayscale array.

Accepts either a file path (any format cv2 can read) or an already-loaded ndarray, so callers can mix disk files and in-memory back-projected frames interchangeably.

dpivsoft.stereo_DPIV.stereo_calibration(final_matrix_l, final_matrix_r, org_width, org_height, mode='reduced')[source]

Calibrate a stereo camera pair using the Soloff mapping.

mode selects the polynomial:

  • 'reduced' (default) — the 9-term, linear-in-z model (basis [x², y², xy, x, y, 1, z, x·z, y·z]); needs >=2 distinct z planes.

  • 'full' — the classic 19-term Soloff (Soloff et al. 1997): cubic in-plane at z⁰ (the cubic terms model lens distortion), quadratic at z¹, linear at z². Needs >=3 distinct z planes (the highest z-power) and enough in-plane points per plane. Falls back to NaN maps (Soloff unavailable) if the plane condition is not met.

For each camera, fits the chosen polynomial in both directions by exact least squares:

forward (pixel -> world): X,Y = poly(x_px, y_px, Z) map (world -> pixel): x_px,y_px = poly(X, Y, Z)

The forward map’s Z=0 part builds the world-coordinate grid; the world->pixel map is the Soloff mapping used by soloff_velocity (full local Jacobian) and for back-projection (its Z=0 part). A dual-plane calibration (>=2 distinct Z) is required to constrain the parallax (Z and cross-terms).

Returns:

  • fwd_a_l, fwd_b_l, fwd_a_r, fwd_b_r (ndarray, shape (9,) or (19,)) – Forward (pixel→world) coefficients for X and Y, per camera (9 in reduced mode, 19 in full mode). Used (Z=0 part) to compute the world grid.

  • map_a_l, map_b_l, map_a_r, map_b_r (ndarray, shape (9,) or (19,)) – Soloff world->pixel mapping coefficients for x and y, per camera; used by soloff_velocity (local Jacobian) and back-projection (Z=0 part). NaN-filled if the calibration lacks enough distinct Z planes (parallax unconstrained).

  • results (str) – Human-readable summary of fit RMS and Soloff-map readiness.

dpivsoft.stereo_DPIV._poly9_design(px, py, pz)[source]

Reduced (9-term) Soloff design matrix.

Basis [p², q², pq, p, q, 1, z, pz, qz] — quadratic in-plane at z⁰, linear in-plane at z¹. KEEP this order (on-disk files and the hand-derived fold-back in _fit_poly9 depend on it).

dpivsoft.stereo_DPIV._poly19_design(px, py, pz)[source]

Full (19-term) Soloff design matrix (Soloff et al. 1997).

Basis, in coefficient order: cubic in-plane at z⁰ (the cubic terms model lens distortion), quadratic in-plane at z¹, linear in-plane at z²:

[p³, p²q, pq², q³, p², pq, q², p, q, 1, (z⁰, 10)

p²z, pqz, q²z, pz, qz, z, (z¹, 6) pz², qz², z²] (z², 3)

dpivsoft.stereo_DPIV._fit_poly9(px, py, pz, b)[source]

Least-squares fit of the 9-term Soloff polynomial, well-conditioned.

Fits b poly9(px, py, pz) but solves in normalised coordinates (each of px, py, pz shifted to zero mean and unit std), so the design-matrix columns are all O(1) instead of spanning ~7 orders of magnitude (px² in pixels ~1e7, the z column ~1e0). That drops cond(C) from ~1e7 to ~1, so the weakly-excited parallax coefficients (z, p·z, q·z) — the ones stereo depends on — are resolved at full precision.

The fitted coefficients are folded back into the raw 9-term basis, so the returned 9-vector is in the exact same convention as a direct raw fit (the basis is closed under per-axis affine normalisation): _poly9_eval / _poly9_jacobian, every caller, and the on-disk format stay unchanged.

dpivsoft.stereo_DPIV._fit_poly19(px, py, pz, b)[source]

Least-squares fit of the full 19-term Soloff polynomial.

Cubic in-plane at z⁰ (lens distortion), quadratic at z¹, linear at z² (Soloff et al. 1997). Needs >=3 distinct z planes (the highest z-power) and enough in-plane points per plane for the cubic terms.

Conditioning is handled by column equilibration rather than the coordinate-normalisation fold-back used by _fit_poly9: each design column is scaled to unit RMS before the solve and the coefficients are divided back afterwards (a similarity transform that leaves the raw least-squares solution unchanged but drops cond(C) by many orders). Equilibration is basis-agnostic, so it extends to all 19 terms without re-deriving the fold-back algebra.

dpivsoft.stereo_DPIV._is_full_poly(c)[source]

True for a full (19-term) Soloff vector, False for reduced (9-term).

Calibrations are only ever 9 (reduced) or 19 (full Soloff); any other length is a malformed/corrupt map, so raise rather than silently mis-modelling. Used by the _poly_eval / _poly_jacobian selectors to dispatch.

dpivsoft.stereo_DPIV._poly9_eval(c, X, Y, Z)[source]

Evaluate the reduced 9-term Soloff polynomial.

Basis [X², Y², XY, X, Y, 1, Z, X·Z, Y·Z]. X, Y, Z may be arrays.

dpivsoft.stereo_DPIV._poly9_jacobian(c, X, Y, Z=0.0)[source]

Partials (dF/dX, dF/dY, dF/dZ) of the reduced 9-term polynomial at Z.

Linear in Z, so the parallax slope dF/dZ = c6 + c7·X + c8·Y does NOT depend on Z; only the in-plane derivatives pick up the small c7·Z / c8·Z terms.

dpivsoft.stereo_DPIV._poly19_eval(c, X, Y, Z)[source]

Evaluate the full 19-term Soloff polynomial.

Coefficient order matches _poly19_design: cubic in-plane at z⁰, quadratic at z¹, linear at z². X, Y, Z may be arrays.

dpivsoft.stereo_DPIV._poly19_jacobian(c, X, Y, Z=0.0)[source]

Partials (dF/dX, dF/dY, dF/dZ) of the full 19-term polynomial at Z.

Unlike the reduced model, the parallax slope dF/dZ is Z-dependent (the z² curvature the extra planes buy) and the in-plane derivatives carry the cubic-distortion terms.

dpivsoft.stereo_DPIV._poly_eval(c, X, Y, Z)[source]

Evaluate the Soloff map, picking the model by coefficient length.

dpivsoft.stereo_DPIV._poly_jacobian(c, X, Y, Z=0.0)[source]

Soloff map Jacobian, picking the model by coefficient length.

dpivsoft.stereo_DPIV._stereo_recon_grid(calibration, img_shape, piv_shape)[source]

Common world grid at PIV vector resolution over the cameras’ overlap.

Shared by soloff_velocity and disparity_to_delta_z so both work on identical grid points. make_world_grid returns the overlap at full image resolution (for dewarping); reconstructing there would upsample a few thousand PIV vectors onto millions of points – needlessly huge and physically meaningless – so the grid is sampled at the input PIV shape.

Returns (Xg, Yg): 1-D world axes (mm) meshgrid.

dpivsoft.stereo_DPIV.soloff_velocity(x_l, y_l, u_l, v_l, x_r, y_r, u_r, v_r, calibration, img_shape, delta_z=None)[source]

Classic Soloff 3-component reconstruction from raw-image PIV fields.

At every point of a common world grid it builds each camera’s local world->pixel mapping Jacobian and solves the over-determined linear system

[Δx_l, Δy_l, Δx_r, Δy_r]ᵀ = M · [ΔX, ΔY, ΔZ]ᵀ (M is 4×3)

by least squares for the world displacement (U, V, W). The Jacobian (hence the parallax) varies across the field, so the reconstruction is locally correct everywhere.

Parameters:
  • x_l (ndarray — left-camera PIV grid in raw image pixels.)

  • y_l (ndarray — left-camera PIV grid in raw image pixels.)

  • u_l (ndarray — left-camera in-plane displacement (raw pixels).)

  • v_l (ndarray — left-camera in-plane displacement (raw pixels).)

  • x_r (ndarray — same for the right camera.)

  • y_r (ndarray — same for the right camera.)

  • u_r (ndarray — same for the right camera.)

  • v_r (ndarray — same for the right camera.)

  • calibration (Parameters.Stereo_Calibration) – Must carry the Soloff maps map_a_l/map_b_l/map_a_r/map_b_r (produced by a dual-plane calibration).

  • img_shape (tuple (height, width)) – Pixel dimensions of the raw camera images (for the world grid extent).

  • delta_z (None, float, or ndarray, optional) – Out-of-plane offset Z (mm) at which to evaluate the Soloff map and its Jacobian, instead of the calibration plane Z=0. This is the disparity / Δz self-calibration correction (Wieneke 2005): it accounts for the laser sheet sitting at a (possibly spatially varying) offset from the calibration plane. None (default) reproduces the uncorrected Z=0 reconstruction. A scalar applies a uniform offset; an array must match the input PIV grid shape (np.shape(x_l)) and gives a per-point Δz — build it from a measured disparity field with disparity_to_delta_z. Because the map already carries the Z dependence.

Returns:

  • x, y (ndarray — common world grid (mm).)

  • u, v (ndarray — in-plane world displacement.)

  • u_z (ndarray — out-of-plane (w) displacement. Front-Back convention:) – negative = toward left camera, positive = toward right camera.

dpivsoft.stereo_DPIV.save(x, y, u, v, u_z, filename, option='dpivsoft', Matlab=False, param=False)[source]

save flow field to a file. Option indicates the saving format.

dpivsof: save in python .npz file using the original formating of dpivsoft in matlab

openpiv: save the field in an ascii file compatible with openpiv

dpivsoft.stereo_DPIV.make_world_grid(calibration, img_shape, scale_px_per_mm=None, margin_mm=0.0)[source]

Compute a world-coordinate output grid covering both cameras’ fields of view.

Maps the image corners of each camera to world coordinates via the forward polynomial mapping, then builds a regular grid over the intersection bounding box.

Parameters:
  • calibration (Parameters.Stereo_Calibration)

  • img_shape (tuple (height, width)) – Pixel dimensions of the raw camera images.

  • scale_px_per_mm (float or None) – Output resolution (pixels per mm). If None, estimated from the average image-width-to-world-X-extent ratio of both cameras.

  • margin_mm (float) – Inward margin subtracted from each side of the overlap region (mm).

Returns:

  • world_x (ndarray, shape (nx,) — X coordinates of grid columns (mm).)

  • world_y (ndarray, shape (ny,) — Y coordinates of grid rows (mm),) – running from y_max (row 0, physically high) to y_min (last row).

dpivsoft.stereo_DPIV.backproject_image(img, inv_a, inv_b, world_x, world_y, method='linear', Z=0.0)[source]

Back-project a raw camera image onto a regular world-coordinate grid.

For each point on the output world grid, the world->pixel mapping (inv_a, inv_b) maps it to a source pixel location, which is then interpolated from the raw image.

Parameters:
  • img (ndarray, shape (ny_img, nx_img)) – Raw camera image (float or int).

  • inv_a (ndarray) – World->pixel mapping coefficients (pass calibration.map_a_l / map_b_l etc.). The full 9-term Soloff map is evaluated at Z.

  • inv_b (ndarray) – World->pixel mapping coefficients (pass calibration.map_a_l / map_b_l etc.). The full 9-term Soloff map is evaluated at Z.

  • world_x (ndarray, shape (nx,)) – X world coordinates of the output grid columns (mm), 1-D, monotone.

  • world_y (ndarray, shape (ny,)) – Y world coordinates of the output grid rows (mm), 1-D.

  • method (str) – Interpolation method passed to RegularGridInterpolator.

  • Z (float or ndarray, optional) – Out-of-plane plane (mm) at which to evaluate the Soloff map. 0.0 (default) dewarps at the calibration plane (the in-plane Z=0 part of the map, as before). A scalar shifts the whole grid to one Z; an array must broadcast to the world grid (len(world_y), len(world_x)) and gives a per-point Δz — pass a Δz(X,Y) field to re-dewarp on the laser sheet (disparity self-calibration iteration). Because the 9-term map already carries the Z dependence, no extra geometry is needed.

Returns:

img_bp – Back-projected image in world coordinates.

Return type:

ndarray, shape (ny, nx)

dpivsoft.stereo_DPIV.list_images(src_dir, exts=('.tif', '.tiff', '.png', '.bmp', '.jpg', '.jpeg'))[source]

Return the sorted image filenames in src_dir (any of exts).

dpivsoft.stereo_DPIV.download_pivchallenge_E(dest_dir, url='https://www.pivchallenge.org/pub14/4th_PIV-Challenge_Case_E.zip', force=False, keep_zip=False)[source]

Download the 4th PIV Challenge (2014) Case E stereo dataset into dest_dir, sorted into calibration, camera1 and camera2 subfolders that hold only the image files.

Case E is a time-resolved stereo-PIV vortex-ring experiment recorded by two cameras (1 and 3). The archive identifies every image by filename:

  • calibration target E_camera_{1,3}_z_{1..7}.tif (7 Z-planes, ΔZ = 1 mm) -> calibration (filenames keep the camera/plane, so both cameras live in the same folder without ambiguity)

  • particle frames E_camera_{1,3}_frame_NNNNN.tif -> camera1 (the lower camera index) and camera2 (the higher one)

Classification is by filename (_z_ vs _frame_ and the camera_N index), so the layout inside the zip is irrelevant. Everything that is not an image (the instructions PDF, readmes, …) is dropped. This lets the stereo tests run against a real dataset without committing ~200 MB of images to the repository.

Parameters:
  • dest_dir (str) – Target folder; calibration/camera1/camera2 are created inside it.

  • url (str, optional) – Source archive (defaults to the official pivchallenge.org URL).

  • force (bool, optional) – Re-download and re-extract even if the subfolders already hold images.

  • keep_zip (bool, optional) – Keep the downloaded .zip (in dest_dir) instead of deleting it.

Returns:

{'calibration': path, 'camera1': path, 'camera2': path} with the number of images sorted into each printed to stdout.

Return type:

dict

dpivsoft.stereo_DPIV.backproject_folder(src_dir, dst_dir, inv_a, inv_b, world_x, world_y, exts=('.tif', '.tiff', '.png', '.bmp', '.jpg', '.jpeg'), files=None, Z=0.0)[source]

Back-project images in src_dir onto the world-coordinate grid and save results to dst_dir, preserving filenames and bit depth.

Parameters:
  • src_dir (str) – Folder containing raw camera images (any format in exts).

  • dst_dir (str) – Output folder (created if it does not exist).

  • inv_a (ndarray) – World->pixel mapping coefficients (pass calibration.map_a_l / map_b_l).

  • inv_b (ndarray) – World->pixel mapping coefficients (pass calibration.map_a_l / map_b_l).

  • world_x (ndarray) – World grid from make_world_grid().

  • world_y (ndarray) – World grid from make_world_grid().

  • exts (tuple of str) – Image extensions to process (default IMAGE_EXTS).

  • files (list of str or None) – Explicit subset of filenames (relative to src_dir) to process. When None (default) every image in the folder is dewarped; pass a slice of list_images(src_dir) to dewarp only selected frames.

  • Z (float or ndarray, optional) – Out-of-plane plane (mm) for the dewarp, forwarded to backproject_image. 0.0 (default) dewarps at the calibration plane; pass a Δz(X,Y) field on the world grid to re-dewarp on the laser sheet for disparity self-calibration iteration.

dpivsoft.stereo_DPIV.compute_disparity(paths_cam1, paths_cam2, window_size=128, overlap=0.75, peak_search_ratio=0.6, peak_ratio=0.83, show_corr_windows=False)[source]

Compute the disparity field between two cameras from backprojected images.

Uses ensemble correlation: the normalised cross-correlation maps from all image pairs are averaged before searching for the peak. This reinforces the true disparity signal coherently while random noise averages toward zero, giving a much sharper and more reliable peak than averaging individual per-pair displacements.

Parameters:
  • paths_cam1 (list of str or ndarray) – Back-projected world images for camera 1, given either as file paths (any format cv2 reads) or as pre-loaded arrays.

  • paths_cam2 (list of str or ndarray) – Corresponding images for camera 2 (same order, same-instant pairs).

  • window_size (int) – Interrogation window size in pixels (square). Default 128.

  • overlap (float) – Fractional overlap between adjacent windows, in [0, 1). Default 0.75.

  • peak_search_ratio (float) – Fraction of window_size used as the peak-search radius in the correlation plane. Limits the maximum detectable disparity to window_size * peak_search_ratio / 2 pixels. Default 0.6.

  • peak_ratio (float) – Maximum allowed second-to-first correlation peak ratio (same convention as DPIV.find_peaks). Windows whose secondary peak exceeds this fraction of the primary are ambiguous and marked invalid (NaN). Lower is stricter; >= 1 disables rejection. Default 0.83 (= 1/1.2).

  • show_corr_windows (bool) – If True, display 4 sample mean correlation windows (spread across the grid) with the detected peak marked, so you can inspect peak quality. Default False.

Returns:

  • x_grid (ndarray, shape (ny_win, nx_win)) – X pixel coordinate (column) of each window centre in the world image.

  • y_grid (ndarray, shape (ny_win, nx_win)) – Y pixel coordinate (row) of each window centre in the world image.

  • disp_x (ndarray, shape (ny_win, nx_win)) – X-disparity (cam2 minus cam1) in pixels of the world image, derived from the ensemble-averaged correlation peak.

  • disp_y (ndarray, shape (ny_win, nx_win)) – Y-disparity in pixels.

  • valid (ndarray of bool, shape (ny_win, nx_win)) – True where the ensemble peak is unambiguous (peak_ratio not exceeded).

dpivsoft.stereo_DPIV.build_disparity_maps(x_d, y_d, disp_x, disp_y, valid, height, width)[source]

Interpolate the sparse disparity field to full world-image resolution.

The sparse grid returned by compute_disparity has one vector per interrogation window. This function lifts it to a dense (H x W) map so that apply_disparity_correction can warp every pixel cheaply with a single cv2.remap call. Call this once before the PIV loop and reuse the result for every image.

Parameters:
  • x_d (ndarray, shape (ny_win, nx_win)) – Pixel coordinates of the sparse disparity window centres.

  • y_d (ndarray, shape (ny_win, nx_win)) – Pixel coordinates of the sparse disparity window centres.

  • disp_x (ndarray, shape (ny_win, nx_win)) – Disparity in world-image pixels (cam2 minus cam1).

  • disp_y (ndarray, shape (ny_win, nx_win)) – Disparity in world-image pixels (cam2 minus cam1).

  • valid (ndarray of bool, shape (ny_win, nx_win)) – Mask of reliable vectors. Invalid entries are filled by nearest-neighbour extrapolation before interpolating.

  • height (int) – Size of the world image in pixels.

  • width (int) – Size of the world image in pixels.

Returns:

dx_full, dy_full – Dense disparity maps ready for apply_disparity_correction.

Return type:

ndarray, shape (H, W), dtype float32

dpivsoft.stereo_DPIV.disparity_to_delta_z(calibration, x_grid, y_grid, disp_x, disp_y, valid, world_x, world_y, img_shape, piv_shape, surface_order=None)[source]

Convert a measured stereo disparity field to an out-of-plane Δz map.

The disparity is the residual misregistration left when a quiescent, same-instant pair is dewarped to the common world grid at Z=0 and cross-correlated (backproject_* + compute_disparity). It is non-zero because the particles live on the laser sheet, at an offset Δz(X,Y) from the calibration plane (Wieneke 2005). The returned Δz is sampled on the Soloff reconstruction grid (_stereo_recon_grid), ready to pass to soloff_velocity(..., delta_z=...).

compute_disparity returns the disparity in world-image pixels on a world-image-pixel grid, whereas the map Jacobian’s parallax slope ∂(x,y)/∂Z is in raw-camera pixels per mm. These must be reconciled:

  1. Window-centre pixel coords (x_grid, y_grid) and the disparity are converted to world millimetres via the world-image scale (the spacing of world_x/world_y used for the back-projection).

  2. A particle at Z=Δz, dewarped assuming Z=0, lands at world offset J⁻¹·(∂map/∂Z)·Δz in that camera’s dewarped image (J = in-plane map Jacobian; J⁻¹ turns the raw-pixel parallax into the world-mm shift the dewarp actually shows). The cam2-minus-cam1 disparity is therefore

    d_world = G · Δz, G = J_r⁻¹·∂map_r/∂Z − J_l⁻¹·∂map_l/∂Z

    (a dimensionless 2-vector). Δz is recovered by least squares (projecting the 2-D disparity onto G): Δz = (d_world·G)/(G·G).

Sign convention: cam1 must be the LEFT camera (map_*_l) and cam2 the RIGHT (map_*_r), matching compute_disparity’s cam2-minus-cam1 definition. Qualitatively validated – iterating the self-cal loop (stereo_tutorial.py) for 2 and 3 passes improves all metrics (the residual disparity converges toward center), which confirms the Δz sign and a self- consistent magnitude. Still to do: check the absolute Δz/w against an independent ground truth (e.g. Willert’s pivbook vortex ring or a synthetic known-w field).

Parameters:
  • calibration (Parameters.Stereo_Calibration) – Must carry the dual-plane Soloff maps map_a_l/map_b_l/map_a_r/map_b_r.

  • x_grid (ndarray) – Outputs of compute_disparity (window-centre pixel coords, disparity in world-image pixels, and the reliability mask).

  • y_grid (ndarray) – Outputs of compute_disparity (window-centre pixel coords, disparity in world-image pixels, and the reliability mask).

  • disp_x (ndarray) – Outputs of compute_disparity (window-centre pixel coords, disparity in world-image pixels, and the reliability mask).

  • disp_y (ndarray) – Outputs of compute_disparity (window-centre pixel coords, disparity in world-image pixels, and the reliability mask).

  • valid (ndarray) – Outputs of compute_disparity (window-centre pixel coords, disparity in world-image pixels, and the reliability mask).

  • world_x (ndarray, 1-D) – World axes (mm) of the back-projected images the disparity was measured on (the make_world_grid arrays used for back-projection). Their spacing sets the world-image pixel scale.

  • world_y (ndarray, 1-D) – World axes (mm) of the back-projected images the disparity was measured on (the make_world_grid arrays used for back-projection). Their spacing sets the world-image pixel scale.

  • img_shape (tuple) – Raw image size and PIV grid shape, forwarded to _stereo_recon_grid so the returned Δz lands on the same grid soloff_velocity uses.

  • piv_shape (tuple) – Raw image size and PIV grid shape, forwarded to _stereo_recon_grid so the returned Δz lands on the same grid soloff_velocity uses.

  • surface_order (None, 1 or 2, optional) –

    Optional low-order surface fit of the scattered per-point Δz before it is sampled onto the reconstruction grid – a regularizer that denoises the Δz field (a laser sheet’s Δz is physically low-order: a flat/tilted/gently bowed plane). The raw per-point estimate Δz=(d·G)/(G·G) is noise-limited (its error tracks the disparity noise ~1:1); fitting a surface averages that noise out.

    • None (default) – raw per-point + griddata resample (the original behaviour; existing runs are unchanged).

    • 1 – fit a plane [1, X, Y] (≈ Wieneke’s exact triangulation).

    • 2 – fit a quadratic [1, X, Y, X², XY, Y²]; keeps real sheet curvature and rejects noise (best for a bowed sheet, where a plane is biased). Going higher would re-admit noise – don’t.

    A synthetic geometric study (iid disparity noise) found order 1/2 beat the raw per-point Δz ~30× on flat/tilted sheets, and on a curved sheet order 2 beats both the raw estimate (~20×) and a plane (which is frozen at the curvature bias). NB: this improves noise behaviour only – it is not a substitute for validating the absolute Δz against ground truth.

Returns:

delta_z – Out-of-plane offset (mm) per grid point, pluggable as soloff_velocity(..., delta_z=delta_z).

Return type:

ndarray, shape == reconstruction grid (= piv_shape)

dpivsoft.stereo_DPIV.delta_z_on_world_grid(delta_z, world_x, world_y)[source]

Resample a recon-grid Δz field onto the world-image dewarp grid.

disparity_to_delta_z returns Δz on the Soloff reconstruction grid (piv_shape), but re-dewarping for disparity self-calibration iteration needs Δz on the world-image grid (world_x x world_y, full image resolution), so it can be passed straight as Z to backproject_*.

The reconstruction grid is just world_x/world_y resampled to PIV resolution (see _stereo_recon_grid), so the two grids share the same world rectangle and the recon-grid axes are recovered from the world endpoints and delta_z’s shape – no calibration or image size needed.

delta_z may also be None (-> 0.0: dewarp at the calibration plane) or a scalar (uniform offset); both pass straight through, so the caller can hand whatever Δz estimate it has to backproject_*(..., Z=...) with no branch.

Parameters:
  • delta_z (None, float, or ndarray) – Δz (mm): None / scalar / recon-grid field (shape = piv_shape).

  • world_x (ndarray, 1-D) – World axes (mm) of the dewarp grid (the make_world_grid arrays).

  • world_y (ndarray, 1-D) – World axes (mm) of the dewarp grid (the make_world_grid arrays).

Returns:

Z_world – Δz on the world grid, ready as backproject_image(..., Z=Z_world).

Return type:

float or ndarray, shape (len(world_y), len(world_x))

dpivsoft.stereo_DPIV.disparity_convergence_report(disp_x, disp_y, valid, dz_inc, prev_rms=None, tag='')[source]

Print disparity self-calibration metrics; return disp_rms for the next call.

disp_rms alone plateaus at the PIV noise floor, so also show: the Δz step RMS (-> 0 when converged), the bias (coherent part Δz removes -> 0), the scatter (~irreducible floor) and the valid-window count. A disp_rms that GROWS vs prev_rms means a wrong Δz sign for this geometry.

dpivsoft.stereo_DPIV.calibration_GUI(show_diagnostics=False)[source]

Launch the stereo calibration GUI (defined in stereo_gui.py).

Imported lazily so this math module has no hard Tkinter/PIL dependency.

Parameters:

show_diagnostics (bool) – Developer flag, forwarded to the GUI: when True, sort_points pops its diagnostic plot (the detected dots annotated with their assigned lattice (row, col) labels). Off by default so the workflow is not interrupted.