def _compose_transforms(transformDirectory, invert=False): """Strings together transofrm files in the correct order to apply a transform. """ transforms = [] if not invert: if '1Warp.nii.gz' in os.listdir(transformDirectory): SyN_file = os.path.join(transformDirectory, '1Warp.nii.gz') field = ants.image_read(SyN_file) transform = ants.transform_from_displacement_field(field) if transform is None: # Adds compatibility with ANTsPy 2.0+ transform = _transform_from_displacement_field(field) transforms.append(transform) if '0GenericAffine.mat' in os.listdir(transformDirectory): affine_file = os.path.join(transformDirectory, '0GenericAffine.mat') transforms.append(ants.read_transform(affine_file)) else: if '0GenericAffine.mat' in os.listdir(transformDirectory): affine_file = os.path.join(transformDirectory, '0GenericAffine.mat') transforms.append(ants.read_transform(affine_file).invert()) if '1InverseWarp.nii.gz' in os.listdir(transformDirectory): inv_file = os.path.join(transformDirectory, '1InverseWarp.nii.gz') field = ants.image_read(inv_file) transform = ants.transform_from_displacement_field(field) if transform is None: # Adds compatibility with ANTsPy 2.0+ transform = _transform_from_displacement_field(field) transforms.append(transform) return ants.compose_ants_transforms(transforms)
def test_read_write_transform(self): for tx in self.txs: filename = mktemp(suffix='.mat') ants.write_transform(tx, filename) tx2 = ants.read_transform(filename) # file doesnt exist with self.assertRaises(Exception): ants.read_transform('blah-blah.mat')
def planewise_affine(fixed, moving, return_transforms=False): zshift = get_zshift(fixed, moving) fixed = to_numpy(fixed) moving = to_numpy(moving) size_z = fixed.shape[0] warped = np.zeros_like(fixed) transforms = [None]*size_z for z in prog_percent(list(range(max((0, -zshift)), min((size_z, -zshift + size_z))))): mov = ants.from_numpy(moving[z + zshift].swapaxes(0, 1)) fix = ants.from_numpy(fixed[z].swapaxes(0, 1)) res = ants.registration(mov, fix, type_of_transform='Affine', reg_iterations=[500, 500, 500], grad_step=.1, verbose=True) t = ants.read_transform(res['fwdtransforms'][0]) transforms[z] = t trans = ants.apply_ants_transform_to_image(t, mov, fix) warped[z] = trans.numpy().swapaxes(0, 1) if return_transforms: return warped, (transforms, zshift) return warped
def motion_correction(brain_master, brain_slave, motcorr_directory, printlog, meanbrain, suffix=''): motCorr_brain_master = [] motCorr_brain_slave = [] durations = [] transform_matrix = [] for i in range(np.shape(brain_master)[-1]): #printlog('Aligning brain volume {}'.format(i)) t0 = time() #First, align given master volume to master meanbrain with stderr_redirected(): # to prevent dumb itk gaussian error bullshit infinite printing # note meanbrain is already an ants object motCorr_vol = ants.registration(meanbrain, ants.from_numpy(brain_master[:,:,:,i]), type_of_transform='SyN') motCorr_brain_master.append(motCorr_vol['warpedmovout'].numpy()) transformlist = motCorr_vol['fwdtransforms'] #Use warp parameters on slave volume if provided if brain_slave: motCorr_brain_slave.append(ants.apply_transforms(meanbrain,ants.from_numpy(brain_slave[:,:,:,i]),transformlist).numpy()) #Lets immediately grab the transform file because otherwise I think it is auto deleted due to "tmp" status...? #Indeed I think CentOS possibly perges /tmp pretty frequently #printlog('fwd_files: {}'.format(transformlist)) for x in transformlist: if '.mat' in x: temp = ants.read_transform(x) transform_matrix.append(temp.parameters) os.remove(x) #printlog('Deleted fwd: {}'.format(x)) # Delete invtransforms for /tmp directory size issue. note that .mat are shared, so only need to delete .nii.gz transformlist = motCorr_vol['invtransforms'] #printlog('inv_files: {}'.format(transformlist)) for x in transformlist: if '.mat' not in x: os.remove(x) #printlog('Deleted inv: {}'.format(x)) print(F"[{i+1}]") #IMPORTANT FOR COMMUNICATION WITH DATAFLOW MAIN sys.stdout.flush() # Save motcorr brains save_motCorr_brain(motCorr_brain_master, motcorr_directory, suffix='red'+suffix) if brain_slave: save_motCorr_brain(motCorr_brain_slave, motcorr_directory, suffix='green'+suffix) # Save transforms transform_matrix = np.array(transform_matrix) save_file = os.path.join(motcorr_directory, 'motcorr_params{}'.format(suffix)) np.save(save_file,transform_matrix)
def get_zshift(fixed, moving): fixed_ants = to_ants(fixed) moving_ants = to_ants(moving) res = ants.registration(fixed_ants, moving_ants, type_of_transform='Translation', grad_step=.2) t = ants.read_transform(res['fwdtransforms'][0]) zshift_float = t.parameters[-1] zshift = int(round(zshift_float)) return zshift
def transform_coordinates(coordinates, from_imaging, to_imaging, file_invMatrix): """coordinate transformation from one imaging modality to other; coordinates must be included as integers""" transformed = {'points': [], 'indices': []} physical_points = ants.transform_index_to_physical_point( from_imaging, coordinates) transformed['points'] = ants.apply_ants_transform( ants.read_transform(file_invMatrix), physical_points) transformed['indices'] = ants.transform_physical_point_to_index( image=to_imaging, point=transformed['points']) return transformed
def transform_rois(fixed, moving, rois, **kwargs): def set_ifn(key, val): if not key in kwargs: kwargs[key] = val set_ifn('type_of_transform', 'Affine') set_ifn('reg_iterations', [500, 500, 500]) set_ifn('grad_step', .1) res = ants.registration(fixed, moving, **kwargs) t = ants.read_transform(res['fwdtransforms'][0]) xyzs = rois[:, :3] rs = rois[:, 3:] xyzs_transformed = np.array(list(map(lambda xyz: transform_xyz(t.invert(), xyz, moving, fixed), xyzs))) return np.concatenate([xyzs_transformed, rs], axis=1)
def main(input_path, transform_path, resampled_image_path): if resampled_image_path is None and transform_path is None: raise ValueError('You must provide the path to at least one output') try: import ants except ImportError as e: message = 'Install ANTS for registration: pip install antspyx' raise ModuleNotFoundError(message) from e import numpy as np import torchio as tio reference = ants.image_read(str(tio.datasets.Colin27().t1.path)) floating = ants.image_read(input_path) results = ants.registration(reference, floating, type_of_transform='Affine') if transform_path is not None: transform = ants.read_transform(results['fwdtransforms'][0]) affine = np.eye(4) affine[:3] = transform.parameters.reshape(4, 3).T affine = tio.io._from_itk_convention(affine) tio.io.write_matrix(affine, transform_path) if resampled_image_path is not None: ants.image_write(results['warpedmovout'], resampled_image_path) return 0
def ANTsCoregisterMultiprocessing(self, file_fixed, file_moving, subj, input_folder, flag, step, status, run=1): """Performs Co-Registration taking advantage of multicores, i.e. multiple subjects processed in parallel""" status.put(tuple([file_fixed, file_moving, subj])) prev_reg = glob.glob( os.path.join(input_folder + "/" + self.cfg['preprocess'][flag]['prefix'] + 'run*' + os.path.basename(file_moving))) if not prev_reg: print('\tNo previous registration found, starting with first run') filename_save = os.path.join( input_folder, self.cfg['preprocess'][flag]['prefix'] + 'run' + str(run) + '_' + os.path.basename(file_moving)) elif re.search(r'\w+{}.'.format('CT_'), file_moving, re.IGNORECASE) and file_moving.endswith('.nii'): print('\tNo second run for CT-MRI registrations possible.') return else: allruns = [ re.search(r'\w+(run)([\d.]+)', x).group(2) for x in prev_reg ] lastrun = int(sorted(allruns)[-1]) file_moving = os.path.join( input_folder, self.cfg["preprocess"]["registration"]["prefix"] + 'run' + str(lastrun) + '_' + os.path.basename(file_moving)) # update for second run run = lastrun + 1 n4prefix = self.cfg['preprocess']['ANTsN4']['prefix'] basename = '{}{}'.format(n4prefix, file_moving.split(n4prefix)[1]) filename_save = os.path.join( input_folder, self.cfg['preprocess'][flag]['prefix'] + 'run' + str(run) + '_' + basename) print(filename_save) log_filename = os.path.join( ROOTDIR, 'logs', "log_Registration_using_ANTs_{}_run_{}_".format(subj, str(run)) + time.strftime("%Y%m%d-%H%M%S") + '.txt') imaging = dict() for idx, file_id in enumerate([file_fixed, file_moving]): sequence = ants.image_read( file_id) # load data and resample images if necessary imaging[idx] = Imaging.resampleANTs( mm_spacing=self.cfg['preprocess']['registration'] ['resample_spacing'], ANTsImageObject=sequence, file_id=file_id, method=int( self.cfg['preprocess']['registration']['resample_method'])) if run == 1: metric = self.cfg['preprocess']['registration']['metric'][0] else: self.cfg['preprocess']['registration'][ 'default_registration'] = 'yes' # TODO: must be changed if non-default works metric = self.cfg['preprocess']['registration']['metric'][0] if self.cfg['preprocess']['registration'][ 'default_registration'] == 'yes': registered_images = self.default_registration(imaging, file_fixed, file_moving, log_filename, metric=metric, step=step) else: registered_images = self.custom_registration( imaging, file_fixed, file_moving, input_folder + '/', log_filename, run) key2rename = { 'fwdtransforms': ['{}_0GenericAffineRegistration.mat'.format(step), 1], 'invtransforms': ['{}_1InvWarpMatrix.mat'.format(step), 0] } for key, value in key2rename.items(): Transform = ants.read_transform(registered_images[key][value[1]]) ants.write_transform(Transform, os.path.join(input_folder, value[0])) ants.image_write(registered_images['warpedmovout'], filename=filename_save) FileOperations.create_folder(os.path.join(input_folder, "debug")) if run > 1: # Previous registrations are moved to debug-folder prev_reg = ''.join(prev_reg) if type( prev_reg) == list else prev_reg filename_dest = re.sub( r'({}run[0-9]_)+({})'.format( self.cfg['preprocess']['registration']['prefix'], self.cfg['preprocess']['ANTsN4']['prefix']), '{}RUNPREV{}_{}'.format( self.cfg['preprocess']['registration']['prefix'], lastrun, self.cfg['preprocess']['ANTsN4']['prefix']), os.path.basename(prev_reg)) shutil.move(prev_reg, os.path.join(input_folder, 'debug', filename_dest)) create_mask = True if create_mask and 't1' in file_moving and not os.path.isfile( os.path.join(input_folder, 'brainmask_T1.nii')): Imaging.create_brainmask( input_folder, subj=subj, registered_images=registered_images['warpedmovout'])
mi = ants.image_read(ants.get_data("r64")) tx = "Affine" pnum = 0 tx = "SyN" pnum = 1 metrics = ["MeanSquares", "GC", "Mattes"] asr = 1 for m in range(0, len(metrics)): mytx1 = ants.registration( fixed=fi, moving=mi, type_of_transform=tx, aff_metric=metrics[m], aff_random_sampling_rate=asr, ) p1 = ants.read_transform(mytx1["fwdtransforms"][pnum]) p1 = ants.get_ants_transform_parameters(p1) for k in range(0, 2): mytx2 = ants.registration( fixed=fi, moving=mi, type_of_transform=tx, aff_metric=metrics[m], aff_random_sampling_rate=asr, ) p2 = ants.read_transform(mytx2["fwdtransforms"][pnum]) p2 = ants.get_ants_transform_parameters(p2) metval = ants.image_mutual_information(fi, mytx2["warpedmovout"]) chg = abs(p2 - p1).sum() print(metrics[m] + " Change: try " + str(k) + " Is " + str(chg) + " Similarity= " + str(metval))
def test_example(self): # test ANTsPy/ANTsR example fi = ants.image_read(ants.get_ants_data("r16")) mi = ants.image_read(ants.get_ants_data("r27")) txfile = ants.affine_initializer(fi, mi) tx = ants.read_transform(txfile, dimension=2)
def __init__(self, filename='path', **options): import ants self.tx = ants.read_transform(filename, **options)