Source code for scilpy.image.volume_b0_synthesis

# -*- coding: utf-8 -*-
import logging
import os
import warnings

# Disable tensorflow warnings
with warnings.catch_warnings():
    os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
    warnings.simplefilter("ignore")
    from dipy.nn.tf.synb0 import Synb0

import numpy as np
from dipy.align.imaffine import AffineMap
from dipy.segment.tissue import TissueClassifierHMRF
from scipy.ndimage import gaussian_filter

from scilpy.image.volume_operations import register_image


[docs] def compute_b0_synthesis(t1_data, t1_bet_data, b0_data, b0_bet_data, template_data, t1_affine, b0_affine, template_affine, verbose): """ Note. Tensorflow is required here, through dipy.Synb0. If not installed, dipy will raise an error, like: >> dipy.utils.tripwire.TripWireError: We need package tensorflow_addons for these functions, but ``import tensorflow_addons`` raised an ImportError. Parameters ---------- t1_data: np.ndarary The T1 (wholebrain, with the skull). t1_bet_data: np.ndarray The mask. b0_data: np.ndarray The b0 (wholebrain, with the skull). b0_bet_data: np.ndarray The mask. template_data: np.ndarray The template for typical usage. t1_affine: np.ndarray The T1's affine. b0_affine: np.ndarray The b0's affine. template_affine: np.ndarray The template's affine verbose: bool Whether to make dipy's Synb0 verbose. Returns ------- rev_b0: np.ndarray The synthetized b0. """ logging.info('The usage of synthetic b0 is not fully tested.' 'Be careful when using it.') # Crude estimation of the WM mean intensity and normalization logging.info('Estimating WM mean intensity') hmrf = TissueClassifierHMRF() t1_bet_data = gaussian_filter(t1_bet_data, 2) _, final_segmentation, _ = hmrf.classify(t1_bet_data, 3, 0.25, tolerance=1e-4, max_iter=5) avg_wm = np.mean(t1_data[final_segmentation == 3]) # Modifying t1 t1_data /= avg_wm t1_data *= 110 # SyNB0 works only in a standard space, so we need to register the images logging.info('Registering images') # Use the BET image for registration t1_bet_to_b0, t1_bet_to_b0_transform = register_image( b0_bet_data, b0_affine, t1_bet_data, t1_affine, fine=True) affine_map = AffineMap(t1_bet_to_b0_transform, domain_grid_shape=b0_data.shape, domain_grid2world=b0_affine, codomain_grid_shape=t1_data.shape, codomain_grid2world=t1_affine) t1_skull_to_b0 = affine_map.transform(t1_data.astype(np.float64)) # Then register to MNI (using the BET again) _, t1_bet_to_b0_to_mni_transform = register_image( template_data, template_affine, t1_bet_to_b0, b0_affine, fine=True) affine_map = AffineMap(t1_bet_to_b0_to_mni_transform, domain_grid_shape=template_data.shape, domain_grid2world=template_affine, codomain_grid_shape=b0_data.shape, codomain_grid2world=b0_affine) # But for prediction, we want the skull b0_skull_to_mni = affine_map.transform(b0_data.astype(np.float64)) t1_skull_to_mni = affine_map.transform(t1_skull_to_b0.astype(np.float64)) logging.info('Running SyN-B0') SyNb0 = Synb0(verbose) rev_b0 = SyNb0.predict(b0_skull_to_mni, t1_skull_to_mni) rev_b0 = affine_map.transform_inverse(rev_b0.astype(np.float64)) return rev_b0