Skip to main content

LCS and MIST frameworks for single-exposure multi-contrast X-ray imaging: transmission, phase, isotropic and directional dark-field retrieval

Project description

๐Ÿ”ฌ LCS-Retrieval โ€” Low Coherence System & MIST framework for multi-contrast X-ray imaging

PyPI version Python versions License: MIT Status


LCS-Retrieval implements two complementary frameworks for simultaneous retrieval of transmission, phase, isotropic dark-field, and directional dark-field from X-ray images:

  • LCS (Low Coherence System) โ€” implicit sliding-window least-squares solver based on the TIE + Fokkerโ€“Planck model
  • MIST (Multimodal Intrinsic Speckle Tracking) โ€” phase and dark-field retrieval via local contrast statistics and FFT-based inversion

Both frameworks share a unified orientation analysis pipeline for the directional scattering tensor (theta, anisotropy, HSV visualization).

Compatible with speckle-based, modulation-based, and single-grid X-ray imaging setups.

Based on the paper:

Implicit Single-Exposure Retrieval of X-ray Phase, Absorption, and Anisotropic Dark-Field Samy KEFS, Chris Ninham, Clara Magnin, Sabine Rolland du Roscoat, Pierre Lhuissier, Emmanuel Brun IEEE Transactions on Medical Imaging, 2025


๐Ÿš€ Overview

Conventional multi-contrast X-ray imaging requires multiple exposures or phase steps to separate absorption, phase, and scattering signals. LCS-Retrieval eliminates this need by reformulating the inverse problem locally within a sliding window around each pixel.

From a single pair of images (reference + sample), both methods retrieve:

Signal LCS symbol MIST symbol Description
๐Ÿ”ฒ Transmission T Iob Absorption contrast
๐ŸŒŠ Phase dy, dx phi Phase / wavefront
๐ŸŒ€ Isotropic dark-field DF Deff Overall scattering strength
๐Ÿงญ Directional dark-field Dxx, Dxy, Dyy Dxx, Dxy, Dyy Anisotropic scattering tensor

โœณ๏ธ Key Features

  • ๐Ÿ”น Single-exposure retrieval โ€” no phase stepping or mask motion required
  • ๐Ÿ”น LCS solver โ€” sliding-window least-squares on the TIE + Fokkerโ€“Planck model
  • ๐Ÿ”น MIST solver โ€” local contrast statistics + FFT-based Fokkerโ€“Planck inversion
  • ๐Ÿ”น Shared orientation pipeline โ€” lcs.hsv_retrieval() and lcs.ddf_metrics() work on both LCS and MIST outputs
  • ๐Ÿ”น Multi-exposure mode supported for both methods (win_size=1)
  • ๐Ÿ”น External absorption injection โ€” provide an independent T map for both LCS and MIST
  • ๐Ÿ”น HSV orientation visualization of the directional scattering tensor
  • ๐Ÿ”น Compatible with speckle-based, modulation-based, and single-grid setups

โš™๏ธ Installation

โ–ถ๏ธ From PyPI (recommended)

pip install LCS-Retrieval

To also install the dependencies for the example notebooks (matplotlib, fabio):

pip install LCS-Retrieval[examples]

โ–ถ๏ธ From source

git clone https://github.com/MuguiwaraSamy/LCS-Retrieval.git
cd LCS-Retrieval
pip install -e .

Requirements: Python โ‰ฅ 3.9, NumPy โ‰ฅ 2.0, SciPy โ‰ฅ 1.10


๐Ÿง  Quick start โ€” LCS

import lcs

# ref, sample: 2D arrays (H, W) or multi-exposure stacks (H, W, N)

# โ”€โ”€ Isotropic dark-field โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
result_df = lcs.lcs_df(ref, sample, win_size=5, alpha=1e-5)
# Output shape: (H', W', 4)
T  = result_df[..., 0]   # Transmission
dy = result_df[..., 1]   # Vertical refraction
dx = result_df[..., 2]   # Horizontal refraction
DF = result_df[..., 3]   # Isotropic dark-field

# โ”€โ”€ Directional dark-field โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
result_ddf = lcs.lcs_ddf(ref, sample, win_size=5, alpha=1e5)
# Output shape: (H', W', 6) โ†’ [T, dy, dx, Dxx, Dxy, Dyy]

# โ”€โ”€ HSV orientation visualization โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
rgb, metrics = lcs.hsv_retrieval(result_ddf, sigma=5.0)

๐Ÿง  Quick start โ€” MIST

import mist
import lcs  # shared orientation pipeline

energy     = 8                    # keV
wavelength = 12.398e-10 / energy  # X-ray wavelength in metres
dist_det   = 0.8                  # metres

# โ”€โ”€ Isotropic dark-field + phase โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
result_df = mist.mist_df(ref, sample, dist_det=dist_det, wavelength=wavelength, win_size=3)
phi  = result_df['phi']   # Phase map
Deff = result_df['Deff']  # Isotropic dark-field

# โ”€โ”€ Directional dark-field โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
result_ddf = mist.mist_ddf(
    ref, sample, gamma_mat=100, dist_det=dist_det, wavelength=wavelength, win_size=3
)
# Output shape: (H', W', 6) โ†’ [thickness, Iob, G, Dxx, Dxy, Dyy]
thickness = result_ddf[..., 0]
Iob       = result_ddf[..., 1]
G         = result_ddf[..., 2]

# โ”€โ”€ Shared orientation pipeline โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
rgb, metrics = lcs.hsv_retrieval(result_ddf, sigma=5.0)  # works on MIST too!

๐Ÿ—‚๏ธ Acquisition modes

Both methods support the same three modes:

Mode Input shape win_size
Single exposure + sliding window (H, W) odd integer โ‰ฅ 3
Multi-exposure (standard) (H, W, N) 1
Multi-exposure + sliding window (H, W, N) odd integer โ‰ฅ 3

๐Ÿงช External absorption image

Both methods accept an optional absorption argument. The solver divides sample by absorption before retrieval, and returns the provided map (cropped to the valid window region) in the T/Iob channel.

# T_abs: independently measured absorption image, shape (H, W)

# LCS
result_df  = lcs.lcs_df( ref, sample, win_size=5, absorption=T_abs)
result_ddf = lcs.lcs_ddf(ref, sample, win_size=5, absorption=T_abs)

# MIST
result_df  = mist.mist_df( ref, sample, dist_det=dist_det, wavelength=wavelength, absorption=T_abs)
result_ddf = mist.mist_ddf(ref, sample, gamma_mat=100, dist_det=dist_det,
                            wavelength=wavelength, absorption=T_abs)

๐Ÿ”— Shared orientation pipeline

Both lcs.lcs_ddf and mist.mist_ddf return a (H', W', 6) stack whose last 3 channels are always the scattering tensor [Dxx, Dxy, Dyy]. This means the orientation analysis functions work identically on both:

# Works with both lcs.lcs_ddf() and mist.mist_ddf() outputs
rgb, metrics = lcs.hsv_retrieval(result_ddf, sigma=5.0)
metrics      = lcs.ddf_metrics(result_ddf, sigma=5.0)

# Or directly on tensor components
metrics = lcs.tensor_metrics(Dxx, Dxy, Dyy, sigma=5.0)

metrics contains: theta, theta_smooth, coherence, aniso, traceS, major, minor, lambda_max, lambda_min, intensity


๐Ÿ“– API reference

LCS

lcs.lcs_df(ref, sample, *, win_size=5, alpha=1e-5, absorption=None)

Parameter Type Default Description
ref ndarray (H,W) or (H,W,N) โ€” Reference image(s)
sample ndarray (H,W) or (H,W,N) โ€” Sample image(s)
win_size int 5 Sliding window size (odd)
alpha float 1e-5 Tikhonov regularization
absorption ndarray (H,W) or None None External absorption image

Returns ndarray (H', W', 4) โ†’ [T, dy, dx, DF]

lcs.lcs_ddf(ref, sample, *, win_size=5, alpha=1e5, absorption=None)

Returns ndarray (H', W', 6) โ†’ [T, dy, dx, Dxx, Dxy, Dyy]


MIST

mist.mist_df(ref, sample, dist_det, wavelength, *, win_size=3, sig_scale=0.0, median_filter_size=0, alpha=1e5, absorption=None)

Parameter Type Default Description
ref ndarray (H,W) or (H,W,N) โ€” Reference image(s)
sample ndarray (H,W) or (H,W,N) โ€” Sample image(s)
dist_det float โ€” Sample-to-detector distance (m)
wavelength float โ€” X-ray wavelength in metres (12.398e-10 / energy_keV)
win_size int 3 Sliding window size (odd)
sig_scale float 0.0 Gaussian high-pass filter scale
median_filter_size int 0 Median filter on Deff (0 = off)
alpha float 1e5 Tikhonov regularization
absorption ndarray (H,W) or None None External absorption image

Returns dict โ†’ {'phi', 'Deff', 'phi_laplacian'}

mist.mist_ddf(ref, sample, gamma_mat, dist_det, wavelength, *, win_size=3, sig_scale=0.0, alpha=1e5, absorption=None)

Parameter Type Default Description
gamma_mat float โ€” Material delta/beta ratio
dist_det float โ€” Sample-to-detector distance (m)
wavelength float โ€” X-ray wavelength in metres (12.398e-10 / energy_keV)
sig_scale float 0.0 Gaussian high-pass filter scale
absorption ndarray (H,W) or None None External absorption image

Returns ndarray (H', W', 6) โ†’ [thickness, Iob, G, Dxx, Dxy, Dyy]


Shared orientation functions

lcs.hsv_retrieval(result_ddf, *, sigma=5.0, percentile=99.0, sat_min=0.0, sat_max=1.0, val_min=0.0, val_max=1.0)

Returns (rgb, metrics) โ€” works on both LCS and MIST outputs.

lcs.ddf_metrics(result_ddf, *, sigma=5.0)

Returns metrics dict โ€” works on both LCS and MIST outputs.

lcs.tensor_metrics(Dxx, Dxy, Dyy, *, sigma=5.0)

Returns metrics dict directly from tensor components.


๐Ÿ“˜ Example notebooks

Notebook Description
examples/example_lcs.ipynb LCS isotropic & directional dark-field
examples/example_mist.ipynb MIST phase, isotropic & directional dark-field

๐Ÿ–ฅ๏ธ ImageJ Plugin

A dedicated ImageJ/Fiji plugin for LCS retrieval is also available: ๐Ÿ‘‰ github.com/MuguiwaraSamy/LCS-ImageJ


๐Ÿ“„ Citation

If you use this package in your work, please cite:

@article{kefs2025lcs,
  title   = {Implicit Single-Exposure Retrieval of {X}-ray Phase, Absorption, and Anisotropic Dark-Field},
  author  = {Kefs, Samy and Ninham, Chris and Magnin, Clara and
             Rolland du Roscoat, Sabine and Lhuissier, Pierre and Brun, Emmanuel},
  journal = {IEEE Transactions on Medical Imaging},
  year    = {2025},
}

๐Ÿ“œ License

Distributed under the MIT License. ยฉ 2025 Samy KEFS. All rights reserved.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

lcs_retrieval-0.1.0.tar.gz (3.2 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

lcs_retrieval-0.1.0-py3-none-any.whl (15.6 kB view details)

Uploaded Python 3

File details

Details for the file lcs_retrieval-0.1.0.tar.gz.

File metadata

  • Download URL: lcs_retrieval-0.1.0.tar.gz
  • Upload date:
  • Size: 3.2 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.4

File hashes

Hashes for lcs_retrieval-0.1.0.tar.gz
Algorithm Hash digest
SHA256 97e327cf6809e0756068e014463e72be2943181b6c8a8bee4f00a183ab967794
MD5 b64ec08ee0203f7e674db6449f8b66cd
BLAKE2b-256 36f2d212e9d14d08616057625bc97b880b840ddf41525d05c7eb4b647240e9d4

See more details on using hashes here.

File details

Details for the file lcs_retrieval-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: lcs_retrieval-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 15.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.4

File hashes

Hashes for lcs_retrieval-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3332a93c022e233fec78a622c403c0c6c43c60b6edf064e40686c7c445b6c830
MD5 a4311c0b9993b999cbab04d66d79c404
BLAKE2b-256 117c3425ab4c920f016146082e703753eed7df271d81488b6bef100f8f5cf791

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page