Fréchet Radiomics Distance (FRD) — a metric for comparing medical image distributions
Project description
NEWS 1/9/26: 🎉 the FRD paper has been accepted to Medical Image Analysis 🎉!
FRD (Fréchet Radiomic Distance): A Metric Designed for Medical Image Distribution Comparison in the Age of Deep Learning
By Nicholas Konz*, Richard Osuala*, (* = equal contribution), Preeti Verma, Yuwen Chen, Hanxue Gu, Haoyu Dong, Yaqian Chen, Andrew Marshall, Lidia Garrucho, Kaisar Kushibar, Daniel M. Lang, Gene S. Kim, Lars J. Grimm, John M. Lewin, James S. Duncan, Julia A. Schnabel, Oliver Diaz, Karim Lekadir and Maciej A. Mazurowski.
Fréchet Radiomics Distance (FRD)
Project Website · Paper (Medical Image Analysis) · arXiv · Evaluation Framework · Documentation · API
FRD measures the similarity of radiomic image features between two datasets by computing the Fréchet distance between Gaussians fitted to the extracted and normalized features. The lower the FRD, the more similar the two datasets.
FRD supports both 2D (PNG, JPG, TIFF, BMP) and 3D (NIfTI .nii.gz) radiological images.
Why FRD over FID, KID, CMMD, etc.?
FRD uses standardised radiomic features rather than pretrained deep features (as in FID, KID, CMMD). We show in our paper that this yields:
- Better alignment with downstream task performance (e.g. segmentation).
- Improved stability and computational efficiency for small-to-moderately-sized datasets.
- Improved interpretability, because radiomic features are clearly defined and widely used in medical imaging.
FRD Versions
| FRDv0 (Osuala et al., 2024) | FRDv1 (Konz, Osuala et al., 2026) — default | |
|---|---|---|
| Features | ~94 (Original only) | ~464 (Original + LoG + Wavelet) |
| Normalization | min-max, joint | z-score, D1-referenced |
| Output | raw Fréchet distance | log-transformed Fréchet distance |
| Feature classes | firstorder, glcm, glrlm, gldm, glszm, ngtdm, shape, shape2D | firstorder, glcm, glrlm, glszm, ngtdm |
Installation
From PyPI (recommended)
pip install frd-score
Note:
frd-scorerequires pyradiomics, which must be installed separately from GitHub because the PyPI release is broken for Python ≥ 3.10 (#903):
pip install git+https://github.com/AIM-Harvard/pyradiomics.git@master
From Conda (conda-forge)
conda install -c conda-forge frd-score
The conda-forge package includes all dependencies (including pyradiomics), so no additional installation steps are needed.
From source
git clone https://github.com/RichardObi/frd-score.git
cd frd-score
pip install git+https://github.com/AIM-Harvard/pyradiomics.git@master
pip install -e ".[dev]"
Requirements
- Python ≥ 3.10
- pyradiomics (installed from GitHub, see above)
- numpy, scipy, Pillow, SimpleITK, opencv-contrib-python-headless
Windows users
Building pyradiomics from source requires a C compiler and CMake. Install Visual Studio Build Tools with the "Desktop development with C++" workload, then retry the pip install.
Quick Start
CLI
# Compute FRD between two image folders (default: v1)
python -m frd_score path/to/dataset_A path/to/dataset_B
# Use FRDv0 instead
python -m frd_score path/to/dataset_A path/to/dataset_B --frd_version v0
# With masks
python -m frd_score path/to/dataset_A path/to/dataset_B -m path/to/masks_A path/to/masks_B
# Save precomputed statistics to .npz
python -m frd_score --save_stats path/to/dataset path/to/output.npz
# Re-use .npz file
python -m frd_score path/to/output.npz path/to/dataset_B
Python API
from frd_score import compute_frd
# Basic usage
frd_value = compute_frd(["path/to/dataset_A", "path/to/dataset_B"])
# With masks and options
frd_value = compute_frd(
["path/to/dataset_A", "path/to/dataset_B"],
paths_masks=["path/to/masks_A", "path/to/masks_B"],
frd_version="v1",
verbose=True,
)
# From file lists
frd_value = compute_frd([
["img1.png", "img2.png", "img3.png"],
["img4.png", "img5.png", "img6.png"],
])
CLI Reference
Main command
python -m frd_score path1 path2 [OPTIONS]
| Flag | Description | Default |
|---|---|---|
--frd_version |
v0 or v1 |
v1 |
-m, --paths_masks |
Two mask folder paths | None |
-f, --feature_groups |
Feature classes to extract (e.g. firstorder glcm) |
version default |
-I, --image_types |
Image filter types (Original, LoG, Wavelet) |
version default |
-r, --resize_size |
Resize images to N×N or W×H | None |
-R, --norm_range |
Normalization range [min max] |
version default |
-T, --norm_type |
minmax or zscore |
version default |
--norm_ref |
Normalization reference: joint, d1, independent |
version default |
-v, --verbose |
Verbose logging | off |
-w, --num_workers |
CPU workers for multiprocessing | auto |
-s, --save_stats |
Save statistics to .npz |
off |
-F, --save_features |
Save features to CSV | off |
--use_paper_log |
Use paper Eq. 3 log transform: log(√d²) |
off |
--means_only |
Mean-only Fréchet distance (no covariance) | off |
--log_sigma |
LoG sigma values | [2.0, 3.0, 4.0, 5.0] |
--bin_width |
PyRadiomics bin width | 5 |
--normalize_scale |
PyRadiomics normalize scale | 100 |
--voxel_array_shift |
PyRadiomics voxel array shift | 300 |
--config_path |
Custom PyRadiomics YAML config | None |
--exclude_features |
Post-extraction exclusion: textural, wavelet, firstorder, shape |
None |
--match_sample_count |
Subsample larger dataset to match smaller | off |
--interpret |
Run interpretability analysis | off |
--interpret_dir |
Output dir for interpretation plots | outputs/interpretability_visualizations |
OOD subcommand
# Image-level OOD detection
python -m frd_score ood path/to/reference path/to/test
# Dataset-level nFRD
python -m frd_score ood path/to/reference path/to/test --detection_type dataset
| Flag | Description | Default |
|---|---|---|
--detection_type |
image or dataset |
image |
--val_frac |
Fraction of reference held out for threshold | 0.1 |
--use_val_set |
Enable hold-out validation split | off |
--id_dist_assumption |
gaussian, t, or counting |
gaussian |
--output_dir |
Directory for OOD CSV output | outputs/ood_predictions |
--seed |
Random seed for reproducibility | None |
All shared extraction flags (--frd_version, -f, -I, --norm_ref, etc.) are also available in the ood subcommand.
Python API Reference
compute_frd(paths, **kwargs)
Main entry point. See API docs for the full signature and parameter descriptions.
save_frd_stats(paths, **kwargs)
Compute and save feature statistics to a .npz file for later re-use. Accepts the same parameters as compute_frd().
interpret_frd(feature_list, feature_names, **kwargs)
Run interpretability analysis on extracted features. Produces t-SNE plots and per-feature difference rankings. Requires matplotlib and scikit-learn.
detect_ood(feature_list, **kwargs)
Out-of-distribution detection using normalized radiomics features. Supports per-image scoring (detection_type="image") and dataset-level nFRD (detection_type="dataset").
Interpretability
FRD enables interpretable comparison of image sets. Use the --interpret flag or call interpret_frd() to:
- Rank the most-changed radiomic features between two distributions
- Visualise feature distributions via t-SNE
- Identify which images changed the most (for paired datasets)
python -m frd_score path/to/dataset_A path/to/dataset_B --interpret
Out-of-Domain (OOD) Detection
FRD can detect whether newly acquired medical images come from the same domain as a reference set — useful for flagging potential distribution shifts (e.g. different scanners, protocols).
# Per-image OOD scores and p-values
python -m frd_score ood path/to/reference path/to/test_images
# Dataset-level OOD score (nFRD)
python -m frd_score ood path/to/reference path/to/test_images --detection_type dataset
Results are saved to outputs/ood_predictions/ood_predictions.csv with columns: filename, ood_score, ood_prediction, p_value.
Citation
If you use this library in your research, please cite:
@article{konz2026frd,
title = {Fr\'{e}chet Radiomic Distance (FRD): A Versatile Metric for
Comparing Medical Imaging Datasets},
author = {Konz, Nicholas and Osuala, Richard and Verma, Preeti and
Chen, Yuwen and Gu, Hanxue and Dong, Haoyu and Chen, Yaqian
and Marshall, Andrew and Garrucho, Lidia and Kushibar, Kaisar
and Lang, Daniel M. and Kim, Gene S. and Grimm, Lars J. and
Lewin, John M. and Duncan, James S. and Schnabel, Julia A. and
Diaz, Oliver and Lekadir, Karim and Mazurowski, Maciej A.},
journal = {Medical Image Analysis},
volume = {110},
pages = {103943},
year = {2026},
publisher = {Elsevier},
doi = {10.1016/j.media.2026.103943},
url = {https://www.sciencedirect.com/science/article/pii/S1361841526000125},
}
Earlier FRD work:
@article{osuala2024towards,
title = {Towards Learning Contrast Kinetics with Multi-Condition
Latent Diffusion Models},
author = {Osuala, Richard and Lang, Daniel and Verma, Preeti and
Joshi, Smriti and Tsirikoglou, Apostolia and Skorupko, Grzegorz
and Kushibar, Kaisar and Garrucho, Lidia and Pinaya, Walter HL
and Diaz, Oliver and others},
journal = {arXiv preprint arXiv:2403.13890},
year = {2024},
}
Links
- API Documentation — overview, benchmarks, datasets, FAQ
- Change Log — overview, benchmarks, datasets, FAQ
- Project Website — overview, benchmarks, datasets, FAQ
- Journal Article — Medical Image Analysis, Vol. 110 (2026)
- arXiv Preprint
- Evaluation Framework — scripts for OOD detection, translation evaluation, and metric comparison
- API Documentation — full docs hosted on GitHub Pages
Acknowledgements
- Preeti Verma — implementation of a script of an early frd version.
- Nicholas Konz — FRDv1 and RaD repository
- PyRadiomics — radiomic feature extraction backend
- pytorch-fid — Fréchet distance implementation reference
License
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file frd_score-1.0.1.tar.gz.
File metadata
- Download URL: frd_score-1.0.1.tar.gz
- Upload date:
- Size: 42.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3d8a73b81cd7146b685c8b7104db5beb5c183bc969fd0bf5c9424a73fe2408ca
|
|
| MD5 |
40c83e016d34e90c8f3343613168b8dd
|
|
| BLAKE2b-256 |
84399a0a8e54cf16d94d988aeb96d5c1a4d8fd1dbae9fcdc56e9985cd0e74651
|
Provenance
The following attestation bundles were made for frd_score-1.0.1.tar.gz:
Publisher:
publish.yml on RichardObi/frd-score
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
frd_score-1.0.1.tar.gz -
Subject digest:
3d8a73b81cd7146b685c8b7104db5beb5c183bc969fd0bf5c9424a73fe2408ca - Sigstore transparency entry: 994084184
- Sigstore integration time:
-
Permalink:
RichardObi/frd-score@bf05c71fc44e461ab123bd273e58390b90f9cf54 -
Branch / Tag:
refs/tags/v1.0.1 - Owner: https://github.com/RichardObi
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@bf05c71fc44e461ab123bd273e58390b90f9cf54 -
Trigger Event:
release
-
Statement type:
File details
Details for the file frd_score-1.0.1-py3-none-any.whl.
File metadata
- Download URL: frd_score-1.0.1-py3-none-any.whl
- Upload date:
- Size: 36.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
449c031c190d64ae9217784383efa99a5a65f92a6335e978447fc145e6fa1621
|
|
| MD5 |
d74c80705db477527f966079b2e74e42
|
|
| BLAKE2b-256 |
39fd1234fa3b5dc9ef058d6e2f3e3c415776721394175687ee61fdf8d78965ba
|
Provenance
The following attestation bundles were made for frd_score-1.0.1-py3-none-any.whl:
Publisher:
publish.yml on RichardObi/frd-score
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
frd_score-1.0.1-py3-none-any.whl -
Subject digest:
449c031c190d64ae9217784383efa99a5a65f92a6335e978447fc145e6fa1621 - Sigstore transparency entry: 994084279
- Sigstore integration time:
-
Permalink:
RichardObi/frd-score@bf05c71fc44e461ab123bd273e58390b90f9cf54 -
Branch / Tag:
refs/tags/v1.0.1 - Owner: https://github.com/RichardObi
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@bf05c71fc44e461ab123bd273e58390b90f9cf54 -
Trigger Event:
release
-
Statement type: