smlmlp.registrate_pcc_shift module

smlmlp.registrate_pcc_shift(optimized, /, ref_pix=1.0, fit_window=11, *, cuda=False, parallel=False)[source]

Estimate redundant pairwise shifts from phase cross-correlation images.

This function computes the phase cross-correlation between every pair of optimized channels and estimates a subpixel shift for each frame from the cross-correlation peak.

Parameters:
  • optimized (sequence of ndarray) – Sequence of optimized image, one per channel.

  • ref_pix (float or tuple of float, optional) – Reference pixel size used to convert shifts to physical units. If a scalar is provided, it is applied to both y and x as (ref_pix, ref_pix).

  • fit_window (int, optional) – Half-size of the square crop used for Gaussian peak fitting around the integer PCC maximum. The fitted crop side is 2*fit_window + 1. Can be passed positionally or by keyword.

  • cuda (bool, optional) – Whether to enable CUDA processing.

  • parallel (bool, optional) – Whether to enable parallel processing.

Returns:

A tuple (CC, shiftx, shifty, info) where:

  • CC is the list of phase cross-correlation stacks for all channel pairs,

  • shiftx is the list of per-frame x shifts for all channel pairs,

  • shifty is the list of per-frame y shifts for all channel pairs,

  • info is a dictionary containing reusable intermediate results.

The dictionary contains the following keys:

'ref_pix'

Reference pixel size used for shift conversion.

'pairs'

List of channel index pairs (i, j) corresponding to the cross-correlation and shift outputs.

Return type:

tuple

Notes

For each channel pair, the peak of the phase cross-correlation is detected on each frame. A local Gaussian fit is then performed on x/y profiles of a square crop around that maximum to estimate a robust subpixel offset.

Returned shifts follow registrate_transform convention, i.e. they are corrective shifts to apply to channel j in pair (i, j).

Examples

>>> import numpy as np
>>> ch1 = np.random.rand(16, 16).astype(np.float32)
>>> ch2 = np.random.rand(16, 16).astype(np.float32)
>>> CC, shiftx, shifty, info = registrate_pcc_shift([ch1, ch2])
>>> len(CC)
1
>>> info["pairs"]
[(0, 1)]
>>> ch3 = np.random.rand(16, 16).astype(np.float32)
>>> CC, shiftx, shifty, info = registrate_pcc_shift(
...     [ch1, ch2, ch3],
...     ref_pix=(100.0, 120.0),
... )
>>> len(info["pairs"])
3