Flat Panel QA: A Complete Toolkit for Digital X-ray Detector Characterisation
Why I built this
As a medical physicist dedicated to medical imaging devices, I characterise detectors and perform their corresponding QA tests on an annual basis. When it’s time to analyse the results of the QA tests, you need specialised software, and most tools are per-metric: one to get MTF, another one to get NPS, a third different one to get the contrast-detail curve, and so on. Not only are they quite expensive — even more so if you need the full pack — but most of the time they are kind of black boxes: you don’t know what happens under the hood and, suddenly, they drop a result, a number you have to trust. Or maybe sometimes they don’t meet your expectations: they don’t use the equations you want them to, or they make assumptions when they don’t have to.
After facing all these problems, I decided to start this project to gather all the metrics — all the software I needed — in one single web app. And what made it more attractive to me: since I was going to code the entire app and its computations, I would know what was happening when analysing the results.
Here I tell you about the very first feature I added to the app: flat panel QA.
What it does
Characterising a flat panel X-ray detector properly means more than running a quick uniformity check. A thorough QA programme requires quantifying spatial resolution, frequency-dependent noise, dose efficiency, and contrast detectability — following the same international standard across every measurement so results are comparable and reproducible.
The X-ray Imaging Analysis Toolkit is a Streamlit web application that implements the complete flat panel QA pipeline defined in IEC 62220-1-1:2015. It operates on raw, unprocessed detector images (“FOR PROCESSING”) to measure intrinsic detector performance, independent of any manufacturer post-processing.
The Analysis Pipeline
The six modules form a logical dependency chain where earlier analyses feed directly into later ones. Solid arrows indicate required inputs; dashed arrows indicate the optional kerma-domain mode enabled when the detector response fit is available.

Detector Response Characterisation
Everything else depends on knowing how the detector converts incident radiation into digital output. This module takes a series of flat-field exposures acquired at different dose levels and fits the MPV vs Air Kerma relationship:
| Image type | Fit model |
|---|---|
| RAW (linear encoding) | |
| STD (log-encoded) |
The fit method can be auto-detected from the DICOM tag (0028,1040) PixelIntensityRelationship. Results are characterised by and maximum deviation. The fitted prediction function — and its inverse — are cached in session state for use by every downstream module.
The same set of exposures also yields two additional analyses:
EI vs Air Kerma — A linear fit of the IEC 62494-1 Exposition Index against kerma (), enabling cross-manufacturer exposure level comparisons.
Noise Decomposition — The total variance across the measured kerma range is decomposed into three physical components:

The structural component is measured directly from repeated exposures at a single reference kerma level using the division method (Monnin et al., Phys. Med. Biol. 59, 2014). Dividing each frame by the pixel-wise mean across all frames normalises out the multiplicative fixed-pattern noise, isolating the stochastic (quantum + electronic) component. Electronic and quantum components are then separated by weighted linear extrapolation of the stochastic variance to .
Spatial Uniformity
A 30 mm × 30 mm moving ROI slides across the central 80% of a flat-field image with a 15 mm step. For each position, MPV, SD, and SNR are computed. Two levels of uniformity are reported:
Global Uniformity (GU) — Maximum deviation of any ROI from the overall mean:
Local Uniformity (LU) — The same metric computed relative to each ROI’s 8 immediate neighbours. This catches localised defects that global metrics can miss.
When the detector response fit is available in session state, the analysis can run entirely in kerma domain, providing a physics-based uniformity assessment expressed in dose units rather than arbitrary pixel values.
Modulation Transfer Function (MTF)
Spatial resolution is measured via the slanted edge method specified in IEC 62220-1-1:2015. The user uploads one or two RAW images of a lead or tungsten edge phantom tilted slightly off-axis.
Algorithm:
- Hough Transform detects the edge angle and orientation.
- Pixel values are projected perpendicular to the edge to build the Edge Spread Function (ESF), oversampled by the slant angle.
- The Line Spread Function (LSF) is computed as the numerical derivative of the ESF.
- The MTF is the magnitude of the Fourier Transform of the LSF: .
IEC 62220-1-1 requires edge angles of 3°–5° (horizontal) or 85°–87° (vertical). The UI reports angle compliance and flags any deviation from this range.
When two orthogonal edge images are provided, the module computes the geometric mean MTF:
This isotropic MTF is required as input to the DQE calculation.
Key metrics: (practical resolution limit) and (high-frequency cutoff), both in lp/mm.
Noise Power Spectrum (NPS)
The NPS quantifies frequency-dependent noise following IEC 62220-1-1:2015. One or more uniform flat-field images are accepted; multiple images improve statistical reliability (IEC recommends total analysed pixels).
Algorithm:
- A large central ROI (default 1024 px, adjustable 25–250 mm) is extracted from each image and subdivided into small ROIs (default 128 px).
- Each small ROI undergoes a 2D FFT; power spectra are averaged across all ROIs and all images.
- The result is normalised to yield the NNPS:
Outputs: radial-average NNPS () for display, plus directional X and Y profiles for detecting anisotropic noise such as scan-line artefacts. The raw 1D NPS in mm² is cached for DQE computation. A warning is issued if the analysed pixel count falls below the IEC threshold.
Detective Quantum Efficiency (DQE)
DQE is the single figure of merit for a digital X-ray detector — it quantifies what fraction of the dose reaching the detector is actually converted into useful signal information. The IEC 62220-1-1:2015 working formula is:
where is the photon fluence per unit kerma for the RQA5 beam quality specified by the standard, and is the air kerma in . NNPS here is the raw 1D NPS in mm².
Both MTF (geometric mean from two orthogonal edges) and NPS must be completed in the same session. The module interpolates them onto a common frequency grid (300 points across the intersection of their frequency ranges) and reports:
| Metric | Meaning |
|---|---|
| Low-frequency dose efficiency | |
| at | Frequency at which half the input is preserved |
| at | High-frequency cutoff |
Interpretation:
| Assessment | |
|---|---|
| 0.6–0.8 | Excellent (modern CsI/a-Si or Se-based panels) |
| 0.4–0.6 | Good (well-maintained system) |
| 0.2–0.4 | Fair (ageing or suboptimal configuration) |
| < 0.2 | Poor — investigation warranted |
Threshold Contrast Detail Detectability (TCDD)
TCDD estimates the minimum detectable contrast as a function of detail size, using the statistical method described by Paruccini et al. (2021). It operates on a flat-field image independently of MTF and NPS, but like Uniformity it benefits from the detector response fit when available — optionally converting pixel values to kerma domain before computing contrast thresholds.
From a uniform flat-field image, sub-ROIs of varying size are sampled across the central px region. For each detail size, the threshold contrast at 99.9% confidence is:
where is the standard deviation of sub-ROI means at that size. Results are normalised to the mean signal and expressed as a percentage.
The contrast-detail relationship is fitted to , and key values at and are reported for cross-system comparison.
IEC 62220-1-1:2015 Compliance
| IEC Requirement | Module | Implementation |
|---|---|---|
| Slanted edge MTF | MTF | Hough-based edge detection, ESF → LSF → FFT |
| Edge angle 3°–5° or 85°–87° | MTF | Angle detection with compliance flag |
| Geometric mean of orthogonal MTFs | MTF | Automatic when 2 images provided |
| NPS from pixels | NPS | Multi-image support with pixel count warning |
| NNPS normalisation | NPS | with unit conversion |
| DQE | RQA5 , raw NPS in mm² | |
| Detector response linearity | Detector Response | MPV vs kerma (linear or log), auto-detected from DICOM |
Under the hood
| Layer | Technology |
|---|---|
| Analysis engine | NumPy, SciPy, and a pinned fork of pylinac (EdgeMTF with Hough-based edge detection, NPS and TCDD routines) |
| Image I/O | pydicom for DICOM, plus raw-binary readers with endianness handling |
| User interface | Streamlit, with Altair and Matplotlib for plots |
| Offline mode | PWA service worker and a Pyodide client mode via stlite, with the whole Python runtime vendored as same-origin static files |
| Serving | nginx in front of Streamlit, adding the PWA layer without touching the app |
| Deployment | Docker Compose, images built in CI and published to GHCR, exposed through a Cloudflare Tunnel |
Choosing the stack
First of all, I chose Python because of the very helpful foundation of pylinac, developed by medical physicists, and Streamlit to speed up the whole process of bringing the app into production; it is simple and quick to develop apps with it. At the beginning, the app was designed to be hosted on a hospital server, so any physicist could reach and use it at the same time, rather than having to install the app on each computer. Then the Progressive Web App (PWA) solution came along and allowed me to have it both on a server and offline if needed.
During development, and although pylinac is incredibly helpful and I will always be indebted to its creators, I needed to change a few things, such as the MTF edge detection or the NPS ROI algorithm. I decided to fork the original repo and make my changes there, for a later pull request. Since a fork is not directly installable inside Pyodide, I had to build a wheel from it.
Finally, Docker and uv were the chosen tools for serving the app and testing it during development, respectively. They’re easy to work with and widely used.
What I learnt
By developing this web app, I truly understood all the physics that lies behind all the studied metrics; all of them come down to how signal and noise are processed through a physical system. And, beyond the physics, the main lesson I take home is how the byte order can change the stored image; this detail is rarely mentioned in manuals, papers or courses on medical imaging, but indeed not setting it correctly completely changes the image, both visually and in its analysis.
Getting Started
All modules are available in the web application. Upload your DICOM or RAW flat-field and edge phantom images and run the modules in pipeline order — each result feeds the next.
Last modified: 11 Nov 2026