def resample_to_img(source, target, **kwargs): """ Use nilearn.image.resample_to_img. Returns ------- out_file: str The absolute path to the output file. """ from nilearn.image import resample_to_img return resample_to_img(source_img=source, target_img=target, **kwargs)
def _post_run_hook(self, runtime): self._fixed_image = self.inputs.after self._moving_image = self.inputs.before if self.inputs.base == 'before': resampled_after = nli.resample_to_img(self._fixed_image, self._moving_image) fname = fname_presuffix(self._fixed_image, suffix='_resampled', newpath=runtime.cwd) resampled_after.to_filename(fname) self._fixed_image = fname else: resampled_before = nli.resample_to_img(self._moving_image, self._fixed_image) fname = fname_presuffix(self._moving_image, suffix='_resampled', newpath=runtime.cwd) resampled_before.to_filename(fname) self._moving_image = fname self._contour = self.inputs.wm_seg if isdefined(self.inputs.wm_seg) else None NIWORKFLOWS_LOG.info( 'Report - setting before (%s) and after (%s) images', self._fixed_image, self._moving_image) runtime = super(ResampleBeforeAfterRPT, self)._post_run_hook(runtime) NIWORKFLOWS_LOG.info('Successfully created report (%s)', self._out_report) os.unlink(fname) return runtime
def inject_skullstripped(subjects_dir, subject_id, skullstripped): mridir = op.join(subjects_dir, subject_id, 'mri') t1 = op.join(mridir, 'T1.mgz') bm_auto = op.join(mridir, 'brainmask.auto.mgz') bm = op.join(mridir, 'brainmask.mgz') if not op.exists(bm_auto): img = nb.load(t1) mask = nb.load(skullstripped) bmask = new_img_like(mask, mask.get_data() > 0) resampled_mask = resample_to_img(bmask, img, 'nearest') masked_image = new_img_like(img, img.get_data() * resampled_mask.get_data()) masked_image.to_filename(bm_auto) if not op.exists(bm): copyfile(bm_auto, bm, copy=True, use_hardlink=True) return subjects_dir, subject_id
def roi_average_rdm(rdms_f, rdm_idx_f, roi_f): rdms = np.load(rdms_f) # Mask index map with the ROI idx_img = nb.load(rdm_idx_f) roi_img = math_img('img > 0.5', img=resample_to_img(roi_f, idx_img)) try: idx_sel = apply_mask(idx_img, roi_img) idx_sel = np.array(idx_sel[idx_sel > -1], dtype=int) except ValueError: print("************ problem with: ******************") print(rdms_f) print(rdm_idx_f) print(roi_f) return np.zeros(rdms[0].shape) # Load RDMs and average those included in the ROI return np.mean(rdms[idx_sel], axis=0)
def gen_mask(t1w_head, t1w_brain, mask): import os.path as op from nilearn.image import math_img t1w_brain_mask = f"{op.dirname(t1w_head)}/t1w_brain_mask.nii.gz" if mask is not None: from nilearn.image import resample_to_img print(f"Using {mask}...") nib.save(resample_to_img(nib.load(mask), nib.load(t1w_head)), t1w_brain_mask) else: # Check if already skull-stripped. If not, strip it. img = nib.load(t1w_head) t1w_data = img.get_fdata() perc_zero = np.count_nonzero( np.nan_to_num( np.array(t1w_data < 10).astype('int'))) / np.count_nonzero( np.nan_to_num(t1w_data.astype('bool').astype('int'))) # TODO: find a better heuristic for determining whether a t1w image has # already been skull-stripped if perc_zero < 0.75: try: t1w_brain_mask = deep_skull_strip(t1w_data, t1w_brain_mask, img) except RuntimeError: print('Deepbrain extraction failed...') else: print('Your T1w data appears to already be skull-stripped? ' 'Skipping...') # Threshold T1w brain to binary in anat space t_img = nib.load(t1w_brain_mask) img = math_img("img > 0.0", img=t_img) img.to_filename(t1w_brain_mask) t_img.uncache() os.system(f"fslmaths {t1w_head} -mas {t1w_brain_mask} {t1w_brain}") assert op.isfile(t1w_brain) assert op.isfile(t1w_brain_mask) return t1w_brain, t1w_brain_mask
def show_images(): # prediction_file_location = "D:\\Master\\predicted\\predicted\\oasis\\CNNAllFinal_pred__OAS1_0012_MR1_mpr_n4_anon_111_t88_gfc_masked.nii.gz" # prediction_file_location = "D:\\Master\\predicted\\predictions\\" prediction_file_location = "D:\\Master\\predicted\\predictions\\volume-0_processed_pred_Segm.nii.gz" data_file_location = "D:\\MRISCANS\\LITS\\LITSTrainingData\\" data_file_name = "volume-0_processed.nii.gz" label_file_location = "D:\\MRISCANS\\LITS\\LITSTrainingLabels\\segmentation-0_processed.nii.gz" arcSaveName = "DeepMedic" prediction = nib.load(prediction_file_location) data = nib.load(data_file_location + data_file_name) label = nib.load(label_file_location) # prediction_plot = plotting.plot_roi(prediction, bg_img=data, cmap='Greys') # label_plot = plotting.plot_roi(label, bg_img=data, cmap='Greys') pred = resample_to_img(prediction, label, interpolation='linear').get_data() error_map = np.zeros(pred.shape) lab = label.get_data() error_map = np.zeros(pred.shape) error_map += np.array((pred != lab), dtype=float) * 2 error_map += lab # Don't know why I have to have these random colours in the beginning. cmap = ListedColormap( ['green', 'green', 'red', 'red', 'red', 'green', 'red', 'cyan'], 'indexed') print("jjjj") nif = nib.Nifti1Image(error_map, label.affine) # label_and_prediction_plot = plotting.plot_stat_map(nif, bg_img=label, cmap=cmap, cut_coords=(10, 10, 10)) label_and_prediction_plot = plotting.plot_roi(nif, bg_img=data, cmap=cmap, colorbar=False, cut_coords=(-4, -71, 10)) print("jjjj") data_file_name = data_file_name.split('.')[0] plotting.show()
def peaks2maps_workflow(sleuth_file, output_dir=None, prefix=None, n_iters=10000): """Run the peaks2maps workflow.""" LGR.info("Loading coordinates...") dset = convert_sleuth_to_dataset(sleuth_file) LGR.info("Reconstructing unthresholded maps...") k = Peaks2MapsKernel(resample_to_mask=False) imgs = k.transform(dset, return_type="image") mask_img = resample_to_img(dset.mask, imgs[0], interpolation="nearest") z_data = apply_mask(imgs, mask_img) LGR.info("Estimating the null distribution...") log_p_map, t_map, _ = permuted_ols( np.ones((z_data.shape[0], 1)), z_data, confounding_vars=None, model_intercept=False, # modeled by tested_vars n_perm=n_iters, two_sided_test=True, random_state=42, n_jobs=1, verbose=0, ) res = {"logp": log_p_map, "t": t_map} res = MetaResult(permuted_ols, maps=res, mask=mask_img) if output_dir is None: output_dir = os.path.dirname(os.path.abspath(sleuth_file)) else: pathlib.Path(output_dir).mkdir(parents=True, exist_ok=True) if prefix is None: base = os.path.basename(sleuth_file) prefix, _ = os.path.splitext(base) prefix += "_" LGR.info("Saving output maps...") res.save_maps(output_dir=output_dir, prefix=prefix)
def create_atlas(freesurfer_label_path, t1w_path, FS_MB_df, new_atlas_path, labels_to_use): t1w_image = nib.load(t1w_path) freesurfer_label_img = nib.load(freesurfer_label_path) freesurfer_label_data = freesurfer_label_img.get_data() new_atlas_data = np.zeros_like(freesurfer_label_data) for region in labels_to_use: new_atlas_data[freesurfer_label_data == region] = FS_MB_df[ FS_MB_df.Freesurfer_label == region].label new_atlas_img = nib.Nifti1Image(new_atlas_data, affine=freesurfer_label_img.affine, header=freesurfer_label_img.header) new_atlas_img = resample_to_img(new_atlas_img, t1w_image, interpolation="nearest") #al_t1 = nib.Nifti1Image(t1w_image.get_data(), affine=np.eye(4), header=t1w_image.header) #al_dkt = nib.Nifti1Image(new_atlas_img.get_data(), affine=np.eye(4), header=new_atlas_img.header) nib.save(new_atlas_img, new_atlas_path) print("New Mindboggle DKT atlas: " + new_atlas_path)
def _transform(self, mask, coordinates): transformed = [] coordinates_list = [] ids = [] for id_, data in coordinates.groupby("id"): ijk = np.vstack( (data.i.values, data.j.values, data.k.values)).T.astype(int) xyz = vox2mm(ijk, mask.affine) coordinates_list.append(xyz) ids.append(id_) imgs = compute_p2m_ma(coordinates_list, skip_out_of_bounds=True, model_dir=self._model_dir) resampled_imgs = [] for img in imgs: resampled_imgs.append(image.resample_to_img(img, mask).get_fdata()) transformed = list(zip(resampled_imgs, ids)) return transformed
def get_roi_mask( atlas_maps, index_mask, labels, path=None, global_mask=None, resample_to_img_=None, intersect_with_img=False, PROJECT_PATH="/neurospin/unicog/protocols/IRMf/LePetitPrince_Pallier_2018/LePetitPrince/" ): """Return the Niftimasker object for a given ROI based on an atlas. Optionally resampled based on a resample_to_img_ image and another masker (global masker) parameters. """ if path is None: check_folder(os.path.join(PROJECT_PATH, 'derivatives/fMRI/ROI_masks')) path = os.path.join( PROJECT_PATH, 'derivatives/fMRI/ROI_masks', labels[index_mask]) #be careful to remove ‘background‘ from labels if os.path.exists(path + '.nii.gz') and os.path.exists(path + '.yml'): masker = load_masker(path, resample_to_img_=resample_to_img_, intersect_with_img=intersect_with_img) else: mask = math_img('img=={}'.format(index_mask + 1), img=atlas_maps) if resample_to_img_ is not None: mask = resample_to_img(mask, resample_to_img_, interpolation='nearest') if intersect_with_img: mask_img = math_img('img==2', img=math_img('img1+img2', img1=mask_img, img2=resample_to_img_)) masker = NiftiMasker(mask) if global_mask: params = read_yaml(global_mask + '.yml') params['detrend'] = False params['standardize'] = False masker.set_params(**params) masker.fit() save_masker(masker, path) return masker
def gen_mask(t1w_head, t1w_brain, mask): import time import os.path as op from pynets.registration import utils as regutils from nilearn.image import math_img t1w_brain_mask = f"{op.dirname(t1w_head)}/t1w_brain_mask.nii.gz" img = nib.load(t1w_head) if mask is not None and op.isfile(mask): from nilearn.image import resample_to_img print(f"Using {mask}...") mask_img = nib.load(mask) nib.save(resample_to_img(mask_img, img), t1w_brain_mask) else: # Perform skull-stripping if mask not provided. img = nib.load(t1w_head) t1w_data = img.get_fdata(dtype=np.float32) try: t1w_brain_mask = deep_skull_strip(t1w_data, t1w_brain_mask, img) except RuntimeError as e: print(e, 'Deepbrain extraction failed...') del t1w_data # Threshold T1w brain to binary in anat space t_img = nib.load(t1w_brain_mask) img = math_img("img > 0.0", img=t_img) img.to_filename(t1w_brain_mask) t_img.uncache() time.sleep(0.5) t1w_brain = regutils.apply_mask_to_image(t1w_head, t1w_brain_mask, t1w_brain) time.sleep(0.5) assert op.isfile(t1w_brain) assert op.isfile(t1w_brain_mask) return t1w_brain, t1w_brain_mask
def check_mask_atlas_overlap(mask_img, atlas_img): # resample atlas to mask image # TO-DO: both stat mask and atlas image contain integers. When one has to be # resampled to the other, continous resampling can not be used (labels # like 1.4 are not valid.). interpolation keyword seems to do the trick: # Using interpolation == 'nearest' seems to keep resampled labels as integers. atlas_img = resample_to_img(source_img=atlas_img, target_img=mask_img, interpolation='nearest') # get intersection of mask image and atlas image intersect_img = math_img('img_1 * img_2', img_1=atlas_img, img_2=mask_img) # get region labels and region sizes of atlas image and intersection image atlas_labels, atlas_sizes = np.unique(atlas_img.get_fdata(), return_counts=True) intersect_img_labels, intersect_img_counts = np.unique( intersect_img.get_fdata(), return_counts=True) # check which labels are not shared by atlas image and intersection image not_shared_labels = np.array( [list(set(atlas_labels) - set(intersect_img_labels))]).reshape(-1, ) not_shared_zeros = np.zeros(not_shared_labels.shape) # fill up labels and sizes arrays with not shared labels and corresponding # zero sizes intersect_img_labels_all = np.concatenate( (intersect_img_labels, not_shared_labels)) intersect_img_sizes_all = np.concatenate( (intersect_img_counts, not_shared_zeros)) # sort filled up intersection image sizes intersect_img_labels_all_sorted_indices = np.argsort( intersect_img_labels_all) intersect_img_sizes_all_sorted = intersect_img_sizes_all[ intersect_img_labels_all_sorted_indices] # compare atlas sizes and intersection image sizes overlap_proportion = (intersect_img_sizes_all_sorted / atlas_sizes) * 100 return overlap_proportion
def process_pool(study_name, path): print(f'Processing {study_name}...') try: z_img = nilearn.image.load_img(path) except ValueError: # File path not found print(f'File {path} not found. Ignored.') return if np.isnan(z_img.get_fdata()).any(): print(f'Image {path} contains Nan. Ignored.') return if not re.match(r'^\w+$', study_name): raise ValueError('Study {study_name} contains invalid caracters.') o_study_path = f'{o_dir}{study_name}/' os.makedirs(o_study_path, exist_ok=True) _, filename = ntpath.split(path) file, ext = filename.split('.', 1) z_img = image.resample_to_img(z_img, template) z_img.to_filename(f'{o_study_path}{file}.{ext}') sub_imgs = [] for i in range(1, n_sub+1): print(f'Simulating subject {i}...', end='\r') sub_img = sim_sub(z_img, s1, s2) # sub_dir = f'{o_study_path}sub-{str(i).zfill(len(str(n_sub)))}/' # os.makedirs(sub_dir, exist_ok=True) # sub_img.to_filename(f'{sub_dir}{filename}') sub_imgs.append(sub_img) std_img = nilearn.image.math_img('np.std(imgs, axis=3)', imgs=sub_imgs) del sub_imgs std_img.to_filename(f'{o_study_path}{file}_se.{ext}') con_img = nilearn.image.math_img('np.multiply(img1, img2)', img1=z_img, img2=std_img) del z_img, std_img con_img.to_filename(f'{o_study_path}{file}_con.{ext}') del con_img
def concat_rois_func(in_WM, in_mask, ref_header): import os import nibabel as nb from nilearn.image import resample_to_img WM_nii = nb.load(in_WM) mask_nii = nb.load(in_mask) # we have to do this explicitly because of potential differences in # qform_code between the two files that prevent SignalExtraction to do # the concatenation concat_nii = nb.funcs.concat_images([ resample_to_img(WM_nii, mask_nii, interpolation='nearest'), mask_nii ]) concat_nii = nb.Nifti1Image(concat_nii.get_data(), nb.load(ref_header).affine, nb.load(ref_header).header) concat_nii.to_filename("concat.nii.gz") return os.path.abspath("concat.nii.gz")
def inject_skullstripped(subjects_dir, subject_id, skullstripped): mridir = op.join(subjects_dir, subject_id, "mri") t1 = op.join(mridir, "T1.mgz") bm_auto = op.join(mridir, "brainmask.auto.mgz") bm = op.join(mridir, "brainmask.mgz") if not op.exists(bm_auto): img = nb.load(t1) mask = nb.load(skullstripped) bmask = new_img_like(mask, np.asanyarray(mask.dataobj) > 0) resampled_mask = resample_to_img(bmask, img, "nearest") masked_image = new_img_like( img, np.asanyarray(img.dataobj) * resampled_mask.dataobj) masked_image.to_filename(bm_auto) if not op.exists(bm): copyfile(bm_auto, bm, copy=True, use_hardlink=True) return subjects_dir, subject_id
def concat_rois_func(in_WM, in_mask, ref_header): import os import nibabel as nb from nilearn.image import resample_to_img WM_nii = nb.load(in_WM) mask_nii = nb.load(in_mask) # we have to do this explicitly because of potential differences in # qform_code between the two files that prevent SignalExtraction to do # the concatenation concat_nii = nb.funcs.concat_images([resample_to_img(WM_nii, mask_nii, interpolation='nearest'), mask_nii]) concat_nii = nb.Nifti1Image(concat_nii.get_data(), nb.load(ref_header).affine, nb.load(ref_header).header) concat_nii.to_filename("concat.nii.gz") return os.path.abspath("concat.nii.gz")
def prepare_roi_from_probtissue(in_file, epi_mask, epi_mask_erosion_mm=0, erosion_mm=0): import os import nibabel as nb import scipy.ndimage as nd from nilearn.image import resample_to_img probability_map_nii = resample_to_img(in_file, epi_mask) probability_map_data = probability_map_nii.get_data() # thresholding probability_map_data[probability_map_data < 0.95] = 0 probability_map_data[probability_map_data != 0] = 1 epi_mask_nii = nb.load(epi_mask) epi_mask_data = epi_mask_nii.get_data() if epi_mask_erosion_mm: epi_mask_data = nd.binary_erosion( epi_mask_data, iterations=int( epi_mask_erosion_mm / max(probability_map_nii.header.get_zooms()))).astype(int) eroded_mask_file = os.path.abspath("erodd_mask.nii.gz") nb.Nifti1Image(epi_mask_data, epi_mask_nii.affine, epi_mask_nii.header).to_filename(eroded_mask_file) else: eroded_mask_file = epi_mask probability_map_data[epi_mask_data != 1] = 0 # shrinking if erosion_mm: iter_n = int(erosion_mm / max(probability_map_nii.header.get_zooms())) probability_map_data = nd.binary_erosion(probability_map_data, iterations=iter_n).astype(int) new_nii = nb.Nifti1Image(probability_map_data, probability_map_nii.affine, probability_map_nii.header) new_nii.to_filename("roi.nii.gz") return os.path.abspath("roi.nii.gz"), eroded_mask_file
def main(): parser = ArgumentParser() parser.add_argument("--sub", help="PseudoGUID of interest.") parser.add_argument("--tractoflow_dir", help="Please provide path to the TractoFlow output directory") parser.add_argument("--parcellation", help="Name of parcellation") parser.add_argument("--parcellation_file", help="Please provide path to the parcellation file of interest") parser.add_argument("--roi_labels_file", help="Please provide path to ROI labels file") results = parser.parse_args() sub = results.sub tractoflow_dir = results.tractoflow_dir parcellation = results.parcellation parcellation_file = results.parcellation_file roi_labels_file = results.roi_labels_file parcellation_img = nib.load(parcellation_file) if parcellation == 'HCP': parcellation_img = renum_hcp_atlas(parcellation_img) elif parcellation == 'aparc500': parcellation_img = renum_aparc500_atlas(parcellation_img) with open(roi_labels_file, 'r') as f: roi_labels = f.read().split("\n")[:-1] metrics = ['fa', 'md', 'ad', 'rd', 'ga', 'mode'] for metric in metrics: metric_file = glob.glob(os.path.join(tractoflow_dir, "sub-{0}_ses-v01".format(sub), "DTI_Metrics", "*{0}.nii.gz".format(metric)))[0] metric_img = nib.load(metric_file) metric_img = resample_to_img(metric_img, parcellation_img) masker = NiftiLabelsMasker(labels_img=parcellation_img, standardize=True, memory='nilearn_cache', verbose=5) metric_arr = masker.fit_transform([metric_img])[0] metric_mat = pd.DataFrame(index = [sub], columns = roi_labels) metric_mat.loc[sub, roi_labels] = metric_arr metric_mat.to_csv(os.path.join(tractoflow_dir, "sub-{0}_ses-v01".format(sub), "DTI_Metrics", "sub-{0}_ses-v01_parcellation-{1}_{2}.csv".format(sub, parcellation, metric)))
def roi2dwi_align( roi, t1w_brain, roi_in_t1w, roi_in_dwi, ap_path, mni2t1w_warp, t1wtissue2dwi_xfm, mni2t1_xfm, template, simple, ): """ A function to perform alignment of a waymask from MNI space --> T1w --> dwi. """ import time from pynets.registration import utils as regutils from nilearn.image import resample_to_img roi_img = nib.load(roi) template_img = nib.load(template) roi_img_res = resample_to_img(roi_img, template_img, interpolation="nearest") roi_res = f"{roi.split('.nii')[0]}_res.nii.gz" nib.save(roi_img_res, roi_res) # Apply warp or transformer resulting from the inverse MNI->T1w created # earlier if simple is False: regutils.apply_warp(t1w_brain, roi, roi_in_t1w, warp=mni2t1w_warp) else: regutils.applyxfm(t1w_brain, roi, mni2t1_xfm, roi_in_t1w) time.sleep(0.5) # Apply transform from t1w to native dwi space regutils.applyxfm(ap_path, roi_in_t1w, t1wtissue2dwi_xfm, roi_in_dwi) return roi_in_dwi
def make_mask(atlas,mask): import nibabel as nib import numpy as np import os from nilearn.image import resample_to_img subcort_labels = [16, 28, 60, 10, 49] # brainstem, L/R VentralDC, L/R thalamus atlas_img = nib.load(atlas) atlas_data = atlas_img.get_data() affine = atlas_img.affine mask_data = np.isin(atlas_data, subcort_labels).astype('uint8') mask_img = nib.Nifti1Image(mask_data, affine=affine) mask_filename = os.path.abspath('subcortical_mask.nii.gz') nodif_mask_img = nib.load(mask) mask_resample = resample_to_img(mask_img, nodif_mask_img) nib.save(mask_resample, mask_filename) return mask_filename
def load_masker(path, resample_to_img_=None, intersect_with_img=False, **kwargs): params = read_yaml(path + '.yml') mask_img = nib.load(path + '.nii.gz') if resample_to_img_ is not None: mask_img = resample_to_img(mask_img, resample_to_img_, interpolation='nearest') if intersect_with_img: mask_img = math_img('img==2', img=math_img('img1+img2', img1=mask_img, img2=resample_to_img_)) masker = NiftiMasker(mask_img) masker.set_params(**params) if kwargs: masker.set_params(**kwargs) masker.fit() return masker
def get_volume_mask(subject, session, mask, bids_folder='/data'): if session.endswith('1'): task = 'mapper' else: task = 'task' base_mask = op.join( bids_folder, 'derivatives', f'fmriprep/sub-{subject}/ses-{session}/func/sub-{subject}_ses-{session}_task-{task}_run-1_space-T1w_desc-brain_mask.nii.gz' ) if mask is None: return base_mask mask = mask.replace('_', '') mask = op.join(bids_folder, 'derivatives', 'ips_masks', f'sub-{subject}', 'anat', f'sub-{subject}_space-T1w_desc-{mask}_mask.nii.gz') mask = image.resample_to_img(mask, base_mask, interpolation='nearest') return mask
def get_activations(path, threshold): """ Retrieve the xyz activation coordinates from an image. Args: path (string or Nifti1Image): Path to or object of a nibabel.Nifti1Image from which to extract coordinates. threshold (float): Same as the extract_from_paths function. Returns: (tuple): Size 3 tuple of lists storing respectively the X, Y and Z coordinates """ X, Y, Z = [], [], [] try: img = nilearn.image.load_img(path) except ValueError: # File path not found print(f'File {path} not found. Ignored.') return None if np.isnan(img.get_fdata()).any(): print(f'Img {path} contains Nan. Ignored.') return None img = image.resample_to_img(img, template) peaks = get_3d_peaks(img, mask=gray_mask, threshold=threshold) if not peaks: return X, Y, Z for peak in peaks: X.append(peak['pos'][0]) Y.append(peak['pos'][1]) Z.append(peak['pos'][2]) del peaks return X, Y, Z
def transform(self, ids, masked=False): """ Generate peaks2maps modeled activation images for each Contrast in dataset. Parameters ---------- ids : :obj:`list` A list of Contrast IDs for which to generate modeled activation images. masked : :obj:`boolean` Whether to mask the maps generated by peaks2maps Returns ------- imgs : :obj:`list` of :obj:`nibabel.Nifti1Image` A list of modeled activation images (one for each of the Contrasts in the input dataset). """ coordinates_list = [] for id_ in ids: data = self.coordinates.loc[self.coordinates['id'] == id_] mm_coords = [] for coord in data[['i', 'j', 'k']].values: mm_coords.append(vox2mm(coord, self.mask.affine)) coordinates_list.append(mm_coords) imgs = peaks2maps(coordinates_list, skip_out_of_bounds=True) resampled_imgs = [] for img in imgs: resampled_imgs.append(resample_to_img(img, self.mask)) if masked: masked_images = [] for img in resampled_imgs: masked_images.append( math_img('map*mask', map=img, mask=self.mask)) return masked_images return resampled_imgs
def crop_nifti(input_img, ref_img): """ :param input_img: :param crop_sagittal: :param crop_coronal: :param crop_axial: :return: """ import nibabel as nib import os import numpy as np from nilearn.image import resample_img, crop_img, resample_to_img from nibabel.spatialimages import SpatialImage basedir = os.getcwd() crop_ref = crop_img(ref_img, rtol=0.5) crop_ref.to_filename( os.path.join( basedir, os.path.basename(input_img).split('.nii')[0] + '_cropped_template.nii.gz')) crop_template = os.path.join( basedir, os.path.basename(input_img).split('.nii')[0] + '_cropped_template.nii.gz') ## resample the individual MRI onto the cropped template image crop_img = resample_to_img(input_img, crop_template) crop_img.to_filename( os.path.join( basedir, os.path.basename(input_img).split('.nii')[0] + '_cropped.nii.gz')) output_img = os.path.join( basedir, os.path.basename(input_img).split('.nii')[0] + '_cropped.nii.gz') return output_img, crop_template
def get_established_parcellation(parcellation="Harvard_Oxford", target_img=None, parcellation_dir=None): if parcellation == "Harvard_Oxford": name = "Harvard_Oxford_cort-prob-2mm" data = datasets.fetch_atlas_harvard_oxford('cort-prob-2mm', data_dir=parcellation_dir) parcel = nibabel.load(data['maps']) labels = data['labels'][1:] # first label is background atlas_threshold = 25 elif parcellation == "smith": name = "smith_rsn70" data = datasets.fetch_atlas_smith_2009( data_dir=parcellation_dir)['rsn70'] parcel = nibabel.load(data) labels = range(parcel.shape[-1]) atlas_threshold = 4 elif parcellation == "glasser": glasser_dir = path.join(parcellation_dir, 'glasser') data = image.load_img( path.join(glasser_dir, 'HCP-MMP1_on_MNI152_ICBM2009a_nlin.nii.gz')) parcel = image.new_img_like(data, (data.get_fdata() + .01).astype(int)) labels = list( np.genfromtxt(path.join(glasser_dir, 'HCP-MMP1_on_MNI152_ICBM2009a_nlin.txt'), dtype=str, usecols=1)) name = 'glasser' atlas_threshold = None # split down midline into lateralized ROIs data_coords = np.where(parcel.get_data()) right_coords = *(i[data_coords[0] > parcel.shape[0] // 2] for i in data_coords), # tuple comprehension parcel.get_data()[right_coords] += len(labels) labels = labels + [l.replace('L_', 'R_') for l in labels] if target_img: parcel = image.resample_to_img(parcel, target_img, interpolation='nearest') return parcel, labels, name, atlas_threshold
def prediction_to_image(data, input_image, reference_image=None, interpolation="linear", segmentation=False, segmentation_labels=None, threshold=0.5, sum_then_threshold=False, label_hierarchy=False): pred_image = new_img_like(input_image, data=data) if reference_image is not None: pred_image = resample_to_img(pred_image, reference_image, interpolation=interpolation) if segmentation: pred_image = one_hot_image_to_label_map( pred_image, labels=segmentation_labels, threshold=threshold, sum_then_threshold=sum_then_threshold, label_hierarchy=label_hierarchy) return pred_image
def prep_tmap(img, reference=None, center=False, scale=False, threshold=None, quantile=None, binary=False): """Quick transforms to speed corr. calc. for spatial maps""" if isinstance(img, (Nifti1Image, Nifti1Pair)): img = img elif img is None and isinstance(reference, (Nifti1Image, Nifti1Pair)): img = reference else: image.load_img(img) if isinstance(reference, (str, (Nifti1Image, Nifti1Pair))): if img.shape != reference.shape: img = image.resample_to_img(source_img=img, target_img=reference) dat = img.get_fdata(caching='unchanged').flatten() dat[np.logical_not(np.isfinite( dat))] = 0 # zero out all NaN, indexing syntax required by numpy if center: dat[dat.nonzero()] = dat[dat.nonzero()] - dat[dat.nonzero()].mean() if scale: if dat[dat.nonzero()].std(ddof=1) != 0: dat[dat.nonzero( )] = dat[dat.nonzero()] / dat[dat.nonzero()].std(ddof=1) if quantile: dat[dat < np.percentile(dat[dat.nonzero()], quantile)] = 0. if threshold: # if threshold appears to be fraction, threshold vol. based on fraction of maximum if (0 < threshold < 1 < dat.max()): threshold = dat.max() * threshold dat[dat < threshold] = 0. if binary: # note that prev. centering, quantiles, scaling will create 0 or neg. values dat[dat < 0] = 0. dat[dat.nonzero()] = 1. return dat
def prepare_roi_from_probtissue(in_file, epi_mask, epi_mask_erosion_mm=0, erosion_mm=0): import os import nibabel as nb import scipy.ndimage as nd from nilearn.image import resample_to_img probability_map_nii = resample_to_img(in_file, epi_mask) probability_map_data = probability_map_nii.get_data() # thresholding probability_map_data[probability_map_data < 0.95] = 0 probability_map_data[probability_map_data != 0] = 1 epi_mask_nii = nb.load(epi_mask) epi_mask_data = epi_mask_nii.get_data() if epi_mask_erosion_mm: epi_mask_data = nd.binary_erosion( epi_mask_data, iterations=int(epi_mask_erosion_mm / max(probability_map_nii.header.get_zooms()))).astype(int) eroded_mask_file = os.path.abspath("erodd_mask.nii.gz") nb.Nifti1Image(epi_mask_data, epi_mask_nii.affine, epi_mask_nii.header).to_filename(eroded_mask_file) else: eroded_mask_file = epi_mask probability_map_data[epi_mask_data != 1] = 0 # shrinking if erosion_mm: iter_n = int(erosion_mm/max(probability_map_nii.header.get_zooms())) probability_map_data = nd.binary_erosion(probability_map_data, iterations=iter_n).astype(int) new_nii = nb.Nifti1Image(probability_map_data, probability_map_nii.affine, probability_map_nii.header) new_nii.to_filename("roi.nii.gz") return os.path.abspath("roi.nii.gz"), eroded_mask_file
def get_roi_mask(atlas_maps, index_mask, labels, path=None, global_mask=None): """Return the Niftimasker object for a given ROI based on an atlas. Optionally resampled based on a global masker. """ if path is None: path = os.path.join(PROJECT_PATH, 'derivatives/fMRI/ROI_masks', labels[index_mask+1]) check_folder(path) if os.path.exists(path + '.nii.gz') and os.path.exists(path + '.yml'): masker = load_masker(path) else: mask = math_img('img > 50', img=index_img(atlas_maps, index_mask)) if global_mask: global_masker = nib.load(global_mask + '.nii.gz') mask = resample_to_img(mask, global_masker, interpolation='nearest') params = read_yaml(global_mask + '.yml') params['detrend'] = False params['standardize'] = False masker = NiftiMasker(mask) if global_mask: masker.set_params(**params) masker.fit() save_masker(masker, path) return masker
def apply_weighted_mask(img, mask): """ Returns weighted average of `mask` applied to `img` Averaging procedure ignores voxels which are 0 in `mask` Parameters ---------- img : niimg_like Image to which `mask` should be appplied mask : niimg_like Weighted (not binarized) mask to apply to `img` Returns ------- average : float Weighted average of `mask` applied to `img` """ mdata = mask.get_fdata() res = resample_to_img(img, mask).get_fdata() * mdata return res[mdata != 0].mean()
def _post_run_hook(self, runtime: Bunch) -> Bunch: if not self.inputs.bg_nii: self._bg_nii = nib.load( os.path.join(self.inputs.fs_dir, "mri", "T1.mgz")) else: self._bg_nii = nib.load(self.inputs.bg_nii) self._mask_nii = self.inputs.mask_nii or None # TODO: ENUM this to the available freesurfer parcellations parcellation = nib.load(self.inputs.parcellation) d_parcellation = parcellation.get_fdata().astype(int) # Re-normalize the ROI values by rank # Then extract colors from full colortable using rank ordering unique_v, u_id = np.unique(d_parcellation.flatten(), return_inverse=True) colormap = _parse_freesurfer_LUT(self.inputs.colortable) # Remap parcellation to rank ordering d_parcellation = u_id.reshape(d_parcellation.shape) parcellation = nimg.new_img_like(parcellation, d_parcellation, copy_header=True) # Resample to background resolution self._parcellation = nimg.resample_to_img(parcellation, self._bg_nii, interpolation='nearest') # Get segmentation colors self._colors = [colormap[i] for i in unique_v] # Now we need to call the parent process return super(IFreesurferVolParcellationRPT, self)._post_run_hook(runtime)
def inject_skullstripped(subjects_dir, subject_id, skullstripped): import os import nibabel as nib from nilearn.image import resample_to_img, new_img_like from niworkflows.nipype.utils.filemanip import copyfile mridir = os.path.join(subjects_dir, subject_id, 'mri') t1 = os.path.join(mridir, 'T1.mgz') bm_auto = os.path.join(mridir, 'brainmask.auto.mgz') bm = os.path.join(mridir, 'brainmask.mgz') if not os.path.exists(bm_auto): img = nib.load(t1) mask = nib.load(skullstripped) bmask = new_img_like(mask, mask.get_data() > 0) resampled_mask = resample_to_img(bmask, img, 'nearest') masked_image = new_img_like( img, img.get_data() * resampled_mask.get_data()) masked_image.to_filename(bm_auto) if not os.path.exists(bm): copyfile(bm_auto, bm, copy=True, use_hardlink=True) return subjects_dir, subject_id
def crop_nifti(input_img, ref_crop): """Crop input image based on the reference. It uses nilearn `resample_to_img` function. Args: input_img (str): image to be processed ref_crop (str): template used to crop the image Returns: output_img (NIfTI image): crop image on disk. crop_template: (NIfTI image): output template on disk. """ import os from nilearn.image import crop_img, resample_to_img basedir = os.getcwd() # crop_ref = crop_img(ref_img, rtol=0.5) # crop_ref.to_filename(os.path.join(basedir, os.path.basename(input_img).split('.nii')[0] + '_cropped_template.nii.gz')) # crop_template = os.path.join(basedir, os.path.basename(input_img).split('.nii')[0] + '_cropped_template.nii.gz') # resample the individual MRI into the cropped template image crop_img = resample_to_img(input_img, ref_crop, force_resample=True) crop_img.to_filename( os.path.join( basedir, os.path.basename(input_img).split(".nii")[0] + "_cropped.nii.gz" ) ) output_img = os.path.join( basedir, os.path.basename(input_img).split(".nii")[0] + "_cropped.nii.gz" ) crop_template = ref_crop return output_img, crop_template
############################################################################### # Print basic information on the dataset print('First gray-matter anatomy image (3D) is located at: %s' % oasis_dataset.gray_matter_maps[0]) # 3D data print('First white-matter anatomy image (3D) is located at: %s' % oasis_dataset.white_matter_maps[0]) # 3D data ############################################################################### # Get a mask image: A mask of the cortex of the ICBM template gm_mask = datasets.fetch_icbm152_brain_gm_mask() ############################################################################### # Resample the images, since this mask has a different resolution from nilearn.image import resample_to_img mask_img = resample_to_img( gm_mask, gray_matter_map_filenames[0], interpolation='nearest') ############################################################################# # Analyse data # ------------ # # First create an adequate design matrix with three columns: 'age', # 'sex', 'intercept'. import pandas as pd import numpy as np intercept = np.ones(n_subjects) design_matrix = pd.DataFrame(np.vstack((age, sex, intercept)).T, columns=['age', 'sex', 'intercept']) ############################################################################# # Plot the design matrix
icbm_mask = fetch_icbm152_brain_gm_mask() from nilearn.plotting import plot_roi plt.figure(figsize=(16, 4)) ax = plt.subplot(121) plot_roi(icbm_mask, title='ICBM mask', axes=ax) ax = plt.subplot(122) plot_roi(data_mask, title='Data-driven mask', axes=ax) plt.show() ######################################################################### # For the sake of time saving, we reample icbm_mask to our data # For this we call the resample_to_img routine of Nilearn. # We use interpolation = 'nearest' to keep the mask a binary image from nilearn.image import resample_to_img resampled_icbm_mask = resample_to_img(icbm_mask, data_mask, interpolation='nearest') ######################################################################### # Impact on the first-level model first_level_model = FirstLevelModel( t_r, hrf_model='spm + derivative', smoothing_fwhm=5, slice_time_ref=0.5, mask=resampled_icbm_mask).fit( fmri_img, events=events, confounds=confounds) design_matrix = first_level_model.design_matrices_[0] plot_design_matrix(design_matrix) plot_contrast(first_level_model) plt.show() ######################################################################### # Note that it removed spurious spots in the white matter.
# First we load the required datasets using the nilearn datasets module. from nilearn.datasets import fetch_localizer_button_task from nilearn.datasets import load_mni152_template template = load_mni152_template() localizer_dataset = fetch_localizer_button_task(get_anats=True) localizer_tmap_filename = localizer_dataset.tmaps[0] localizer_anat_filename = localizer_dataset.anats[0] ############################################################################### # Now, the localizer t-map image can be resampled to the MNI template image. from nilearn.image import resample_to_img resampled_localizer_tmap = resample_to_img(localizer_tmap_filename, template) ############################################################################### # Let's check the shape and affine have been correctly updated. # First load the original t-map in memory: from nilearn.image import load_img tmap_img = load_img(localizer_dataset.tmaps[0]) original_shape = tmap_img.shape original_affine = tmap_img.affine resampled_shape = resampled_localizer_tmap.shape resampled_affine = resampled_localizer_tmap.affine template_img = load_img(template)
def spatial_maps_pairwise_similarity(imgs1, imgs2, mask_file, distance='correlation'): """ Similarity values of each image in `imgs1` to each image in `imgs2`, both masked by `mask_file`. These values are based on distance metrics, specified by `distance` argument. The resulting similarity value is the complementary value of the distance, i.e., '1 - <distance value>'. The images in `imgs1` will be resampled to `imgs2` if their affine matrix don't match. Parameters ---------- imgs1: list of niimg-like or 4D niimg-like imgs2: list of niimg-like or 4D niimg-like mask_file: niimg-like distance: str Valid values for `distance` are: From scikit-learn: ['cityblock', 'cosine', 'euclidean', 'l1', 'l2', 'manhattan']. From scipy.spatial.distance: ['braycurtis', 'canberra', 'chebyshev', 'correlation', 'dice', 'hamming', 'jaccard', 'kulsinski', 'mahalanobis', 'matching', 'minkowski', 'rogerstanimoto', 'russellrao', 'seuclidean', 'sokalmichener', 'sokalsneath', 'sqeuclidean', 'yule'] See the documentation for scipy.spatial.distance for details on these metrics. Returns ------- corrs: np.ndarray A matrix of shape MxN, where M is len(imgs1) and N is len(imgs2). It contains the similarity values. """ img1_ = niimg.load_img(imgs1) img2_ = niimg.load_img(imgs2) n_imgs1 = img1_.shape[-1] n_imgs2 = img2_.shape[-1] corrs = np.zeros((n_imgs1, n_imgs2), dtype=float) mask_trnsf = niimg.resample_to_img(mask_file, niimg.index_img(img2_, 0), interpolation='nearest', copy=True) for idx1, img1 in enumerate(niimg.iter_img(img1_)): img1_resamp = niimg.resample_to_img(img1, niimg.index_img(img2_, 0), copy=True) img1_masked = nimask.apply_mask(img1_resamp, mask_trnsf) for idx2, img2 in enumerate(niimg.iter_img(img2_)): img2_masked = nimask.apply_mask(img2, mask_trnsf) dist = pairwise_distances(img1_masked.reshape(1, -1), img2_masked.reshape(1, -1), metric=distance) # since this is a scalar value dist = dist[0][0] # since this is a distance, not a similarity value corr = 1 - dist # store it corrs[idx1, idx2] = corr return corrs
def spatial_maps_goodness_of_fit(rsn_imgs, spatial_maps, mask_file, rsn_thr=4.0): """ Goodness-of-fit values described as in Zhou et al., 2010, Brain. Parameters ---------- rsn_imgs: list of niimg-like or 4D niimg-like The RSN maps. They should be thresholded beforehand if `rsn_thr` is lower or equal than 0. spatial_maps: list of niimg-like or 4D niimg-like mask_file: niimg-like An extra mask to apply to the thresholded RSN masks. This is used to exclude values outside of the RSN blobs. It is recommended to use a brain mask for this. rsn_thr: float, optional The threshold to apply to `rsn_imgs` to create the RSN masks. If rsn_thr <= 0, no thresholding will be applied. Returns ------- gof_df: np.ndarray A matrix of shape MxN, where M is len(rsn_imgs) and N is len(spatial_maps). It contains the goodness-of-fit values. Notes ----- "These ICN templates were thresholded at a z-score 4.0 to be visually comparable to the consistent ICNs published by Damoiseaux et al. (2006). A minor modification of previous goodness-of-fit methods (Seeley et al., 2007b, 2009) was included here for template matching, with goodness-of-fit scores calculated by multiplying (i) the average z-score difference between voxels falling within the template and voxels falling outside the template; and (ii) the difference in the percentage of positive z-score voxels inside and outside the template. This goodness-of-fit algorithm proves less vulnerable to inter-subject variability in shape, size, location and strength of each ICN", than the one published in Seeley et al., 2007b. This latter method only uses the value in (i). Extracted from Zhou et al., 2010, Brain. """ rsn_img = niimg.load_img(rsn_imgs) spm_img = niimg.load_img(spatial_maps) n_rsns = rsn_img.shape[-1] n_ics = spm_img.shape[-1] gofs = np.zeros((n_rsns, n_ics), dtype=float) # threshold the RSN templates if rsn_thr > 0: thr_rsns = (spatial_map(rsn, thr=rsn_thr, mode='+-') for rsn in niimg.iter_img(rsn_img)) else: thr_rsns = rsn_img # for each RSN template and IC image iter_rsn_ic = itertools.product(enumerate(niimg.iter_img(thr_rsns)), enumerate(niimg.iter_img( spm_img))) for (rsn_idx, rsn), (ic_idx, ic) in iter_rsn_ic: ref_vol = rsn.get_data() rsn_vol = np.zeros(rsn.shape, dtype=int) #rsn_in = niimg.math_img('np.abs(img) > 0', img=rsn) rsn_in = rsn_vol.copy() rsn_in[np.abs(ref_vol) > 0] = 1 #rsn_out = niimg.math_img('img == 0', img=rsn) rsn_out = rsn_vol.copy() rsn_out[ref_vol == 0] = 1 if mask_file is not None: # rsn_out = niimg.math_img('mask * img', mask=rsn_brain_mask, img=rsn_out) rsn_brain_mask = niimg.resample_to_img(mask_file, rsn, interpolation='nearest') rsn_out = rsn_brain_mask.get_data() * rsn_out # convert the mask arrays to image in order to resample rsn_in = niimg.new_img_like(rsn, rsn_in) rsn_out = niimg.new_img_like(rsn, rsn_out) rsn_in = niimg.resample_to_img(rsn_in, ic, interpolation='nearest') rsn_out = niimg.resample_to_img(rsn_out, ic, interpolation='nearest') # apply the mask #zscore_in = niimg.math_img('mask * img', mask=rsn_in, img=ic).get_data() zscore_in = rsn_in.get_data() * ic.get_data() #zscore_out = niimg.math_img('mask * img', mask=rsn_out, img=ic).get_data() zscore_out = rsn_out.get_data() * ic.get_data() #gof_term1 # calculate the the average z-score difference between voxels falling # within the template and voxels falling outside the template gof_term1 = zscore_in.mean() - zscore_out.mean() #gof_term2 # the difference in the percentage of positive z-score voxels inside and outside the template. n_pos_zscore_in = np.sum(zscore_in > 0) n_pos_zscore_out = np.sum(zscore_out > 0) n_pos_zscore_tot = n_pos_zscore_in + n_pos_zscore_out if n_pos_zscore_tot != 0: n_pos_zscore_pcnt = 100 / n_pos_zscore_tot gof_term2 = (n_pos_zscore_in - n_pos_zscore_out) * n_pos_zscore_pcnt else: gof_term2 = 0 # global gof gof = gof_term1 * gof_term2 # add the result gofs[rsn_idx][ic_idx] = gof return gofs
def _create_cifti_image(bold_file, label_file, annotation_files, gii_files, volume_target, surface_target, tr): """ Generate CIFTI image in target space Parameters bold_file : 4D BOLD timeseries label_file : label atlas annotation_files : FreeSurfer annotations gii_files : 4D BOLD surface timeseries in GIFTI format volume_target : label atlas space surface_target : gii_files space tr : repetition timeseries Returns out_file : BOLD data as CIFTI dtseries """ label_img = nb.load(label_file) bold_img = resample_to_img(bold_file, label_img) bold_data = bold_img.get_data() timepoints = bold_img.shape[3] label_data = label_img.get_data() # set up CIFTI information series_map = ci.Cifti2MatrixIndicesMap((0, ), 'CIFTI_INDEX_TYPE_SERIES', number_of_series_points=timepoints, series_exponent=0, series_start=0.0, series_step=tr, series_unit='SECOND') # Create CIFTI brain models idx_offset = 0 brainmodels = [] bm_ts = np.empty((timepoints, 0)) for structure, labels in CIFTI_STRUCT_WITH_LABELS.items(): if labels is None: # surface model model_type = "CIFTI_MODEL_TYPE_SURFACE" # use the corresponding annotation hemi = structure.split('_')[-1] annot = nb.freesurfer.read_annot(annotation_files[hemi == "RIGHT"]) # currently only supports L/R cortex gii = nb.load(gii_files[hemi == "RIGHT"]) # calculate total number of vertices surf_verts = len(annot[0]) # remove medial wall for CIFTI format vert_idx = np.nonzero(annot[0] != annot[2].index(b'unknown'))[0] # extract values across volumes ts = np.array([tsarr.data[vert_idx] for tsarr in gii.darrays]) vert_idx = ci.Cifti2VertexIndices(vert_idx) bm = ci.Cifti2BrainModel(index_offset=idx_offset, index_count=len(vert_idx), model_type=model_type, brain_structure=structure, vertex_indices=vert_idx, n_surface_vertices=surf_verts) bm_ts = np.column_stack((bm_ts, ts)) idx_offset += len(vert_idx) brainmodels.append(bm) else: model_type = "CIFTI_MODEL_TYPE_VOXELS" vox = [] ts = None for label in labels: ijk = np.nonzero(label_data == label) ts = (bold_data[ijk] if ts is None else np.concatenate((ts, bold_data[ijk]))) vox += [[ijk[0][ix], ijk[1][ix], ijk[2][ix]] for ix, row in enumerate(ts)] bm_ts = np.column_stack((bm_ts, ts.T)) vox = ci.Cifti2VoxelIndicesIJK(vox) bm = ci.Cifti2BrainModel(index_offset=idx_offset, index_count=len(vox), model_type=model_type, brain_structure=structure, voxel_indices_ijk=vox) idx_offset += len(vox) brainmodels.append(bm) volume = ci.Cifti2Volume( bold_img.shape[:3], ci.Cifti2TransformationMatrixVoxelIndicesIJKtoXYZ(-3, bold_img.affine)) brainmodels.append(volume) # create CIFTI geometry based on brainmodels geometry_map = ci.Cifti2MatrixIndicesMap((1, ), 'CIFTI_INDEX_TYPE_BRAIN_MODELS', maps=brainmodels) # provide some metadata to CIFTI matrix meta = { "target_surface": surface_target, "target_volume": volume_target, } # generate and save CIFTI image matrix = ci.Cifti2Matrix() matrix.append(series_map) matrix.append(geometry_map) matrix.metadata = ci.Cifti2MetaData(meta) hdr = ci.Cifti2Header(matrix) img = ci.Cifti2Image(bm_ts, hdr) img.nifti_header.set_intent('NIFTI_INTENT_CONNECTIVITY_DENSE_SERIES') _, out_base, _ = split_filename(bold_file) out_file = "{}.dtseries.nii".format(out_base) ci.save(img, out_file) return os.path.join(os.getcwd(), out_file)
############################################################################### # First we load the required datasets using the nilearn datasets module. from nilearn.datasets import fetch_neurovault_motor_task from nilearn.datasets import load_mni152_template template = load_mni152_template() motor_images = fetch_neurovault_motor_task() stat_img = motor_images.images[0] ############################################################################### # Now, the localizer t-map image can be resampled to the MNI template image. from nilearn.image import resample_to_img resampled_stat_img = resample_to_img(stat_img, template) ############################################################################### # Let's check the shape and affine have been correctly updated. # First load the original t-map in memory: from nilearn.image import load_img tmap_img = load_img(stat_img) original_shape = tmap_img.shape original_affine = tmap_img.affine resampled_shape = resampled_stat_img.shape resampled_affine = resampled_stat_img.affine template_img = load_img(template)