assess op• Data kinds: flow2d → table
• Call: import fullseye as fs; fs.ledger.piv_peak_locking(flow, bins=20) (to call the implementation directly, import pivops; pivops.piv_peak_locking(flow, bins=20); from the registry, opspiv.get("piv_peak_locking"))
• GPU: none (CPU reference implementation only)
Strength of peak locking: how far the distribution of the fractional parts deviates from uniform.
Subpixel estimates gravitate towards true displacements when the fractional part is 0 or 0.5. bias (due to the difference in the shape of the correlation peak and the shape of the fitted function) Textbook systematic error). If the flow is not uniform, the fractional part should be close to uniform distribution, Measure the deviation from there.
The index c0 is a chi-square deviation independent of sample size:
sum((n_i - n_bar)^2 / n_bar) / (2*bins - 1). For the 2*bins class that combines both components, if we take a sample from a uniform distribution, we get The expected value is 1, so if it is around 1, it cannot be distinguished from uniform. The larger it is, the more biased it is.
★ However, this index assumes that the decimal part of the true displacement is uniform. number of windows In a field where there is little or where the displacement changes slowly, the true value itself, c0, also becomes large (Actual measurement: True value of linear lamp is 82 —— There are only 19 columns of window grids and the decimal part is discrete. ). Therefore, read c0 by comparing it with the true value of the same input.
Definitive diagnosis is separate —— Scaling the decimal part of uniform translation from 0 to 0.9, See if the estimated values lie on the diagonal line. Actual measurement (win=32, density 0.02):
========== ================= ================== Estimation method RMS maximum absolute error of fractional error ========== ================= ================== gauss3 0.0037 px 0.0088 px parabolic 0.0104 px 0.0151 px centroid 0.2259 px 0.3701 px ========== ================= ==================
centroid answers the true value 0.1 as 0.02, 0.9 as 0.98 — attracts to an integer S-shape just like in the textbook. Confirmation that what was supposed to come out came out, This is not a problem with the implementation (that's why all three are left in place).
Args:
flow: (2, h, w).
bins: Number of histogram classes in the fractional part.
Returns:
dict: c0(index of both components combined), hist((2, bins)),
frac_mean / frac_std, bins.
• piv_displacement family guide
• Sample-data catalog (download URLs / licences) — 2-D uses skimage.data (BSD/public domain) plus synthetic images; 3-D lists download URLs for real data sources (Stanford, PDS, …).
• Operator provenance and references — the sources of the research/methods this op family came from.
• The canonical algorithm (author, year) and its uses are named in the family usage guide above.
• piv_field_analysis_tour — py -3.11 examples/piv_field_analysis_tour.py
• poc_battery_electrode_breathing — py -3.11 examples/poc_battery_electrode_breathing.py
table as input)—
assess)piv_sample_at_windows · piv_error_stats · piv_time_statistics
*Provenance: pivops.py — PIV operator registry. This per-op note is generated by tools/opdocs.py md (do not hand-edit).*
© 2026 Kazufumi Furuse — Fullseye operator documentation. Licensed under Apache-2.0.