epdfsuite.utilities
Functions
|
Compute the radially-averaged DQE from flat-field and dark-field images. |
|
Compute the MTF using the slanted-edge method, with automatic edge angle and position detection via Hough transform. |
|
Wiener 2D MTF deconvolution with optional high-frequency roll-off. |
|
Richardson-Lucy 2D deconvolution with a radial MTF. |
|
Deconvolve an image using a DQE-weighted Wiener filter. |
|
Detect the dominant straight edge in an image using the Hough transform. |
|
Launch the pyFAI-drawmask GUI to interactively draw a pixel mask. |
|
Estimate the Wiener regularisation parameter epsilon from image data. |
|
Extract noise and signal pixel patches on each side of the detected edge. |
- epdfsuite.utilities.draw_mask(dm4_image)[source]
Launch the pyFAI-drawmask GUI to interactively draw a pixel mask.
The input DM4 image is temporarily exported as an EDF file, passed to the
pyFAI-drawmasktool, then the EDF file is deleted. The mask produced by the GUI is saved alongside the image by pyFAI.- Parameters:
dm4_image (str) – Path to the DM4 image file.
- epdfsuite.utilities.detect_edge_angle_hough(edge_data, sigma=1, erosion_px=10, num_peaks=5, plot=False)[source]
Detect the dominant straight edge in an image using the Hough transform.
The pipeline is: normalise → erode NaN mask → Canny edge detection → standard Hough transform (0.05° angular resolution) → extract dominant peak.
- Parameters:
edge_data (ndarray) – 2D image, possibly with NaN pixels marking invalid regions.
sigma (float, optional) – Gaussian smoothing sigma passed to the Canny detector. Default is 1. Use 1–2 for quasi-binary (beamstop/background) images.
erosion_px (int, optional) – Number of pixels to erode from the border of the valid mask before running Canny, to avoid false edges at mask boundaries. Default is 10.
num_peaks (int, optional) – Maximum number of peaks to extract from the Hough accumulator. Only the strongest peak is used. Default is 5.
plot (bool, optional) – If
True, display diagnostic plots of the masked image, Canny edges, and the Hough accumulator. Default isFalse.
- Returns:
line_angle_rad (float) – Angle of the detected edge line with respect to the horizontal, in radians.
line_angle_deg (float) – Same angle in degrees.
edge_point (tuple of float) –
(x, y)coordinates of the point on the line at mid-image height.edge_line (tuple) –
(theta, rho, line_angle_deg)— Hough normal angle (rad), signed distance from origin (px), and line angle (deg).
- epdfsuite.utilities.compute_mtf_slanted_edge(image_path, mask=None, pixel_size=None, binning_factor=1, roi_half_width=15, nbins=500, smooth_sigma=0.5, use_erf_fit=True, plot=True, outputfile=None)[source]
Compute the MTF using the slanted-edge method, with automatic edge angle and position detection via Hough transform.
- Parameters:
image_path (str - Path to the image file.)
mask (str - Path to a fabio mask file (0=valid, 1=masked).)
pixel_size (float - Pixel size in µm.)
binning_factor (int - Binning factor applied to the detector (default 1).)
roi_half_width (int - Half-width of the band around the edge (pixels).)
nbins (int - Number of sub-pixel bins for the ESF.)
smooth_sigma (float - Sigma of the Gaussian smoothing applied to the ESF.)
use_erf_fit (bool - Fit the ESF with an error function before differentiation.)
plot (bool - Display diagnostic plots.)
outputfile (str - If provided, save the MTF to this text file.)
- Returns:
freq_pixel (1D array - Spatial frequencies (cycles/pixel))
mtf (1D array - Corresponding MTF values)
- epdfsuite.utilities.estimate_wiener_epsilon_spectral(noise_patch, signal_patch, subtract_noise=True)[source]
Estimate the Wiener regularisation parameter epsilon from image data.
Computes epsilon as the square root of the ratio of the mean power spectral densities (PSD) of the noise and signal patches:
epsilon = sqrt( <|N(f)|²> / <|S(f)|²> )This estimate is used to set the noise-to-signal power ratio in the Wiener filter:
W(f) = MTF / (MTF² + epsilon²).- Parameters:
noise_patch (ndarray) – 2D (or 1D) sub-image extracted from the beamstop region (dark, noisy side).
signal_patch (ndarray) – 2D (or 1D) sub-image extracted from the bright background region.
subtract_noise (bool, optional) – If
True(default), subtract the mean ofnoise_patchfromsignal_patchbefore computing the signal PSD, to account for any DC offset in the background.
- Returns:
epsilon (float) – Estimated noise-to-signal PSD ratio, suitable for use as
wiener_epsilonindeconvolve_mtf_2d().
- epdfsuite.utilities.extract_noise_and_signal_patches(image, edge_line, band_width=500, noise_box=None, erosion_px=5)[source]
Extract noise and signal pixel patches on each side of the detected edge.
The image is split along the Hough line into two regions: - signal patch (bright side,
d > +erosion_px): background pixels. - noise patch (dark side,d < -erosion_px): beamstop pixels.An erosion band of
erosion_pxpixels around the edge is excluded from both patches to avoid contamination by the edge transition itself. Diagnostic plots are displayed showing the two zones.- Parameters:
image (ndarray) – 2D image, with NaN for masked/invalid pixels.
edge_line (tuple) –
(theta, rho, angle_deg)as returned bydetect_edge_angle_hough().band_width (float, optional) – Total width of the extraction band centred on the edge (pixels). Default is 500.
noise_box (ignored) – Reserved for future use.
erosion_px (int, optional) – Width of the exclusion zone on each side of the edge (pixels). Default is 10.
- Returns:
signal_patch (ndarray) – 1D array of pixel values from the bright (background) side.
noise_patch (ndarray) – 1D array of pixel values from the dark (beamstop) side.
- epdfsuite.utilities.deconvolve_mtf_2d(image, mtf_file, clip=True, wiener_epsilon=None, min_epsilon=0.005, pre_smooth_sigma=0.5, use_rolloff=True, u_cutoff=0.4, rolloff_window='tukey', rolloff_alpha=0.5, rolloff_order=4, plot=False)[source]
Wiener 2D MTF deconvolution with optional high-frequency roll-off.
Applies a Wiener filter built from a radially symmetric MTF to restore spatial frequencies attenuated by the detector. An optional roll-off window suppresses noise amplification at high frequencies.
- Parameters:
image (ndarray) – 2D image to deconvolve.
mtf_file (str) – Path to the MTF file (3-column text: freq (cyc/px), MTF, epsilon).
clip (bool, optional) – If
True(default), clip negative values in the output to zero.wiener_epsilon (float or None, optional) – Regularisation parameter. If
None, read from column 3 ofmtf_file(floored atmin_epsilon).min_epsilon (float, optional) – Minimum allowed epsilon to prevent filter instability. Default is 0.005.
pre_smooth_sigma (float, optional) – Sigma (pixels) of Gaussian pre-smoothing applied before deconvolution to reduce Poisson noise amplification. Default is 0.5. Set to 0 to disable.
use_rolloff (bool, optional) – If
True(default), multiply the Wiener filter by a roll-off window to suppress noise at frequencies aboveu_cutoff.u_cutoff (float or None, optional) – Roll-off cutoff frequency in cycles/pixel (max 0.5 = Nyquist). If
None, automatically set to the frequency whereMTF = epsilon. Default is 0.4.rolloff_window ({‘tukey’, ‘hann’, ‘butterworth’}, optional) – Shape of the roll-off window. Default is
'tukey'.rolloff_alpha (float, optional) – For the Tukey window: fraction of the passband that is flat (0 = Hann, 1 = rectangular). Default is 0.5.
rolloff_order (int, optional) – For the Butterworth window: filter order (higher = steeper). Default is 4.
plot (bool, optional) – If
True, display the Wiener filter profile. Default isFalse.
- Returns:
image_deconv (ndarray) – Deconvolved image, same shape as
image. NaN pixels are preserved.
- epdfsuite.utilities.compute_dqe(flat_paths, dark_paths, mtf_file, gain_reference=None, n_freq=128, plot=False, save=None)[source]
Compute the radially-averaged DQE from flat-field and dark-field images.
The DQE is defined as:
\[\mathrm{DQE}(f) = \frac{\mathrm{MTF}^2(f)}{\bar{n} \cdot \mathrm{NPS}(f)}\]where \(\bar{n}\) is the mean number of electrons per pixel (signal level) and \(\mathrm{NPS}(f)\) is the normalised noise power spectrum:
\[\mathrm{NPS}(f) = \frac{1}{N_{\mathrm{img}}\, N_x N_y\, \bar{n}^2} \sum_k \left| \mathcal{F}\!\left[ I_k - \bar{I} \right](f) \right|^2\]The dark-field mean is subtracted from each flat-field image before computing the NPS, so that the detector read-noise is excluded from \(\bar{n}\) but its contribution to the NPS is correctly accounted for.
- Parameters:
flat_paths (list of str) – Paths to the flat-field (uniform illumination) images. At least 5 images are recommended for a stable NPS estimate; 20–50 are ideal.
dark_paths (list of str) – Paths to the dark-field (shutter closed) images. Used to estimate and subtract the detector dark offset.
mtf_file (str) – Path to the MTF file (columns: frequency in cyc/px, MTF value), as produced by
compute_mtf_slanted_edge().gain_reference (ndarray or None, optional) – 2D gain reference map (same shape as the images). When provided, each flat-field image is divided by
gain_referencebefore computing the NPS to correct for pixel-to-pixel sensitivity variations.Noneskips gain correction. Default isNone.n_freq (int, optional) – Number of radial frequency bins for the azimuthal average. Default is 128.
plot (bool, optional) – If
True, display MTF², NPS, and DQE curves. Default isFalse.save (str or None, optional) – If a file path is given, save the result as a two-column text file (frequency in cyc/px, DQE value) readable by
deconvolve_mtf_2d_rl(). Default isNone.
- Returns:
freq_bins (ndarray, shape (n_freq,)) – Radial frequency axis in cycles/pixel (0 to 0.5).
dqe (ndarray, shape (n_freq,)) – Radially-averaged DQE, values in [0, 1].
Notes
All images must have the same shape.
Images are expected to be in raw detector counts (electrons or ADU).
At very low dose the DQE drops because read noise dominates; at very high dose it drops due to detector non-linearity. Run this function at several dose levels to characterise the dose dependence.
- epdfsuite.utilities.deconvolve_mtf_dqe_2d(image, mtf_file, dqe_file)[source]
Deconvolve an image using a DQE-weighted Wiener filter.
This is a simplified version of
deconvolve_mtf_2d()that applies the DQE weighting directly to the Wiener filter without pre-smoothing or roll-off. The filter is:\[W(f) = \frac{\mathrm{DQE}(f)}{\mathrm{MTF}(f)}\]- Parameters
- imagendarray
2D image to deconvolve.
- mtf_filestr
Path to the MTF file (columns: frequency in cyc/px, MTF value, epsilon).
- dqe_filestr
Path to the DQE file (columns: frequency in cyc/px, DQE value).
- image_deconvndarray
Deconvolved image, same shape as
image. NaN pixels are preserved.
- epdfsuite.utilities.deconvolve_mtf_2d_rl(image, mtf_file, clip=True, n_iterations=50, tol=0.01, dqe_file=None, pre_smooth_sigma=0, verbose=False, plot=False)[source]
Richardson-Lucy 2D deconvolution with a radial MTF.
Suited to Poisson noise (electron/photon counting). Regularisation is implicit: too few iterations under-deconvolves; too many amplify noise.
The stopping criterion is the relative change of the current estimate u:
\[\text{rel} = \frac{\|u^{(k+1)} - u^{(k)}\|_\infty}{\|u^{(k)}\|_\infty} < \text{tol}\]DQE-weighted correction (optional)
When
dqe_fileis provided, the back-projection step is weighted by the 2D DQE map instead of the plain MTF conjugate:\[u^{(k+1)} = u^{(k)} \cdot \mathcal{F}^{-1}\!\left[ \mathrm{DQE}(f)\, H(f)\, \mathcal{F}\!\left[\frac{I}{h \circledast u^{(k)}}\right] \right]\]where \(\mathrm{DQE}(f) = \mathrm{MTF}^2(f) / (\bar{n}\,\mathrm{NPS}(f))\). Frequencies where \(\mathrm{DQE}(f) \approx 0\) (noise-dominated) are naturally suppressed at every iteration, making the algorithm less sensitive to the choice of
n_iterationsand removing the need forpre_smooth_sigmain most cases.Without
dqe_filethe standard R-L update is used and regularisation relies entirely on early stopping viatolandn_iterations.- Parameters:
image (ndarray) – 2D image to deconvolve.
mtf_file (str) – Path to the MTF file (columns: frequency in cyc/px, MTF value).
clip (bool, optional) – If
True, clamp negative values to 0 after each iteration. Default isTrue.n_iterations (int, optional) – Maximum number of iterations (safety cap). Default is 50.
tol (float or None, optional) – Early-stopping threshold on the relative change
||Δu||/||u||.Nonedisables early stopping. Default is1e-2.dqe_file (str or None, optional) – Path to the DQE file (same format as
mtf_file: columns are frequency in cyc/px and DQE value in [0, 1]). When provided, the correction at each iteration is weighted by the 2D DQE map, which suppresses noise-dominated frequencies without requiring aggressive early stopping or pre-smoothing.Nonedisables DQE weighting and reproduces the standard R-L behaviour. Default isNone.pre_smooth_sigma (float, optional) – Standard deviation (pixels) for Gaussian pre-smoothing applied before deconvolution.
0disables smoothing. Default is0.verbose (bool, optional) – If
True, print the relative change at each iteration. Default isFalse.plot (bool, optional) – If
True, display the PSF profile. Default isFalse.
- Returns:
image_deconv (ndarray) – Deconvolved 2D image.