Source code for AFQ.models.wmgm_interface

import nibabel as nib
import numpy as np
from dipy.align import resample
from scipy.ndimage import gaussian_filter
from skimage.morphology import skeletonize
from skimage.segmentation import find_boundaries


[docs] def fit_wm_gm_interface(PVE_img, dwiref_img): """ Compute the white matter/gray matter interface from a PVE image. Parameters ---------- PVE_img : Nifti1Image PVE image containing CSF, GM, and WM segmentations from T1 dwiref_img : Nifti1Image Reference image to find boundary in that space. """ PVE = PVE_img.get_fdata() csf = PVE[..., 0] gm = PVE[..., 1] wm = PVE[..., 2] # Put in diffusion space wm = resample( wm, dwiref_img.get_fdata(), moving_affine=PVE_img.affine, static_affine=dwiref_img.affine, ).get_fdata() gm = resample( gm, dwiref_img.get_fdata(), moving_affine=PVE_img.affine, static_affine=dwiref_img.affine, ).get_fdata() csf = resample( csf, dwiref_img.get_fdata(), moving_affine=PVE_img.affine, static_affine=dwiref_img.affine, ).get_fdata() wm_boundary = find_boundaries(wm > 0.9, mode="inner") gm_smoothed = gaussian_filter(gm, 1) csf_smoothed = gaussian_filter(csf, 1) wm_boundary[~gm_smoothed.astype(bool)] = 0 wm_boundary[csf_smoothed > gm_smoothed] = 0 wm_boundary[wm < 0.5] = 0 skeletonized_data = np.zeros_like(wm_boundary, dtype=bool) for ii in range(wm_boundary.shape[0]): skeletonized_data[ii] = skeletonize(wm_boundary[ii] > 0) for jj in range(wm_boundary.shape[1]): skeletonized_data[:, jj] = np.logical_or( skeletonize(wm_boundary[:, jj] > 0), skeletonized_data[:, jj] ) for kk in range(wm_boundary.shape[2]): skeletonized_data[:, :, kk] = np.logical_or( skeletonize(wm_boundary[:, :, kk] > 0), skeletonized_data[:, :, kk] ) return nib.Nifti1Image(skeletonized_data.astype(np.float32), dwiref_img.affine)