Source code for antspynet.utilities.cortical_thickness

import numpy as np
import tensorflow as tf
import ants

[docs]def cortical_thickness(t1, antsxnet_cache_directory=None, verbose=False): """ Perform KellyKapowski cortical thickness using deep_atropos for segmentation. Description concerning implementaiton and evaluation: https://www.medrxiv.org/content/10.1101/2020.10.19.20215392v1 Arguments --------- t1 : ANTsImage input 3-D unprocessed T1-weighted brain image. antsxnet_cache_directory : string Destination directory for storing the downloaded template and model weights. Since these can be reused, if is None, these data will be downloaded to a ~/.keras/ANTsXNet/. verbose : boolean Print progress to the screen. Returns ------- Cortical thickness image and segmentation probability images. Example ------- >>> image = ants.image_read("t1w_image.nii.gz") >>> kk = cortical_thickness(image) """ from ..utilities import deep_atropos if t1.dimension != 3: raise ValueError("Image dimension must be 3.") atropos = deep_atropos(t1, do_preprocessing=True, antsxnet_cache_directory=antsxnet_cache_directory, verbose=verbose) # Kelly Kapowski cortical thickness kk_segmentation = ants.image_clone(atropos['segmentation_image']) kk_segmentation[kk_segmentation == 4] = 3 gray_matter = atropos['probability_images'][2] white_matter = (atropos['probability_images'][3] + atropos['probability_images'][4]) kk = ants.kelly_kapowski(s=kk_segmentation, g=gray_matter, w=white_matter, its=45, r=0.025, m=1.5, x=0, verbose=int(verbose)) return_dict = {'thickness_image' : kk, 'segmentation_image' : atropos['segmentation_image'], 'csf_probability_image' : atropos['probability_images'][1], 'gray_matter_probability_image' : atropos['probability_images'][2], 'white_matter_probability_image' : atropos['probability_images'][3], 'deep_gray_matter_probability_image' : atropos['probability_images'][4], 'brain_stem_probability_image' : atropos['probability_images'][5], 'cerebellum_probability_image' : atropos['probability_images'][6] } return(return_dict)
[docs]def longitudinal_cortical_thickness(t1s, initial_template="oasis", number_of_iterations=1, refinement_transform="antsRegistrationSyNQuick[a]", antsxnet_cache_directory=None, verbose=False): """ Perform KellyKapowski cortical thickness longitudinally using \code{deepAtropos} for segmentation of the derived single-subject template. It takes inspiration from the work described here: https://pubmed.ncbi.nlm.nih.gov/31356207/ Arguments --------- t1s : list of ANTsImage Input list of 3-D unprocessed t1-weighted brain images from a single subject. initial_template : string or ANTsImage Input image to define the orientation of the SST. Can be a string (see get_antsxnet_data) or a specified template. This allows the user to create a SST outside of this routine. number_of_iterations : int Defines the number of iterations for refining the SST. refinement_transform : string Transform for defining the refinement registration transform. See options in ants.registration. antsxnet_cache_directory : string Destination directory for storing the downloaded template and model weights. Since these can be reused, if is None, these data will be downloaded to a ~/.keras/ANTsXNet/. verbose : boolean Print progress to the screen. Returns ------- Cortical thickness image and segmentation probability images. Example ------- >>> t1s = list() >>> t1s.append(ants.image_read("t1w_image.nii.gz")) >>> kk = longitudinal_cortical_thickness(image) """ from ..utilities import get_antsxnet_data from ..utilities import preprocess_brain_image from ..utilities import deep_atropos ################### # # Initial SST + optional affine refinement # ################## sst = None if isinstance(initial_template, str): template_file_name_path = get_antsxnet_data(initial_template, antsxnet_cache_directory=antsxnet_cache_directory) sst = ants.image_read(template_file_name_path) else: sst = initial_template for s in range(number_of_iterations): if verbose: print("Refinement iteration", s, "( out of", number_of_iterations, ")") sst_tmp = ants.image_clone(sst) * 0 for i in range(len(t1s)): if verbose: print("***************************") print( "SST processing image", i, "( out of", len(t1s), ")") print( "***************************" ) transform_type = "antsRegistrationSyNQuick[r]" if s > 0: transform_type = refinement_transform t1_preprocessed = preprocess_brain_image(t1s[i], truncate_intensity=(0.01, 0.99), brain_extraction_modality=None, template=sst, template_transform_type=transform_type, do_bias_correction=False, do_denoising=False, intensity_normalization_type="01", antsxnet_cache_directory=antsxnet_cache_directory, verbose=verbose) sst_tmp += t1_preprocessed['preprocessed_image'] sst = sst_tmp / len(t1s) ################### # # Preprocessing and affine transform to final SST # ################## t1s_preprocessed = list() for i in range(len(t1s)): if verbose: print("***************************") print( "Final processing image", i, "( out of", len(t1s), ")") print( "***************************" ) t1_preprocessed = preprocess_brain_image(t1s[i], truncate_intensity=(0.01, 0.99), brain_extraction_modality="t1", template=sst, template_transform_type="antsRegistrationSyNQuick[a]", do_bias_correction=True, do_denoising=True, intensity_normalization_type="01", antsxnet_cache_directory=antsxnet_cache_directory, verbose=verbose) t1s_preprocessed.append(t1_preprocessed) ################### # # Deep Atropos of SST for priors # ################## sst_atropos = deep_atropos(sst, do_preprocessing=True, antsxnet_cache_directory=antsxnet_cache_directory, verbose=verbose) ################### # # Traditional Atropos + KK for each iamge # ################## return_list = list() for i in range(len(t1s_preprocessed)): if verbose: print("Atropos for image", i, "( out of", len(t1s), ")") atropos_output = ants.atropos(t1s_preprocessed[i]['preprocessed_image'], x=t1s_preprocessed[i]['brain_mask'], i=sst_atropos['probability_images'][1:7], m="[0.1,1x1x1]", c="[5,0]", priorweight=0.5, p="Socrates[1]", verbose=int(verbose)) kk_segmentation = ants.image_clone(atropos_output['segmentation']) kk_segmentation[kk_segmentation == 4] = 3 gray_matter = atropos_output['probabilityimages'][1] white_matter = atropos_output['probabilityimages'][2] + atropos_output['probabilityimages'][3] kk = ants.kelly_kapowski(s=kk_segmentation, g=gray_matter, w=white_matter, its=45, r=0.025, m=1.5, x=0, verbose=int(verbose)) t1_dict = {'preprocessed_image' : t1s_preprocessed[i]['preprocessed_image'], 'thickness_image' : kk, 'segmentation_image' : atropos_output['segmentation'], 'csf_probability_image' : atropos_output['probabilityimages'][0], 'gray_matter_probability_image' : atropos_output['probabilityimages'][1], 'white_matter_probability_image' : atropos_output['probabilityimages'][2], 'deep_gray_matter_probability_image' : atropos_output['probabilityimages'][3], 'brain_stem_probability_image' : atropos_output['probabilityimages'][4], 'cerebellum_probability_image' : atropos_output['probabilityimages'][5], 'template_transforms' : t1s_preprocessed[i]['template_transforms'] } return_list.append(t1_dict) return_list.append(sst) return(return_list)