corrct.alignment.fitting

Fitting routines.

Created on Tue May 17 12:11:58 2022

@author: Nicola VIGANÒ, Computational Imaging group, CWI, The Netherlands, and ESRF - The European Synchrotron, Grenoble, France

Module Contents

Classes

Trajectory

Base trajectory class.

Ellipse

Elliptic trajectory class.

Functions

fit_shifts_u_sad

Find the U shifts between two sets of lines, by means of the sum-of-absolute-difference (SAD).

fit_shifts_vu_xc

Find the VU shifts of the projected data, through cross-correlation.

fit_shifts_zyx_xc

Find the ZYX shifts of the volume, through cross-correlation.

fit_image_rotation_and_scale

Fit the rotation and scaling of an image against a reference image. This works best for larger rotation angles.

fit_camera_tilt_angle

Estimate the camera tilt angle based on correlation peak values between two images.

sinusoid

Compute the values of a sine function.

fit_sinusoid

Fits a sinusoid to the given values.

extract_peak_regions_1d

Extract a region around the maximum value.

refine_max_position_1d

Compute the sub-pixel max position of the given function sampling.

extract_peak_region_nd

Extract a region around the maximum value.

refine_max_position_2d

Compute the sub-pixel max position of the given function sampling.

fit_parabola_min

Parabolic fit local function stationary point.

fit_ellipse_center

Fit an ellipse center to a set of projected points in VU coordinates.

fit_ellipse_parameters

Fit ellipse parameters to a set of projected points in VU coordinates.

fit_ellipse

Fit an ellipse to a set of 2D points using either least-squares or l1-norm optimization.

Data

NDArrayFloat

eps

API

corrct.alignment.fitting.NDArrayFloat

None

corrct.alignment.fitting.eps

None

corrct.alignment.fitting.fit_shifts_u_sad(data_wu: corrct.alignment.fitting.NDArrayFloat, proj_wu: corrct.alignment.fitting.NDArrayFloat, search_range: int = 16, pad_u: bool = False, error_norm: int = 1, decimals: int = 2) corrct.alignment.fitting.NDArrayFloat[source]

Find the U shifts between two sets of lines, by means of the sum-of-absolute-difference (SAD).

Parameters

data_wu : NDArrayFloat The reference data. proj_wu : NDArrayFloat The other data. search_rage : int, optional The range in pixels of the search, by default 16 error_norm : int, optional The error norm to use, by default 1 decimals : int, optional The precision of the result, by default 2

Returns

NDArrayFloat A list of one shift for each row.

corrct.alignment.fitting.fit_shifts_vu_xc(data_vwu: corrct.alignment.fitting.NDArrayFloat, proj_vwu: corrct.alignment.fitting.NDArrayFloat, pad_u: bool = False, normalize_fourier: bool = False, margin: int = 0, use_rfft: bool = True, stack_axis: int = -2, decimals: int = 2) corrct.alignment.fitting.NDArrayFloat[source]

Find the VU shifts of the projected data, through cross-correlation.

Parameters

data_vwu : NDArrayFloat The collected projection data. proj_vwu : NDArrayFloat The forward-projected images from the reconstruction. pad_u : bool, optional Pad the u coordinate. The default is False. normalize_fourier : bool, optional Whether to normalize the Fourier representation of the cross-correlation. The default is False. margin : int, optional The margin of the region to compare, the default is 0. use_rfft : bool, optional Whether to use the rfft transform in place of the complex fft transform. The default is True. stack_axis : int, optional The axis along which the VU images are stacked. The default is -2. decimals : int, optional Decimals for the truncation of the sub-pixel The default is 2.

Returns

NDArrayFloat The VU shifts.

corrct.alignment.fitting.fit_shifts_zyx_xc(ref_vol_zyx: corrct.alignment.fitting.NDArrayFloat, rec_vol_zyx: corrct.alignment.fitting.NDArrayFloat, pad_zyx: bool = False, normalize_fourier: bool = True, use_rfft: bool = True, decimals: int = 2) corrct.alignment.fitting.NDArrayFloat[source]

Find the ZYX shifts of the volume, through cross-correlation.

Parameters

ref_vol_zyx : NDArrayFloat The reference volume. rec_vol_zyx : NDArrayFloat The reconstructed volume to register. pad_zyx : bool, optional Pad the ZYX coordinates. The default is False. normalize_fourier : bool, optional Whether to normalize the Fourier representation of the cross-correlation. The default is True. use_rfft : bool, optional Whether to use the rfft transform in place of the complex fft transform. The default is True. decimals : int, optional Decimals for the truncation of the sub-pixel The default is 2.

Returns

NDArrayFloat The ZYX shifts.

corrct.alignment.fitting.fit_image_rotation_and_scale(img_1_vu: numpy.typing.NDArray, img_2_vu: numpy.typing.NDArray, pad_mode: str | None = None, window_type: str = 'hann', verbose: bool = False) tuple[float, float][source]

Fit the rotation and scaling of an image against a reference image. This works best for larger rotation angles.

Parameters

img_1_vu : NDArray Reference image img_2_vu : NDArray Rotated and scaled image pad_mode : str | None, optional Padding mode, by default None window_type : str, optional Windowing type (to cud the high frequency aliasing), by default “hann” verbose : bool, optional Whether to give verbose output, by default False

Returns

tuple[float, float] The rotation (in degrees) and scale of the second image with respect to the first

Raises

ValueError In case of mismatching shape of the two images.

corrct.alignment.fitting.fit_camera_tilt_angle(img_1: numpy.typing.NDArray, img_2: numpy.typing.NDArray, pad_u: bool = False, fit_l1: bool = True, verbose: bool = False)[source]

Estimate the camera tilt angle based on correlation peak values between two images.

Parameters

img_1: NDArray The first image. img_2: NDArray The second image. pad_u: bool, optional Enable zero padding. Default is False. fit_l1: bool, optional Perform L1 norm fitting if True. Default is True. verbose: bool, optional Enable verbose output. Default is False.

Returns

tuple[float, float] Tuple containing the estimated center of rotation offset (pixels) and camera tilt angle (degrees).

corrct.alignment.fitting.sinusoid(x: corrct.alignment.fitting.NDArrayFloat | float, a: corrct.alignment.fitting.NDArrayFloat | float, p: corrct.alignment.fitting.NDArrayFloat | float, b: corrct.alignment.fitting.NDArrayFloat | float) corrct.alignment.fitting.NDArrayFloat[source]

Compute the values of a sine function.

Parameters

x : NDArrayFloat | float The independent variable. a : NDArrayFloat | float The amplitude of the sine. p : NDArrayFloat | float The phase of the sine. b : NDArrayFloat | float The bias of the sine.

Returns

NDArrayFloat The computed values.

corrct.alignment.fitting.fit_sinusoid(angles: corrct.alignment.fitting.NDArrayFloat, values: corrct.alignment.fitting.NDArrayFloat, fit_l1: bool = False) tuple[float, float, float][source]

Fits a sinusoid to the given values.

Parameters

angles : NDArrayFloat Angles where to evaluate the sinusoid. values : NDArrayFloat Values of the sinusoid. fit_l1 : bool, optional Whether to use l1 fit instead of the l2 fit, by default False

Returns

Tuple[float, float, float] The amplitude, phase and bias of the sinusoid.

corrct.alignment.fitting.extract_peak_regions_1d(cc: corrct.alignment.fitting.NDArrayFloat, axis: int = -1, peak_radius: int = 1, cc_coords: numpy.typing.ArrayLike | numpy.typing.NDArray | None = None) tuple[corrct.alignment.fitting.NDArrayFloat, numpy.typing.NDArray | None][source]

Extract a region around the maximum value.

Parameters

cc: NDArrayFloat Correlation image. axis: int, optional Find the max values along the specified direction. The default is -1. peak_radius: int, optional The l_inf radius of the area to extract around the peak. The default is 1. cc_coords: ArrayLike, optional The coordinates of cc along the selected axis. The default is None.

Returns

f_vals: NDArrayFloat The extracted function values. fc_ax: NDArrayFloat The coordinates of the extracted values, along the selected axis.

corrct.alignment.fitting.refine_max_position_1d(f_vals: corrct.alignment.fitting.NDArrayFloat, f_x: numpy.typing.ArrayLike | numpy.typing.NDArray | None = None, return_vertex_val: bool = False, decimals: int = 2) corrct.alignment.fitting.NDArrayFloat | tuple[corrct.alignment.fitting.NDArrayFloat, corrct.alignment.fitting.NDArrayFloat][source]

Compute the sub-pixel max position of the given function sampling.

Parameters

f_vals: NDArrayFloat Function values of the sampled points fx: ArrayLike, optional Coordinates of the sampled points return_vertex_val: boolean, option Enables returning the vertex values. Defaults to False.

Raises

ValueError In case position and values do not have the same size, or in case the fitted maximum is outside the fitting region.

Returns

float Estimated function max, according to the coordinates in fx.

corrct.alignment.fitting.extract_peak_region_nd(cc: corrct.alignment.fitting.NDArrayFloat, peak_radius: int = 1, cc_coords: collections.abc.Sequence[collections.abc.Sequence | numpy.typing.NDArray] | None = None) tuple[numpy.typing.NDArray, collections.abc.Sequence[numpy.typing.NDArray] | None][source]

Extract a region around the maximum value.

Parameters

cc: NDArrayFloat Correlation image. peak_radius: int, optional The l_inf radius of the area to extract around the peak. The default is 1. cc_coords: ArrayLike, optional The coordinates of cc. The default is None.

Returns

f_vals: NDArrayFloat The extracted function values. f_coords: Sequence[NDArrayFloat] | None The coordinates of the extracted values.

corrct.alignment.fitting.refine_max_position_2d(f_vals: corrct.alignment.fitting.NDArrayFloat, fy: numpy.typing.ArrayLike | numpy.typing.NDArray | None = None, fx: numpy.typing.ArrayLike | numpy.typing.NDArray | None = None) numpy.typing.NDArray[source]

Compute the sub-pixel max position of the given function sampling.

Parameters

f_vals: NDArrayFloat Function values of the sampled points fy: ArrayLike, optional Vertical coordinates of the sampled points fx: ArrayLike, optional Horizontal coordinates of the sampled points

Raises

ValueError In case position and values do not have the same size, or in case the fitted maximum is outside the fitting region.

Returns

tuple(float, float) Estimated (vertical, horizontal) function max, according to the coordinates in fy and fx.

corrct.alignment.fitting.fit_parabola_min(fun_x: numpy.typing.ArrayLike | numpy.typing.NDArray, fun_vals: numpy.typing.ArrayLike | numpy.typing.NDArray, scale: Literal[linear, log] = 'linear', decimals: int = 2) tuple[float, float, tuple[numpy.typing.NDArray, numpy.typing.NDArray] | None][source]

Parabolic fit local function stationary point.

Parameters

fx : ArrayLike Parameter values. f_vals : ArrayLike Objective function costs of each parameter value. scale : str, optional Scale of the fit. Options are: “log” | “linear”. The default is “log”.

Returns

min_fx : float Expected parameter value of the fitted minimum. min_f_val : float Expected objective function cost of the fitted minimum.

corrct.alignment.fitting.fit_ellipse_center(prj_points_vu: numpy.typing.NDArray, rescale: bool = True, use_l1_norm: bool = False, decimals: int | None = 2) numpy.typing.NDArray[source]

Fit an ellipse center to a set of projected points in VU coordinates.

The function uses a least-squares approach to fit an ellipse center to the given points. Optionally, it can use L1 norm for fitting instead of the default L2 norm, and rescale the points during fitting to have a maximum range of 1 (improve numerical stability).

Parameters

prj_points_vu : NDArray Projected points in VU coordinates. The expected organization is: - Last dimension: List of points (each point is a 2D coordinate). - First dimension: Coordinates (V and U). rescale : bool, optional If True, rescale the points to have a maximum range of 1. Default is True. use_l1_norm : bool, optional If True, use L1 norm for fitting instead of the default L2 norm. Default is False. decimals : int | None, optional The number of decimal places to round the result to. If None, no rounding is performed. Default is 2.

Returns

NDArray The fitted ellipse center in VU coordinates.

corrct.alignment.fitting.fit_ellipse_parameters(prj_points_vu: numpy.typing.NDArray, rescale: bool = True, use_l1_norm: bool = False) tuple[float, float, float, float, float][source]

Fit ellipse parameters to a set of projected points in VU coordinates.

Parameters

prj_points_vu : NDArray Projected points in VU coordinates. The expected organization is: - Last dimension: List of points (each point is a 2D coordinate). - First dimension: Coordinates (V and U). rescale : bool, optional If True, rescale the points to have a maximum range of 1. Default is True. use_l1_norm : bool, optional If True, use L1 norm for fitting instead of the default L2 norm. Default is False.

Returns

tuple[float, float, float, float, float] The fitted ellipse parameters: a, b, c, u, v.

class corrct.alignment.fitting.Trajectory[source]

Bases: abc.ABC

Base trajectory class.

abstract __call__(uus: collections.abc.Sequence[float] | numpy.typing.NDArray) collections.abc.Sequence[numpy.typing.NDArray][source]

Compute V coordinates, given V coordinates.

Parameters

uus : Sequence[float] | NDArray The U coordinates

Returns

Sequence[NDArray] Corresponding V coordinates, given the multiplicity of the trajectory

class corrct.alignment.fitting.Ellipse(a: float, b: float, c: float, u: float, v: float, c_vu: corrct.alignment.fitting.NDArrayFloat)[source]

Bases: corrct.alignment.fitting.Trajectory

Elliptic trajectory class.

Initialization

Initialize ellipse class.

Ellipse corresponding to the equation: a*(x - u)*2 + b(y - v)**2 + 2c(x - u)*(y - v) = 1

Parameters

a : float The semi-major axis of the ellipse. b : float The semi-minor axis of the ellipse. c : float The rotation angle of the ellipse in radians. u : float The center of the ellipse along the x-axis. v : float The center of the ellipse along the y-axis. c_vu : NDArrayFloat The projected center of the circular orbit generating the ellipse.

a: float

None

b: float

None

c: float

None

u: float

None

v: float

None

c_vu: corrct.alignment.fitting.NDArrayFloat

None

__repr__() str[source]

Return a string representation of the Ellipse instance.

property extremes_u: tuple[float, float]

Find the most extreme x coordinates (U coordinates) that are still valid for the given ellipse equation.

Returns

tuple[float, float] A tuple containing the most extreme U coordinates (u_min, u_max).

property center_vu: numpy.typing.NDArray

Return the fitted ellipse center.

Returns

NDArray The fitted center position.

property parameters: tuple[float, float, float, float, float]

Return the fitted ellipse parameters.

Returns

tuple[float, float, float, float, float] The fitted ellipse parameters: b, a, c, v, u.

__call__(uus: numpy.typing.ArrayLike | numpy.typing.NDArray) collections.abc.Sequence[numpy.typing.NDArray][source]

Predict V coordinates of ellipse from its parameters, and U coordinates.

Parameters

uus : Union[ArrayLike, NDArray] The U coordinates

Returns

tuple[NDArray, NDArray] The corresponding top and bottom V coordinates

corrct.alignment.fitting.fit_ellipse(prj_points_vu: numpy.typing.ArrayLike | numpy.typing.NDArray, rescale: bool = True, use_l1_norm: bool = False) corrct.alignment.fitting.Ellipse[source]

Fit an ellipse to a set of 2D points using either least-squares or l1-norm optimization.

Parameters

prj_points_vu : ArrayLike | NDArray A list or array of 2D points (shape: Nx2) representing the trajectory to fit. rescale : bool, optional Whether to rescale the data within the interval [-1, 1] to improve numerical stability. Default is True. use_l1_norm : bool, optional Whether to use the l1-norm or the least-squares (l2-norm) fit for optimization. Default is False.

Returns

Ellipse An Ellipse object containing the fitted ellipse parameters (center, axes, and rotation angle).

Notes

The function first fits the ellipse parameters (axes and rotation angle) and then fits the center separately. The optimization method can be switched between least-squares and l1-norm for robustness against outliers.