Eddeep is composed of 2 models in sequence:
- Translator: Restore correspondences between images.
- Registrator: Estimate the distortion and apply correction.
git clone git@github.com:CIG-UCL/eddeep.git
cd eddeep
pip install -r requirements.txtDuring training (but not at inference), the translator takes as input images that have been corrected for eddy distortions by an external tool. You can typically use FSL Eddy or Tortoise for that.
- Choose a moderately high (700-3000) b-value among the acquired ones.
- For each subject, average all the volumes for this b-value to obtain a direction average image
(assuming b-vectors are uniformly sampled on the sphere).
For the dataloader, the 4D DW data must be chopped into 3D volumes and organised according to the following nested structure: {subject_d} > {PED} > b{b-value} > {vol_gradDir}.nii.gz. The target image for translation following: {subject_d} > {PED} > {vol}_b{target b-value}_mean.nii.gz. For example:
├── sub_001
│ ├── AP
│ │ ├── b0
│ │ │ ├── vol_dir1.nii.gz
│ │ │ ├── vol_dir2.nii.gz
│ │ │ ├── ...
│ │ ├── b1000
│ │ │ ├── ...
│ │ ├── ...
│ │ ├── vol_b2000_mean.nii.gz (only for translation)
│ │ ├── ...
│ └── PA
│ ├── ...
├── sub_002
│ ├── ...
├── ...
- For the translator, the input data is pre-corrected and there is a translation target.
- For the registrator, the input data is the raw DW data.
There must be b=0!
eddeep_dir=<path-to-eddeep>
model_dir=<path-to-models>bvaltarget=<chose-target-bvalue>
data_precorr_train_dir=<path-to-precorrected-training-data-dir>
data_precorr_val_dir=<path-to-precorrected-validation-data-dir>
python ${eddeep_dir}/scripts/train_eddeep_trans.py -t ${data_precorr_train_dir}\
-v ${data_precorr_val_dir}\
-o ${model_dir}/trans\
-B ${bvaltarget} -e 400 -as 0.5 -ai 0.5\
-vs 2Images are resampled to an isotropic voxel size (-vs, 2 mm by default, 0 to keep the native resolution) if their voxel size differs from it by more than 5%. This voxel size is stored in the model: the registrator training and the inference scripts read it from the model, so it only needs to be set here. Models trained before this option can be given one with eddeep.utils.set_vox_size(tf.keras.models.load_model(path), 2.).save(new_path).
data_train_dir=<path-to-training-data-dir>
data_val_dir=<path-to-validation-data-dir>
python ${eddeep_dir}/scripts/train_eddeep_corr.py -t ${data_train_dir}\
-v ${data_val_dir}\
-tr ${model_dir}/trans_gen_best.keras\
-o ${model_dir}/corr\
-p 1\
-e 200 -as 0.5Pre-trained models (2 mm) are provided in models/, as described in [2]:
- eddeep: translator
trans.keras, trained without augmentation, and registratorcorr.keras. - eddeep+: translator
trans_plus.keras, trained with augmentation (probability 0.5), and registratorcorr_plus.keras.
Given:
- A pre-trained Eddeep translator (e.g.
trans_plus.keras). - A pre-trained Eddeep registrator (e.g.
corr_plus.keras).
dw=<path-to-dw-4D-data>
dw_corr=<path-to-corrected-dw-4D-data>
bval=<path-to-bval-file>
bvec=<path-to-bvec-file>
bvec_rot=<path-to-rotated-bvec-file>
model_dir=${eddeep_dir}/models
python ${eddeep_dir}/scripts/apply_correction.py -i ${dw}\
-o ${dw_corr}\
-tr ${model_dir}/trans_plus.keras\
-reg ${model_dir}/corr_plus.keras\
-b ${bval}\
-g ${bvec}\
-og ${bvec_rot}Interpolation (-in): the final resampling is trilinear by default (linear, as in the paper); spline uses cubic B-splines with recursive prefiltering instead.
Rotated b-vectors (-og): the rigid component of the estimated transformation,
If you used Eddeep for your work, please cite the following:
[1] A. Legouhy, R. Callaghan, W. Stee, P. Peigneux, H. Azadbakht and H. Zhang.
Eddeep: Fast eddy-current distortion correction for diffusion MRI with deep learning.
MICCAI (2024) [arxiv]
[2] A. Legouhy, R. Callaghan, Y. Qiao, W. Stee, P. Peigneux, H. Azadbakht and H. Zhang.
Eddeep: a deep-learning framework for fast eddy-current distortion correction in diffusion MRI.
Preprint (2026) [arxiv]
The code uses bits from Neurite and Voxelmorph: