toupy.restoration package

Submodules

toupy.restoration.GUI_tracker module

class toupy.restoration.GUI_tracker.AmpTracker(fig, ax1, ax2, X1, **params)[source]

Bases: PhaseTracker

Widgets for air removal from amplitude projections.

Inherits navigation, mask drawing, I/O, and display from PhaseTracker. Overrides the correction methods to apply rmair() followed by a logarithm instead of phase-ramp removal.

apply_all_masks(event)[source]

Normalise air + log for all uncorrected projections.

apply_mask(event)[source]

Normalise air, apply log; guards against double-correction.

class toupy.restoration.GUI_tracker.PhaseTracker(fig, ax1, ax2, X1, **params)[source]

Bases: object

Widgets for interactive phase-ramp removal.

This class is not normally instantiated directly — use gui_plotphase() instead.

add_mask(event)[source]

Apply the drawn polygon to the current projection’s mask.

apply_all_masks(event)[source]

Remove phase ramp from all projections using their masks.

apply_mask(event)[source]

Remove phase ramp from the current projection using its mask.

cmvmax(val)[source]

Set colormap vmax.

cmvmin(val)[source]

Set colormap vmin.

down(event)[source]

Previous projection button.

draw_mask(event)[source]

Attach a PolygonSelector to the main image axes for mask drawing.

Left-click to add vertices; click the first vertex again (or press Enter in matplotlib ≥ 3.7) to close and finalise the polygon. Then click add mask (or another mask button) to apply it.

The selector is drawn directly on ax1 — no separate figure is opened. Any previously unfinished selector is discarded first.

key_event(event)[source]

Left/right arrow key navigation.

load_masks(event)[source]

Load masks from masks.h5.

mask_all(event)[source]

Copy the current polygon to every projection.

onclose(event)[source]

Close the GUI figure.

onscroll(event)[source]

Scroll wheel navigation.

play(event)[source]

Play through all projections from the current index.

Click stop (or press the stop button) to halt the animation at the current frame.

Each frame is rendered synchronously so the animation is actually visible. draw_idle() (used by update()) schedules an async repaint that never fires inside a tight Python loop; we force a synchronous draw() + flush_events() after each frame to push the data to the screen. flush_events() also pumps the GUI event queue so the stop button callback can fire mid-loop.

remove_all_mask(event)[source]

Remove the drawn polygon from every projection’s mask.

remove_mask(event)[source]

Remove the drawn polygon from the current projection’s mask.

remove_ramp(event)[source]

Remove linear phase ramp from the current projection (no mask).

remove_rampall(event)[source]

Remove linear phase ramp from all projections (no mask).

save_masks(event)[source]

Save masks to masks.h5.

stop_play(event)[source]

Request that the play loop stop at the current frame.

submit(text)[source]

Jump to a projection number via the text box.

unwrapping_all(event)[source]

Unwrap phase of all projections.

unwrapping_phase(event)[source]

Unwrap phase of the current projection.

up(event)[source]

Next projection button.

update()[source]

Refresh the canvas after any state change.

toupy.restoration.GUI_tracker.gui_plotamp(stack_objs, **params)[source]

GUI for air removal from amplitude projections.

Parameters:
  • stack_objs (array_like, shape (nprojs, nr, nc)) – Stack of amplitude projections.

  • **params (dict) –

    crop_reglist or None

    [left, bottom, right, top] pixels to crop.

    vmin, vmaxfloat or None

    Colormap limits.

    colormapstr

    Matplotlib colourmap name.

    autosavebool

    Save projections automatically on load.

    correct_badbool

    Interpolate bad projections listed in bad_projs.

    bad_projslist of int

    Projections to interpolate (0-indexed).

Returns:

tracker – Tracker object holding the corrected stack in tracker.X1.

  • Script modeplt.show(block=True) has already returned before this function returns; tracker.X1 is ready immediately:

    tracker = gui_plotamp(stack_objs, **params)
    stack_ampcorr = tracker.X1.copy()
    
  • Notebook mode (requires %matplotlib widget) — the function returns immediately; interact with the GUI in the cell output, then access results in the next cell:

    tracker = gui_plotamp(stack_objs, **params)
    # ── next cell ──
    stack_ampcorr = tracker.X1.copy()
    

Return type:

AmpTracker

toupy.restoration.GUI_tracker.gui_plotphase(stack_objs, **params)[source]

GUI for phase-ramp removal from phase projections.

Parameters:
  • stack_objs (array_like, shape (nprojs, nr, nc)) – Stack of phase projections (float, radians).

  • **params (dict) –

    crop_reglist or None

    [left, bottom, right, top] pixels to crop.

    hcenint

    Row index of the horizontal profile displayed below the image.

    vmin, vmaxfloat or None

    Colormap limits.

    colormapstr

    Matplotlib colourmap name.

    autosavebool

    Save projections automatically on load.

Returns:

tracker – Tracker object holding the corrected stack in tracker.X1.

  • Script modeplt.show(block=True) has already returned before this function returns; tracker.X1 is ready immediately:

    tracker = gui_plotphase(stack_objs, **params)
    stack_phasecorr = tracker.X1.copy()
    
  • Notebook mode (requires %matplotlib widget) — the function returns immediately; interact with the GUI in the cell output, then access results in the next cell:

    tracker = gui_plotphase(stack_objs, **params)
    # ── next cell ──
    stack_phasecorr = tracker.X1.copy()
    

Return type:

PhaseTracker

toupy.restoration.GUI_tracker.make_air_mask(image, cmap='gray', vmin=None, vmax=None, figsize=(8, 7))[source]

Interactively draw one or more polygon regions on image and return a cumulative boolean mask.

Opens a figure with the image and two buttons:

  • Add region — commits the current polygon to the mask; a permanent dashed outline marks it; you can immediately draw the next polygon.

  • Finish — closes the figure (any in-progress polygon with ≥ 3 vertices is committed automatically).

Draw each polygon by left-clicking vertices directly on the image. The polygon closes visually once you have ≥ 3 points. Click Add region to store it, then draw the next one. No Enter key or precise “click first vertex to close” is needed.

This is the lightweight notebook alternative to the full gui_plotphase() / gui_plotamp() GUI (which is better suited to terminal use).

Important

Jupyter notebook — two-cell workflow. make_air_mask returns immediately (non-blocking) so that the figure widget can be displayed. Do not put painter.mask access in the same cell — the cell will have finished executing before you interact with the figure, and the mask will be empty. Always use two separate cells:

# Cell 1 — show the figure and draw
painter = make_air_mask(stack[0], vmin=-1.6, vmax=1.6)

# Cell 2 — run AFTER clicking Finish in the figure above
air_mask = painter.mask.copy()

Backend requirements

  • Terminal / IPython — works with any backend; blocks until the figure is closed.

  • JupyterLab — requires %matplotlib widget (pip install ipympl). Put it as the first cell of your notebook and restart the kernel.

  • Classic Jupyter Notebook%matplotlib widget (preferred) or %matplotlib notebook (built-in, no install).

  • ``%matplotlib inline`` — not interactive; a UserWarning explains how to switch.

param image:

2-D image to display (e.g. one slice from the projection stack).

type image:

array_like, shape (ny, nx)

param cmap:

Colourmap name. Default 'gray'.

type cmap:

str, optional

param vmin:

Colormap limits.

type vmin:

float or None, optional

param vmax:

Colormap limits.

type vmax:

float or None, optional

param figsize:

Figure size (width, height) in inches. Default (8, 7).

type figsize:

tuple of float, optional

returns:

painter – Object whose .mask attribute (ndarray of bool, shape (ny, nx)) is the union of all added regions. .n_regions counts how many polygons were added.

rtype:

_MaskPainter

Examples

Terminal / IPython (single cell, blocks until Finish is clicked):

from toupy.restoration import make_air_mask, rmphaseramp
import numpy as np

painter = make_air_mask(stack[0], vmin=-1.6, vmax=1.6)
air_mask = painter.mask.copy()   # available immediately after return

corrected = np.stack([
    np.angle(rmphaseramp(np.exp(1j * proj),
                         weight=air_mask, zero_air_phase=True))
    for proj in stack
])

JupyterLab (%matplotlib widget + pip install ipympl once, two separate cells):

# ── Cell 1 ── draw the mask (returns immediately)
painter = make_air_mask(stack[0], vmin=-1.6, vmax=1.6)

# ── Cell 2 ── run after clicking Finish in the figure above
air_mask = painter.mask.copy()

toupy.restoration.derivativetools module

toupy.restoration.derivativetools.calculate_derivatives(stack_array, roiy, roix, shift_method='fourier', symmetric=True, n_cpus=-1)[source]

Compute projection derivatives over a stack of images.

Parameters:
  • stack_array (array_like, shape (nprojs, nr, nc)) – Input stack of projection images.

  • roiy (range or tuple) – Row and column limits of the ROI.

  • roix (range or tuple) – Row and column limits of the ROI.

  • shift_method (str, optional) – Passed to derivatives(). Default "fourier".

  • symmetric (bool, optional) – Passed to derivatives() (fourier path only). Default True.

  • n_cpus (int, optional) –

    Number of CPU cores / threads.

    • "fourier" — passed as workers to scipy.fft.fft(), which parallelises across all rows of all projections in a single call (no Python loop).

    • Other methods — ignored; each C extension manages its own threading internally.

    -1 (default) uses all available cores.

Returns:

aligned_diff – Stack of derivative images.

Return type:

ndarray, shape (nprojs, roi_nr, roi_nc)

toupy.restoration.derivativetools.calculate_derivatives_fft(stack_array, roiy, roix, n_cpus=-1)[source]

Deprecated since version Use: calculate_derivatives() with shift_method="fourier" instead.

toupy.restoration.derivativetools.chooseregiontoderivatives(stack_array, **params)[source]

Interactively choose the region of interest for derivative computation.

Opens a GUI figure showing the first projection with the current ROI (from params) overlaid in red. Click two corners to redefine the rectangle, then click Confirm.

Parameters:
  • stack_array (ndarray, shape (n, nr, nc)) – Stack of projection images.

  • **params

    Must contain:

    deltaxint

    Initial horizontal margin (pixels) from the left/right edges.

    limsytuple of int

    Initial (row_start, row_end) vertical limits.

Returns:

  • Terminal mode(roix, roiy) — both are range objects, ready to use.

  • Jupyter mode (two-cell workflow)picker (_DerivROIPicker) — access picker.roix and picker.roiy in the next cell after clicking Confirm.

toupy.restoration.derivativetools.derivatives(input_array, shift_method='fourier', symmetric=True, n_cpus=-1)[source]

Calculate the horizontal derivative of a 2-D image.

Parameters:
  • input_array (array_like) – Input 2-D image.

  • shift_method (str, optional) –

    Shift / differentiation method.

    "fourier" (default)

    Pure FFT symmetric-difference filter. Applied directly via scipy.fft.fft() — no ShiftFunc overhead. Supports the symmetric and n_cpus parameters.

    "spline", "linear"

    Sub-pixel shift via ShiftFunc (always symmetric ±0.5 px). symmetric and n_cpus are ignored for these methods.

  • symmetric (bool, optional) – Only used when shift_method="fourier". If True (default), applies a symmetric ±½-pixel difference (filter 2i·sin(π f)). If False, applies a forward 1-pixel difference (filter exp(2πi f) 1).

  • n_cpus (int, optional) – Number of threads passed to scipy.fft.fft(). Only used when shift_method="fourier". -1 (default) uses all available cores.

Returns:

diffimg – Derivative image (same shape as input_array).

Return type:

ndarray

toupy.restoration.derivativetools.derivatives_fft(input_img, symmetric=True, n_cpus=-1)[source]

Deprecated since version Use: derivatives() with shift_method="fourier" instead.

toupy.restoration.derivativetools.derivatives_sino(input_sino, shift_method='fourier')[source]

Calculate the derivative of the sinogram along the radial direction.

Parameters:
  • input_sino (array_like) – Input sinogram.

  • shift_method (str, optional) – Passed to derivatives(). Default "fourier".

Returns:

diffsino – Derivative of the sinogram along the radial direction.

Return type:

array_like

toupy.restoration.derivativetools.gradient_axis(x, axis=-1)[source]

Compute the forward-difference gradient along one axis, preserving shape.

Unlike numpy.gradient(), this function keeps all dimensions unchanged and sets the last slice along the chosen axis to zero.

Parameters:
  • x (ndarray, shape (..., M, N)) – Input 2-D (or higher-dimensional) array.

  • axis (int, optional) – Axis along which to compute the difference. -1 (default) computes the difference along columns; 0 computes it along rows.

Returns:

Array of the same shape as x containing the forward finite differences along axis.

Return type:

ndarray

toupy.restoration.ramptools module

toupy.restoration.ramptools.normalize_projections_phase(stack, border=0)[source]

Remove residual per-projection phase offsets from a stack of projections.

After rmphaseramp(), individual projections may still carry small projection-to-projection phase variations that appear as vertical stripes in sinograms. This function corrects them in a second pass using the sinogram itself:

  • Rows that are consistently air at all angles have low phase variance across the stack (object rows vary strongly with angle).

  • Otsu thresholding on the per-row standard-deviation separates air rows (low std) from object rows (high std) automatically.

  • For each projection the residual offset is the circular mean phase over the detected air rows; this is subtracted so that all projections share the same air phase reference.

Parameters:
  • stack (array_like, shape (nprojs, nr, nc)) –

    Stack of ramp-corrected projections. Accepted types:

    • complex — direct output of rmphaseramp(). The function returns a complex array; extract the phase sinogram with np.angle(normalized).

    • real (float) — phase values already extracted via np.angle(). The function returns a float array of the same dtype; use it directly as the sinogram.

    Warning

    Do not pass np.real(rmphaseramp(...)). That gives the real part of the complex projection (amplitude·cos φ), not the phase. Use np.angle(rmphaseramp(...)) or pass the complex array directly.

  • border (int, optional) – Number of pixels to exclude from each edge — should match the border value used in rmphaseramp(). Default 0.

Returns:

  • normalized (ndarray, shape (nprojs, nr, nc)) – Stack with per-projection offsets removed. Same dtype as stack (complex if complex in, float if float in).

  • offsets (ndarray, float, shape (nprojs,)) – Per-projection phase offsets that were subtracted (radians). Relative to the stack circular mean, so they sum to approximately zero.

Examples

Option A — complex stack (direct output of rmphaseramp):

>>> corrected = np.array([
...     rmphaseramp(proj, weight='auto', zero_air_phase=True, border=30)
...     for proj in stack
... ])                                         # complex, shape (N, nr, nc)
>>> corrected, offsets = normalize_projections_phase(corrected, border=30)
>>> sinogram = np.angle(corrected)             # float sinogram

Option B — float phase stack:

>>> phase_stack = np.array([
...     np.angle(rmphaseramp(proj, weight='auto', zero_air_phase=True, border=30))
...     for proj in stack
... ])                                         # float, shape (N, nr, nc)
>>> phase_stack, offsets = normalize_projections_phase(phase_stack, border=30)
>>> sinogram = phase_stack                     # already float
toupy.restoration.ramptools.rmair(image, mask)[source]

Normalise an amplitude image so that the air/vacuum region has mean 1.

Parameters:
  • image (array_like) – Amplitude-contrast image.

  • mask (array_like of bool) – Boolean array indicating the air/vacuum region.

Returns:

normalizedimage – Image divided by the mean air value.

Return type:

ndarray

toupy.restoration.ramptools.rmlinearphase(image, mask=None, weight='auto')[source]

Deprecated since version Use: rmphaseramp() instead — it covers all cases and has additional features (border, n_iter, return_phaseramp).

Migration guide:

Old call

New equivalent

rmlinearphase(image)

rmphaseramp(image, weight='auto')

rmlinearphase(image, mask=mask)

rmphaseramp(image, weight=mask, zero_air_phase=True)

Remove the linear phase ramp from a complex ptychographic image.

Parameters:
  • image (array_like) – Input complex image.

  • mask (array_like of bool, optional) – Boolean array marking the air/vacuum region (True = air). If None, air is detected automatically via Otsu thresholding.

  • weight (str, optional) – Only used when mask=None. Passed to rmphaseramp(). Default 'auto'.

Returns:

im_output – Linear-ramp-corrected image.

Return type:

ndarray, complex

toupy.restoration.ramptools.rmphaseramp(a, weight=None, return_phaseramp=False, n_iter=1, zero_air_phase=False, border=0)[source]

Remove the linear phase ramp from a complex ptychographic image.

This is the single entry point for all phase-ramp correction tasks, including the role previously filled by rmlinearphase(). Pass a boolean mask as weight together with zero_air_phase=True to replicate the old rmlinearphase(image, mask=mask) call exactly.

Parameters:
  • a (array_like) – Input complex 2-D image.

  • weight ({None, 'median', 'abs', 'auto'} or array_like, optional) –

    Strategy for estimating the ramp slope.

    None / 'median'

    Global median phase gradient. Robust to object contamination as long as air covers more than 50 % of the image.

    'abs'

    Amplitude-weighted mean gradient (original Ptypy behaviour).

    'auto'

    Automatically detect the air region from the amplitude image using Otsu thresholding (air = high amplitude). Reliable even when the air region is small, provided amplitude contrast between air and object is detectable.

    array_like (boolean or float)

    Custom mask / weight array (same shape as a). A boolean or 0/1 integer array is treated as a binary air mask: ramp slope is estimated via the median within the mask, and zero_air_phase=True uses the circular mean over those pixels to zero the air phase. A continuous float array uses a modulus-weighted mean instead.

    Replacing rmlinearphase() with a mask: rmlinearphase(image, mask=mask)rmphaseramp(image, weight=mask, zero_air_phase=True)

  • return_phaseramp (bool, optional) – If True, also return the total correction phasor p. Default False.

  • n_iter (int, optional) – Number of self-consistent refinement iterations. Only active when weight is None / 'median' (no prior mask supplied). After the first correction, pixels whose corrected phase is close to zero are identified as air and used to refine the ramp estimate. Default 1 (single pass, no refinement).

  • zero_air_phase (bool, optional) –

    If True, apply a global phase offset after ramp removal so that the mean phase over the air/vacuum region is exactly zero.

    The air phase offset is estimated by two strategies, chosen automatically:

    • Circular mean (used when weight='auto' or a binary mask is supplied): the already-computed air mask is reused. Fast and precise when the mask correctly identifies the air region.

    • Phase histogram mode (fallback for weight=None/'median'/ 'abs'): finds the dominant peak in the interior phase histogram via a two-step smoothed + raw argmax + parabolic interpolation. Robust even without an explicit mask, and tolerant of bright reconstruction artefacts inside the image border.

    Default False.

  • border (int, optional) – Number of pixels to exclude from each edge before computing the Otsu threshold, gradient estimation, and phase-offset correction. In ptychography, scan positions at the image boundary often lack proper overlap, producing strong noise artefacts that corrupt the ramp estimate. Set this to approximately (beam diameter) / (scan step) pixels to remove these artefacts entirely. Default 0 (no exclusion).

Returns:

  • out (ndarray, complex) – Ramp-corrected image.

  • p (ndarray, complex) – Total correction phasor (only returned when return_phaseramp=True).

Notes

Forked from Ptypy (https://github.com/ptycho/ptypy), ported to Python 3, and extended with robust estimation strategies.

rmlinearphase() is now a deprecated wrapper around this function and will be removed in a future version.

Examples

Fully automatic (no mask needed):

>>> b = rmphaseramp(image, weight='auto', zero_air_phase=True)

With border exclusion (ptychography scan-boundary noise):

>>> b = rmphaseramp(image, weight='auto', zero_air_phase=True, border=55)

With a hand-drawn air mask (replaces rmlinearphase):

>>> b = rmphaseramp(image, weight=air_mask, zero_air_phase=True)

Also return the correction phasor:

>>> b, p = rmphaseramp(image, weight='auto', zero_air_phase=True,
...                    return_phaseramp=True)

Iterative refinement (coarse initial estimate):

>>> b = rmphaseramp(image, n_iter=3)

toupy.restoration.roipoly module

toupy.restoration.unwraptools module

toupy.restoration.unwraptools.chooseregiontounwrap(stack_array, threshold=5000, parallel=False, ncores=1)[source]

Choose the region to be unwrapped interactively.

A GUI figure opens showing the first projection overlaid with phase-residue locations (red dots). Click three points in order:

  1. Top-left corner of the rectangular unwrap region.

  2. Bottom-right corner of the unwrap region.

  3. A pixel in air / vacuum (must be inside the rectangle).

Then click Confirm to accept, or Reset to start over.

Parameters:
  • stack_array (ndarray) – A 3-dimensional array containing the stack of projections to be unwrapped.

  • threshold (int, optional) – Threshold for the number of acceptable phase residues. (Default = 5000)

  • parallel (bool, optional) – If True, multiprocessing is used for residue computation. (Default = False)

  • ncores (int, optional) – Number of cores for parallel computation. (Default = 1)

Returns:

  • Terminal mode(rx, ry, airpix) — ranges and air-pixel tuple, ready to use.

  • Jupyter mode (two-cell workflow)picker_RegionPicker instance. Access picker.rx, picker.ry, picker.airpix in the next cell after clicking Confirm.

toupy.restoration.unwraptools.distance(pixel1, pixel2)[source]

Return the Euclidean distance between two pixels.

Parameters:
  • pixel1 (array_like) – Coordinates of the first pixel, e.g. (row, col).

  • pixel2 (array_like) – Coordinates of the second pixel, e.g. (row, col).

Returns:

Euclidean distance between pixel1 and pixel2.

Return type:

float

Examples

>>> distance(np.arange(1,10),np.arange(2,11))
3.0
toupy.restoration.unwraptools.get_charge(residues)[source]

Get the residues charges

Parameters:

residues (ndarray) – A 2-dimensional array containing the with residues

Returns:

  • posres (array_like) – Positions of the residues with positive charge

  • negres (array_like) – Positions of the residues with negative charge

toupy.restoration.unwraptools.phaseresidues(phimage)[source]

Calculates the phase residues [1] for a given wrapped phase image.

Parameters:

phimage (ndarray) – A 2-dimensional array containing the phase-contrast images with gray-level in radians

Returns:

residues – A 2-dimensional array containing the map of residues (valued +1 or -1)

Return type:

ndarray

Note

Note that by convention the positions of the phase residues are marked on the top left corner of the 2 by 2 regions as shown below:

graph g { node [shape=plaintext]; active -- right [label=" res4 "]; right -- belowright [label=" res3 "]; below -- belowright [label=" res2 "]; below -- active [label=" res1 "]; { rank=same; active right } { rank=same; belowright below } }

Inspired by PhaseResidues.m created by B.S. Spottiswoode on 07/10/2004 and by find_residues.m created by Manuel Guizar - Sept 27, 2011

References

toupy.restoration.unwraptools.phaseresiduesStack(stack_array, threshold=5000)[source]

Calculate the map of residues on the stack.

Parameters:
  • stack_array (ndarray) – A 3-dimensional array containing the stack of projections from which to calculate the phase residues.

  • threshold (int, optional) – Maximum number of acceptable phase residues per projection. Projections with more residues than threshold are flagged as problematic. Default 5000.

Returns:

  • resmap (ndarray) – 2-D phase residue accumulation map (sum of absolute residue maps across all projections).

  • posres (tuple of ndarray) – Indices (yres, xres) of pixels where resmap >= 1.

  • nres (int) – Total number of residues found in the last processed projection.

toupy.restoration.unwraptools.phaseresiduesStack_parallel(stack_array, threshold=1000, ncores=2)[source]

Calculate the map of residues on the stack using parallel processing.

Parameters:
  • stack_array (ndarray) – A 3-dimensional array containing the stack of projections from which to calculate the phase residues.

  • threshold (int, optional) – Maximum number of acceptable phase residues per projection. Projections with more residues than threshold are flagged as problematic. Default 1000.

  • ncores (int, optional) – Number of CPU cores for parallel computation. Default 2.

Returns:

  • resmap (ndarray) – 2-D phase residue accumulation map.

  • posres (tuple of ndarray) – Indices (yres, xres) of pixels where resmap >= 1.

  • nres (tuple of int) – Tuple of per-projection residue counts.

toupy.restoration.unwraptools.unwrap_phase_2d(phase, method='herraez', verbose=False)[source]

Unwrap a 2-D phase array using one of three internal algorithms.

Parameters:
  • phase (ndarray) – 2-D wrapped phase array (radians).

  • method (str, optional) –

    Algorithm to use. One of:

    "herraez" (default)

    Reliability-guided BFS. Computes a per-pixel reliability from second-order phase differences and processes pixel edges in decreasing reliability order via a priority queue. Generally the most robust choice for noisy data.

    Reference: M. A. Herraez, D. R. Burton, M. J. Lalor, and M. A. Gdeisat, “Fast two-dimensional phase-unwrapping algorithm based on sorting by reliability”, Applied Optics 41(35), 2002.

    "goldstein"

    Branch-cut algorithm. Locates phase residues, pairs them with a greedy nearest-neighbour strategy, draws L-shaped branch cuts, then unwraps via BFS flood fill from the image centre. Falls back to Flynn’s method when no residues are found.

    Reference: R. M. Goldstein, H. A. Zebker, and C. L. Werner, “Satellite radar interferometry: Two-dimensional phase unwrapping”, Radio Science 23(4), 1988.

    "flynn"

    Row-integration + median row correction. Integrates wrapped horizontal differences row by row, then corrects accumulated row-to-row offsets using a median estimator. O(N) complexity, fastest but least robust to noise.

    Reference: T. J. Flynn, “Two-dimensional phase unwrapping with minimum weighted discontinuity”, Journal of the Optical Society of America A 14(10), 1997.

    "wls"

    DCT-based unweighted least-squares (Ghiglia & Romero, 1994). Solves the 2-D Poisson equation whose right-hand side is the divergence of the wrapped phase gradients, using a DCT-II transform (Neumann boundary conditions). Globally optimal under a flat weight model; O(N log N) complexity. More robust than the greedy methods for densely wrapped, smooth phase fields.

    Reference: D. C. Ghiglia and L. A. Romero, “Robust two-dimensional weighted and unweighted phase unwrapping that uses fast transforms and iterative methods”, J. Opt. Soc. Am. A 11(1), 107-117 (1994).

    "snaphu"

    Statistical-cost network-flow algorithm (Chen & Zebker, 2001). Regarded as the gold standard for 2-D phase unwrapping. The per-pixel reliability map is used as a coherence estimate. Requires the optional package snaphu-py (pip install snaphu).

    Reference: C. W. Chen and H. A. Zebker, “Two-dimensional phase unwrapping with use of statistical models for cost functions in nonlinear optimization”, J. Opt. Soc. Am. A 18(2), 338-351 (2001).

  • verbose (bool, optional) – Only used when method='snaphu'. If False (default) SNAPHU’s extensive C-level log is suppressed and replaced by a single line. Set to True to see the full SNAPHU output.

Returns:

unwrapped – Float64 unwrapped phase array, same shape as phase.

Return type:

ndarray

Raises:
  • ValueError – If method is not one of the recognised algorithm names.

  • ImportError – If method='snaphu' and snaphu-py is not installed.

toupy.restoration.unwraptools.unwrapping_phase(stack_phasecorr, rx, ry, airpix, **params)[source]

Unwrap the phase of the projections in a stack.

Parameters:
  • stack_phasecorr (ndarray) – A 3-dimensional array containing the stack of projections to be unwrapped

  • rx (tuple or list of ints) – Limits of the are to be unwrapped in x and y

  • ry (tuple or list of ints) – Limits of the are to be unwrapped in x and y

  • airpix (tuple or list of ints) – Position of pixel in the air/vacuum area

  • **params

    Dictionary of additional parameters.

    vminfloat or None

    Minimum value for the gray level at each display.

    vmaxfloat or None

    Maximum value for the gray level at each display.

    unwrap_methodstr, optional

    Phase unwrapping algorithm to use. One of "herraez" (default), "goldstein", "flynn", "wls", or "snaphu". See unwrap_phase_2d() for details. "snaphu" requires the optional package snaphu-py (pip install snaphu).

    parallelbool, optional

    If True, use parallel processing. Default True.

    n_cpusint, optional

    Number of CPU cores for parallel computation. Pass -1 to use all available cores. Default -1.

Returns:

stack_unwrap – A 3-dimensional array containing the stack of unwrapped projections

Return type:

ndarray

Notes

Five algorithms are available. The default is the reliability-guided algorithm by Herraez et al. [2]. For the best robustness use "wls" (no extra dependency) or "snaphu" (requires pip install snaphu).

References

toupy.restoration.unwraptools.wrap(phase)[source]

Wrap a scalar value or an entire array to [-0.5, 0.5).

Parameters:

phase (float or array_like) – The value or signal to wrapped.

Returns:

Wrapped value or array

Return type:

float or array

Notes

Created by Sebastian Theilenberg, PyMRR, which is available at Github repository: https://github.com/theilen/PyMRR.git

toupy.restoration.unwraptools.wraptopi(phase, endpoint=True)[source]

Wrap a scalar value or an entire array

Parameters:
  • phase (float or array_like) – The value or signal to wrapped.

  • endpoint (bool, optional) – If endpoint=False, the scalar value or array is wrapped to [-pi, pi), whereas if endpoint=True, it is wrapped to (-pi, pi]. The default value is endpoint=True

Returns:

Wrapped value or array

Return type:

float or array

Examples

>>> import numpy as np
>>> wraptopi(np.linspace(-np.pi,np.pi,7),endpoint=True)
array([ 3.14159265, -2.0943951 , -1.04719755, -0.        ,  1.04719755,
    2.0943951 ,  3.14159265])
>>> wraptopi(np.linspace(-np.pi,np.pi,7),endpoint=False)
array([-3.14159265, -2.0943951 , -1.04719755,  0.        ,  1.04719755,
    2.0943951 , -3.14159265])

toupy.restoration.vorticestools module

toupy.restoration.vorticestools.cart2pol(x, y)[source]

Change from cartesian to polar coordinates

Parameters:
  • x (array_like) – Values in cartesian coordinates

  • y (array_like) – Values in cartesian coordinates

Returns:

rho, phi – Values in polar coordinates

Return type:

array_like

toupy.restoration.vorticestools.get_object_novort(img_phase, residues)[source]

Remove the vortices from the phase projections

Parameters:
  • img_phase (array_like) – Phase image with vortices to be removed without linear phase ramp

  • residues (array_like) – Residues map

Returns:

  • img_phase_novort (array_like) – Phase image without vortices

  • xres, yres (array_like) – Coordinates x and y of the vortices

toupy.restoration.vorticestools.get_probe_novort(img_phase, residues)[source]

Remove the vortices from the probe

Parameters:
  • img_phase (array_like) – Probe image with vortices to be removed without linear phase ramp

  • residues (array_like) – Residues map

Returns:

  • img_phase_novort (array_like) – Probe image without vortices

  • xres, yres (array_like) – Coordinates x and y of the vortices

toupy.restoration.vorticestools.pol2cart(rho, phi)[source]

Change from polar to cartesian coordinates

Parameters:
  • rho (array_like) – Values in polar coordinates

  • phi (array_like) – Values in polar coordinates

Returns:

x, y – Values in cartesian coordinates

Return type:

array_like

toupy.restoration.vorticestools.rmvortices_object(img_in, to_ignore=100)[source]

Remove phase vortices on the object image ignoring border pixels.

Parameters:
  • img_in (array_like) – Complex phase image with vortices to be removed.

  • to_ignore (int, optional) – Number of pixels to ignore from each border. Default 100.

Returns:

  • img_phase_novort (array_like) – Phase image without vortices.

  • xres (ndarray) – X-coordinates (columns) of the detected vortices.

  • yres (ndarray) – Y-coordinates (rows) of the detected vortices.

Notes

Any linear phase ramp present in the input image is removed before and after the vortex correction.

toupy.restoration.vorticestools.rmvortices_probe(img_in, to_ignore=100)[source]

Remove phase vortices on the probe image ignoring border pixels.

Parameters:
  • img_in (array_like) – Complex probe image with vortices to be removed.

  • to_ignore (int, optional) – Number of pixels to ignore from each border. Default 100.

Returns:

  • img_phase_novort (array_like) – Probe image without vortices.

  • xres (ndarray) – X-coordinates (columns) of the detected vortices.

  • yres (ndarray) – Y-coordinates (rows) of the detected vortices.

Notes

Any linear phase ramp present in the input image is removed before and after the vortex correction.