warping_fields = [ WarpingField(filename) for filename in warping_fields_filename ] filenames_output = [] while True: try: warping_fields[0].num_of_frames = number_of_frames image_output_iter, iteration = warping_fields[0].next() image_output_iter.save() filename_warp = image_output_iter.path + image_output_iter.file_name + image_output_iter.ext filename_output = "tmp.warped_image_" + str( iteration - 1) + image_output_iter.ext run("sct_apply_transfo -i " + input_file + " -d " + reference_image + " -w " + filename_warp + " -o " + filename_output) filenames_output.append(filename_output) except ValueError: printv('\nError during warping field generation...', 1, 'error') except StopIteration: printv('\nFinished iterations.') break # run("fslmerge -t " + output_file + " " + " ".join(filenames_output)) from sct_concat_data import concat_data concat_data(','.join(filenames_output), output_file, dim=3) run("rm -rf tmp.*") printv('fslview ' + output_file + " &", 1, 'info')
def main(): # Initialization fname_anat = '' fname_point = '' slice_gap = param.gap remove_tmp_files = param.remove_tmp_files gaussian_kernel = param.gaussian_kernel start_time = time.time() verbose = 1 # get path of the toolbox status, path_sct = commands.getstatusoutput('echo $SCT_DIR') path_sct = sct.slash_at_the_end(path_sct, 1) # Parameters for debug mode if param.debug == 1: sct.printv('\n*** WARNING: DEBUG MODE ON ***\n\t\t\tCurrent working directory: '+os.getcwd(), 'warning') status, path_sct_testing_data = commands.getstatusoutput('echo $SCT_TESTING_DATA_DIR') fname_anat = path_sct_testing_data+'/t2/t2.nii.gz' fname_point = path_sct_testing_data+'/t2/t2_centerline_init.nii.gz' slice_gap = 5 else: # Check input param try: opts, args = getopt.getopt(sys.argv[1:],'hi:p:g:r:k:') except getopt.GetoptError as err: print str(err) usage() if not opts: usage() for opt, arg in opts: if opt == '-h': usage() elif opt in ('-i'): fname_anat = arg elif opt in ('-p'): fname_point = arg elif opt in ('-g'): slice_gap = int(arg) elif opt in ('-r'): remove_tmp_files = int(arg) elif opt in ('-k'): gaussian_kernel = int(arg) # display usage if a mandatory argument is not provided if fname_anat == '' or fname_point == '': usage() # check existence of input files sct.check_file_exist(fname_anat) sct.check_file_exist(fname_point) # extract path/file/extension path_anat, file_anat, ext_anat = sct.extract_fname(fname_anat) path_point, file_point, ext_point = sct.extract_fname(fname_point) # extract path of schedule file # TODO: include schedule file in sct # TODO: check existence of schedule file file_schedule = path_sct + param.schedule_file # Get input image orientation input_image_orientation = get_orientation(fname_anat) # Display arguments print '\nCheck input arguments...' print ' Anatomical image: '+fname_anat print ' Orientation: '+input_image_orientation print ' Point in spinal cord: '+fname_point print ' Slice gap: '+str(slice_gap) print ' Gaussian kernel: '+str(gaussian_kernel) print ' Degree of polynomial: '+str(param.deg_poly) # create temporary folder print('\nCreate temporary folder...') path_tmp = 'tmp.'+time.strftime("%y%m%d%H%M%S") sct.create_folder(path_tmp) print '\nCopy input data...' sct.run('cp '+fname_anat+ ' '+path_tmp+'/tmp.anat'+ext_anat) sct.run('cp '+fname_point+ ' '+path_tmp+'/tmp.point'+ext_point) # go to temporary folder os.chdir(path_tmp) # convert to nii convert('tmp.anat'+ext_anat, 'tmp.anat.nii') convert('tmp.point'+ext_point, 'tmp.point.nii') # Reorient input anatomical volume into RL PA IS orientation print '\nReorient input volume to RL PA IS orientation...' #sct.run(sct.fsloutput + 'fslswapdim tmp.anat RL PA IS tmp.anat_orient') set_orientation('tmp.anat.nii', 'RPI', 'tmp.anat_orient.nii') # Reorient binary point into RL PA IS orientation print '\nReorient binary point into RL PA IS orientation...' # sct.run(sct.fsloutput + 'fslswapdim tmp.point RL PA IS tmp.point_orient') set_orientation('tmp.point.nii', 'RPI', 'tmp.point_orient.nii') # Get image dimensions print '\nGet image dimensions...' nx, ny, nz, nt, px, py, pz, pt = Image('tmp.anat_orient.nii').dim print '.. matrix size: '+str(nx)+' x '+str(ny)+' x '+str(nz) print '.. voxel size: '+str(px)+'mm x '+str(py)+'mm x '+str(pz)+'mm' # Split input volume print '\nSplit input volume...' split_data('tmp.anat_orient.nii', 2, '_z') file_anat_split = ['tmp.anat_orient_z'+str(z).zfill(4) for z in range(0, nz, 1)] split_data('tmp.point_orient.nii', 2, '_z') file_point_split = ['tmp.point_orient_z'+str(z).zfill(4) for z in range(0, nz, 1)] # Extract coordinates of input point # sct.printv('\nExtract the slice corresponding to z='+str(z_init)+'...', verbose) # data_point = Image('tmp.point_orient.nii').data x_init, y_init, z_init = unravel_index(data_point.argmax(), data_point.shape) sct.printv('Coordinates of input point: ('+str(x_init)+', '+str(y_init)+', '+str(z_init)+')', verbose) # Create 2D gaussian mask sct.printv('\nCreate gaussian mask from point...', verbose) xx, yy = mgrid[:nx, :ny] mask2d = zeros((nx, ny)) radius = round(float(gaussian_kernel+1)/2) # add 1 because the radius includes the center. sigma = float(radius) mask2d = exp(-(((xx-x_init)**2)/(2*(sigma**2)) + ((yy-y_init)**2)/(2*(sigma**2)))) # Save mask to 2d file file_mask_split = ['tmp.mask_orient_z'+str(z).zfill(4) for z in range(0,nz,1)] nii_mask2d = Image('tmp.anat_orient_z0000.nii') nii_mask2d.data = mask2d nii_mask2d.setFileName(file_mask_split[z_init]+'.nii') nii_mask2d.save() # # # Get the coordinates of the input point # print '\nGet the coordinates of the input point...' # data_point = Image('tmp.point_orient.nii').data # x_init, y_init, z_init = unravel_index(data_point.argmax(), data_point.shape) # print '('+str(x_init)+', '+str(y_init)+', '+str(z_init)+')' # x_init, y_init, z_init = (data > 0).nonzero() # x_init = x_init[0] # y_init = y_init[0] # z_init = z_init[0] # print '('+str(x_init)+', '+str(y_init)+', '+str(z_init)+')' # # numpy.unravel_index(a.argmax(), a.shape) # # file = nibabel.load('tmp.point_orient.nii') # data = file.get_data() # x_init, y_init, z_init = (data > 0).nonzero() # x_init = x_init[0] # y_init = y_init[0] # z_init = z_init[0] # print '('+str(x_init)+', '+str(y_init)+', '+str(z_init)+')' # # # Extract the slice corresponding to z=z_init # print '\nExtract the slice corresponding to z='+str(z_init)+'...' # file_point_split = ['tmp.point_orient_z'+str(z).zfill(4) for z in range(0,nz,1)] # nii = Image('tmp.point_orient.nii') # data_crop = nii.data[:, :, z_init:z_init+1] # nii.data = data_crop # nii.setFileName(file_point_split[z_init]+'.nii') # nii.save() # # # Create gaussian mask from point # print '\nCreate gaussian mask from point...' # file_mask_split = ['tmp.mask_orient_z'+str(z).zfill(4) for z in range(0,nz,1)] # sct.run(sct.fsloutput+'fslmaths '+file_point_split[z_init]+' -s '+str(gaussian_kernel)+' '+file_mask_split[z_init]) # # # Obtain max value from mask # print '\nFind maximum value from mask...' # file = nibabel.load(file_mask_split[z_init]+'.nii') # data = file.get_data() # max_value_mask = numpy.max(data) # print '..'+str(max_value_mask) # # # Normalize mask beween 0 and 1 # print '\nNormalize mask beween 0 and 1...' # sct.run(sct.fsloutput+'fslmaths '+file_mask_split[z_init]+' -div '+str(max_value_mask)+' '+file_mask_split[z_init]) ## Take the square of the mask #print '\nCalculate the square of the mask...' #sct.run(sct.fsloutput+'fslmaths '+file_mask_split[z_init]+' -mul '+file_mask_split[z_init]+' '+file_mask_split[z_init]) # initialize variables file_mat = ['tmp.mat_z'+str(z).zfill(4) for z in range(0,nz,1)] file_mat_inv = ['tmp.mat_inv_z'+str(z).zfill(4) for z in range(0,nz,1)] file_mat_inv_cumul = ['tmp.mat_inv_cumul_z'+str(z).zfill(4) for z in range(0,nz,1)] # create identity matrix for initial transformation matrix fid = open(file_mat_inv_cumul[z_init], 'w') fid.write('%i %i %i %i\n' %(1, 0, 0, 0) ) fid.write('%i %i %i %i\n' %(0, 1, 0, 0) ) fid.write('%i %i %i %i\n' %(0, 0, 1, 0) ) fid.write('%i %i %i %i\n' %(0, 0, 0, 1) ) fid.close() # initialize centerline: give value corresponding to initial point x_centerline = [x_init] y_centerline = [y_init] z_centerline = [z_init] warning_count = 0 # go up (1), then down (2) in reference to the binary point for iUpDown in range(1, 3): if iUpDown == 1: # z increases slice_gap_signed = slice_gap elif iUpDown == 2: # z decreases slice_gap_signed = -slice_gap # reverse centerline (because values will be appended at the end) x_centerline.reverse() y_centerline.reverse() z_centerline.reverse() # initialization before looping z_dest = z_init # point given by user z_src = z_dest + slice_gap_signed # continue looping if 0 < z < nz while 0 <= z_src and z_src <= nz-1: # print current z: print 'z='+str(z_src)+':' # estimate transformation sct.run(fsloutput+'flirt -in '+file_anat_split[z_src]+' -ref '+file_anat_split[z_dest]+' -schedule '+file_schedule+ ' -verbose 0 -omat '+file_mat[z_src]+' -cost normcorr -forcescaling -inweight '+file_mask_split[z_dest]+' -refweight '+file_mask_split[z_dest]) # display transfo status, output = sct.run('cat '+file_mat[z_src]) print output # check if transformation is bigger than 1.5x slice_gap tx = float(output.split()[3]) ty = float(output.split()[7]) norm_txy = linalg.norm([tx, ty],ord=2) if norm_txy > 1.5*slice_gap: print 'WARNING: Transformation is too large --> using previous one.' warning_count = warning_count + 1 # if previous transformation exists, replace current one with previous one if os.path.isfile(file_mat[z_dest]): sct.run('cp '+file_mat[z_dest]+' '+file_mat[z_src]) # estimate inverse transformation matrix sct.run('convert_xfm -omat '+file_mat_inv[z_src]+' -inverse '+file_mat[z_src]) # compute cumulative transformation sct.run('convert_xfm -omat '+file_mat_inv_cumul[z_src]+' -concat '+file_mat_inv[z_src]+' '+file_mat_inv_cumul[z_dest]) # apply inverse cumulative transformation to initial gaussian mask (to put it in src space) sct.run(fsloutput+'flirt -in '+file_mask_split[z_init]+' -ref '+file_mask_split[z_init]+' -applyxfm -init '+file_mat_inv_cumul[z_src]+' -out '+file_mask_split[z_src]) # open inverse cumulative transformation file and generate centerline fid = open(file_mat_inv_cumul[z_src]) mat = fid.read().split() x_centerline.append(x_init + float(mat[3])) y_centerline.append(y_init + float(mat[7])) z_centerline.append(z_src) #z_index = z_index+1 # define new z_dest (target slice) and new z_src (moving slice) z_dest = z_dest + slice_gap_signed z_src = z_src + slice_gap_signed # Reconstruct centerline # ==================================================================================================== # reverse back centerline (because it's been reversed once, so now all values are in the right order) x_centerline.reverse() y_centerline.reverse() z_centerline.reverse() # fit centerline in the Z-X plane using polynomial function print '\nFit centerline in the Z-X plane using polynomial function...' coeffsx = polyfit(z_centerline, x_centerline, deg=param.deg_poly) polyx = poly1d(coeffsx) x_centerline_fit = polyval(polyx, z_centerline) # calculate RMSE rmse = linalg.norm(x_centerline_fit-x_centerline)/sqrt( len(x_centerline) ) # calculate max absolute error max_abs = max( abs(x_centerline_fit-x_centerline) ) print '.. RMSE (in mm): '+str(rmse*px) print '.. Maximum absolute error (in mm): '+str(max_abs*px) # fit centerline in the Z-Y plane using polynomial function print '\nFit centerline in the Z-Y plane using polynomial function...' coeffsy = polyfit(z_centerline, y_centerline, deg=param.deg_poly) polyy = poly1d(coeffsy) y_centerline_fit = polyval(polyy, z_centerline) # calculate RMSE rmse = linalg.norm(y_centerline_fit-y_centerline)/sqrt( len(y_centerline) ) # calculate max absolute error max_abs = max( abs(y_centerline_fit-y_centerline) ) print '.. RMSE (in mm): '+str(rmse*py) print '.. Maximum absolute error (in mm): '+str(max_abs*py) # display if param.debug == 1: import matplotlib.pyplot as plt plt.figure() plt.plot(z_centerline,x_centerline,'.',z_centerline,x_centerline_fit,'r') plt.legend(['Data','Polynomial Fit']) plt.title('Z-X plane polynomial interpolation') plt.show() plt.figure() plt.plot(z_centerline,y_centerline,'.',z_centerline,y_centerline_fit,'r') plt.legend(['Data','Polynomial Fit']) plt.title('Z-Y plane polynomial interpolation') plt.show() # generate full range z-values for centerline z_centerline_full = [iz for iz in range(0, nz, 1)] # calculate X and Y values for the full centerline x_centerline_fit_full = polyval(polyx, z_centerline_full) y_centerline_fit_full = polyval(polyy, z_centerline_full) # Generate fitted transformation matrices and write centerline coordinates in text file print '\nGenerate fitted transformation matrices and write centerline coordinates in text file...' file_mat_inv_cumul_fit = ['tmp.mat_inv_cumul_fit_z'+str(z).zfill(4) for z in range(0,nz,1)] file_mat_cumul_fit = ['tmp.mat_cumul_fit_z'+str(z).zfill(4) for z in range(0,nz,1)] fid_centerline = open('tmp.centerline_coordinates.txt', 'w') for iz in range(0, nz, 1): # compute inverse cumulative fitted transformation matrix fid = open(file_mat_inv_cumul_fit[iz], 'w') fid.write('%i %i %i %f\n' %(1, 0, 0, x_centerline_fit_full[iz]-x_init) ) fid.write('%i %i %i %f\n' %(0, 1, 0, y_centerline_fit_full[iz]-y_init) ) fid.write('%i %i %i %i\n' %(0, 0, 1, 0) ) fid.write('%i %i %i %i\n' %(0, 0, 0, 1) ) fid.close() # compute forward cumulative fitted transformation matrix sct.run('convert_xfm -omat '+file_mat_cumul_fit[iz]+' -inverse '+file_mat_inv_cumul_fit[iz]) # write centerline coordinates in x, y, z format fid_centerline.write('%f %f %f\n' %(x_centerline_fit_full[iz], y_centerline_fit_full[iz], z_centerline_full[iz]) ) fid_centerline.close() # Prepare output data # ==================================================================================================== # write centerline as text file for iz in range(0, nz, 1): # compute inverse cumulative fitted transformation matrix fid = open(file_mat_inv_cumul_fit[iz], 'w') fid.write('%i %i %i %f\n' %(1, 0, 0, x_centerline_fit_full[iz]-x_init) ) fid.write('%i %i %i %f\n' %(0, 1, 0, y_centerline_fit_full[iz]-y_init) ) fid.write('%i %i %i %i\n' %(0, 0, 1, 0) ) fid.write('%i %i %i %i\n' %(0, 0, 0, 1) ) fid.close() # write polynomial coefficients savetxt('tmp.centerline_polycoeffs_x.txt',coeffsx) savetxt('tmp.centerline_polycoeffs_y.txt',coeffsy) # apply transformations to data print '\nApply fitted transformation matrices...' file_anat_split_fit = ['tmp.anat_orient_fit_z'+str(z).zfill(4) for z in range(0,nz,1)] file_mask_split_fit = ['tmp.mask_orient_fit_z'+str(z).zfill(4) for z in range(0,nz,1)] file_point_split_fit = ['tmp.point_orient_fit_z'+str(z).zfill(4) for z in range(0,nz,1)] for iz in range(0, nz, 1): # forward cumulative transformation to data sct.run(fsloutput+'flirt -in '+file_anat_split[iz]+' -ref '+file_anat_split[iz]+' -applyxfm -init '+file_mat_cumul_fit[iz]+' -out '+file_anat_split_fit[iz]) # inverse cumulative transformation to mask sct.run(fsloutput+'flirt -in '+file_mask_split[z_init]+' -ref '+file_mask_split[z_init]+' -applyxfm -init '+file_mat_inv_cumul_fit[iz]+' -out '+file_mask_split_fit[iz]) # inverse cumulative transformation to point sct.run(fsloutput+'flirt -in '+file_point_split[z_init]+' -ref '+file_point_split[z_init]+' -applyxfm -init '+file_mat_inv_cumul_fit[iz]+' -out '+file_point_split_fit[iz]+' -interp nearestneighbour') # Merge into 4D volume print '\nMerge into 4D volume...' # sct.run(fsloutput+'fslmerge -z tmp.anat_orient_fit tmp.anat_orient_fit_z*') # sct.run(fsloutput+'fslmerge -z tmp.mask_orient_fit tmp.mask_orient_fit_z*') # sct.run(fsloutput+'fslmerge -z tmp.point_orient_fit tmp.point_orient_fit_z*') concat_data(glob.glob('tmp.anat_orient_fit_z*.nii'), 'tmp.anat_orient_fit.nii', dim=2) concat_data(glob.glob('tmp.mask_orient_fit_z*.nii'), 'tmp.mask_orient_fit.nii', dim=2) concat_data(glob.glob('tmp.point_orient_fit_z*.nii'), 'tmp.point_orient_fit.nii', dim=2) # Copy header geometry from input data print '\nCopy header geometry from input data...' copy_header('tmp.anat_orient.nii', 'tmp.anat_orient_fit.nii') copy_header('tmp.anat_orient.nii', 'tmp.mask_orient_fit.nii') copy_header('tmp.anat_orient.nii', 'tmp.point_orient_fit.nii') # Reorient outputs into the initial orientation of the input image print '\nReorient the centerline into the initial orientation of the input image...' set_orientation('tmp.point_orient_fit.nii', input_image_orientation, 'tmp.point_orient_fit.nii') set_orientation('tmp.mask_orient_fit.nii', input_image_orientation, 'tmp.mask_orient_fit.nii') # Generate output file (in current folder) print '\nGenerate output file (in current folder)...' os.chdir('..') # come back to parent folder #sct.generate_output_file('tmp.centerline_polycoeffs_x.txt','./','centerline_polycoeffs_x','.txt') #sct.generate_output_file('tmp.centerline_polycoeffs_y.txt','./','centerline_polycoeffs_y','.txt') #sct.generate_output_file('tmp.centerline_coordinates.txt','./','centerline_coordinates','.txt') #sct.generate_output_file('tmp.anat_orient.nii','./',file_anat+'_rpi',ext_anat) #sct.generate_output_file('tmp.anat_orient_fit.nii', file_anat+'_rpi_align'+ext_anat) #sct.generate_output_file('tmp.mask_orient_fit.nii', file_anat+'_mask'+ext_anat) fname_output_centerline = sct.generate_output_file(path_tmp+'/tmp.point_orient_fit.nii', file_anat+'_centerline'+ext_anat) # Delete temporary files if remove_tmp_files == 1: print '\nRemove temporary files...' sct.run('rm -rf '+path_tmp) # print number of warnings print '\nNumber of warnings: '+str(warning_count)+' (if >10, you should probably reduce the gap and/or increase the kernel size' # display elapsed time elapsed_time = time.time() - start_time print '\nFinished! \n\tGenerated file: '+fname_output_centerline+'\n\tElapsed time: '+str(int(round(elapsed_time)))+'s\n'
def main(): # Initialization fname_anat = '' fname_centerline = '' centerline_fitting = 'polynome' remove_temp_files = param.remove_temp_files interp = param.interp degree_poly = param.deg_poly # extract path of the script path_script = os.path.dirname(__file__) + '/' # Parameters for debug mode if param.debug == 1: print '\n*** WARNING: DEBUG MODE ON ***\n' status, path_sct_data = commands.getstatusoutput( 'echo $SCT_TESTING_DATA_DIR') fname_anat = path_sct_data + '/t2/t2.nii.gz' fname_centerline = path_sct_data + '/t2/t2_seg.nii.gz' else: # Check input param try: opts, args = getopt.getopt(sys.argv[1:], 'hi:c:r:d:f:s:') except getopt.GetoptError as err: print str(err) usage() if not opts: usage() for opt, arg in opts: if opt == '-h': usage() elif opt in ('-i'): fname_anat = arg elif opt in ('-c'): fname_centerline = arg elif opt in ('-r'): remove_temp_files = int(arg) elif opt in ('-d'): degree_poly = int(arg) elif opt in ('-f'): centerline_fitting = str(arg) elif opt in ('-s'): interp = str(arg) # display usage if a mandatory argument is not provided if fname_anat == '' or fname_centerline == '': usage() # check existence of input files sct.check_file_exist(fname_anat) sct.check_file_exist(fname_centerline) # extract path/file/extension path_anat, file_anat, ext_anat = sct.extract_fname(fname_anat) # Display arguments print '\nCheck input arguments...' print ' Input volume ...................... ' + fname_anat print ' Centerline ........................ ' + fname_centerline print '' # Get input image orientation input_image_orientation = get_orientation(fname_anat) # Reorient input data into RL PA IS orientation set_orientation(fname_anat, 'RPI', 'tmp.anat_orient.nii') set_orientation(fname_centerline, 'RPI', 'tmp.centerline_orient.nii') # Open centerline #========================================================================================== print '\nGet dimensions of input centerline...' nx, ny, nz, nt, px, py, pz, pt = Image('tmp.centerline_orient.nii').dim print '.. matrix size: ' + str(nx) + ' x ' + str(ny) + ' x ' + str(nz) print '.. voxel size: ' + str(px) + 'mm x ' + str(py) + 'mm x ' + str( pz) + 'mm' print '\nOpen centerline volume...' file = nibabel.load('tmp.centerline_orient.nii') data = file.get_data() X, Y, Z = (data > 0).nonzero() min_z_index, max_z_index = min(Z), max(Z) # loop across z and associate x,y coordinate with the point having maximum intensity x_centerline = [0 for iz in range(min_z_index, max_z_index + 1, 1)] y_centerline = [0 for iz in range(min_z_index, max_z_index + 1, 1)] z_centerline = [iz for iz in range(min_z_index, max_z_index + 1, 1)] # Two possible scenario: # 1. the centerline is probabilistic: each slices contains voxels with the probability of containing the centerline [0:...:1] # We only take the maximum value of the image to aproximate the centerline. # 2. The centerline/segmentation image contains many pixels per slice with values {0,1}. # We take all the points and approximate the centerline on all these points. X, Y, Z = ((data < 1) * (data > 0)).nonzero() # X is empty if binary image if (len(X) > 0): # Scenario 1 for iz in range(min_z_index, max_z_index + 1, 1): x_centerline[iz - min_z_index], y_centerline[ iz - min_z_index] = numpy.unravel_index( data[:, :, iz].argmax(), data[:, :, iz].shape) else: # Scenario 2 for iz in range(min_z_index, max_z_index + 1, 1): x_seg, y_seg = (data[:, :, iz] > 0).nonzero() if len(x_seg) > 0: x_centerline[iz - min_z_index] = numpy.mean(x_seg) y_centerline[iz - min_z_index] = numpy.mean(y_seg) # TODO: find a way to do the previous loop with this, which is more neat: # [numpy.unravel_index(data[:,:,iz].argmax(), data[:,:,iz].shape) for iz in range(0,nz,1)] # clear variable del data # Fit the centerline points with the kind of curve given as argument of the script and return the new smoothed coordinates if centerline_fitting == 'splines': try: x_centerline_fit, y_centerline_fit = b_spline_centerline( x_centerline, y_centerline, z_centerline) except ValueError: print "splines fitting doesn't work, trying with polynomial fitting...\n" x_centerline_fit, y_centerline_fit = polynome_centerline( x_centerline, y_centerline, z_centerline) elif centerline_fitting == 'polynome': x_centerline_fit, y_centerline_fit = polynome_centerline( x_centerline, y_centerline, z_centerline) #========================================================================================== # Split input volume print '\nSplit input volume...' from sct_split_data import split_data if not split_data('tmp.anat_orient.nii', 2, '_z'): sct.printv('ERROR in split_data.', 1, 'error') file_anat_split = [ 'tmp.anat_orient_z' + str(z).zfill(4) for z in range(0, nz, 1) ] # initialize variables file_mat_inv_cumul = [ 'tmp.mat_inv_cumul_z' + str(z).zfill(4) for z in range(0, nz, 1) ] z_init = min_z_index displacement_max_z_index = x_centerline_fit[ z_init - min_z_index] - x_centerline_fit[max_z_index - min_z_index] # write centerline as text file print '\nGenerate fitted transformation matrices...' file_mat_inv_cumul_fit = [ 'tmp.mat_inv_cumul_fit_z' + str(z).zfill(4) for z in range(0, nz, 1) ] for iz in range(min_z_index, max_z_index + 1, 1): # compute inverse cumulative fitted transformation matrix fid = open(file_mat_inv_cumul_fit[iz], 'w') if (x_centerline[iz - min_z_index] == 0 and y_centerline[iz - min_z_index] == 0): displacement = 0 else: displacement = x_centerline_fit[ z_init - min_z_index] - x_centerline_fit[iz - min_z_index] fid.write('%i %i %i %f\n' % (1, 0, 0, displacement)) fid.write('%i %i %i %f\n' % (0, 1, 0, 0)) fid.write('%i %i %i %i\n' % (0, 0, 1, 0)) fid.write('%i %i %i %i\n' % (0, 0, 0, 1)) fid.close() # we complete the displacement matrix in z direction for iz in range(0, min_z_index, 1): fid = open(file_mat_inv_cumul_fit[iz], 'w') fid.write('%i %i %i %f\n' % (1, 0, 0, 0)) fid.write('%i %i %i %f\n' % (0, 1, 0, 0)) fid.write('%i %i %i %i\n' % (0, 0, 1, 0)) fid.write('%i %i %i %i\n' % (0, 0, 0, 1)) fid.close() for iz in range(max_z_index + 1, nz, 1): fid = open(file_mat_inv_cumul_fit[iz], 'w') fid.write('%i %i %i %f\n' % (1, 0, 0, displacement_max_z_index)) fid.write('%i %i %i %f\n' % (0, 1, 0, 0)) fid.write('%i %i %i %i\n' % (0, 0, 1, 0)) fid.write('%i %i %i %i\n' % (0, 0, 0, 1)) fid.close() # apply transformations to data print '\nApply fitted transformation matrices...' file_anat_split_fit = [ 'tmp.anat_orient_fit_z' + str(z).zfill(4) for z in range(0, nz, 1) ] for iz in range(0, nz, 1): # forward cumulative transformation to data sct.run(fsloutput + 'flirt -in ' + file_anat_split[iz] + ' -ref ' + file_anat_split[iz] + ' -applyxfm -init ' + file_mat_inv_cumul_fit[iz] + ' -out ' + file_anat_split_fit[iz] + ' -interp ' + interp) # Merge into 4D volume print '\nMerge into 4D volume...' from sct_concat_data import concat_data from glob import glob concat_data(glob('tmp.anat_orient_fit_z*.nii'), 'tmp.anat_orient_fit.nii', dim=2) # sct.run(fsloutput+'fslmerge -z tmp.anat_orient_fit tmp.anat_orient_fit_z*') # Reorient data as it was before print '\nReorient data back into native orientation...' set_orientation('tmp.anat_orient_fit.nii', input_image_orientation, 'tmp.anat_orient_fit_reorient.nii') # Generate output file (in current folder) print '\nGenerate output file (in current folder)...' sct.generate_output_file('tmp.anat_orient_fit_reorient.nii', file_anat + '_flatten' + ext_anat) # Delete temporary files if remove_temp_files == 1: print '\nDelete temporary files...' sct.run('rm -rf tmp.*') # to view results print '\nDone! To view results, type:' print 'fslview ' + file_anat + ext_anat + ' ' + file_anat + '_flatten' + ext_anat + ' &\n'
output_file = arguments["-o"] reference_image = arguments["-d"] warping_fields_filename = arguments["-w"] number_of_frames = arguments["-n"] warping_fields = [WarpingField(filename) for filename in warping_fields_filename] filenames_output = [] while True: try: warping_fields[0].num_of_frames = number_of_frames image_output_iter, iteration = warping_fields[0].next() image_output_iter.save() filename_warp = image_output_iter.path + image_output_iter.file_name + image_output_iter.ext filename_output = "tmp.warped_image_" + str(iteration - 1) + image_output_iter.ext run("sct_apply_transfo -i " + input_file + " -d " + reference_image + " -w " + filename_warp + " -o " + filename_output) filenames_output.append(filename_output) except ValueError: printv('\nError during warping field generation...', 1, 'error') except StopIteration: printv('\nFinished iterations.') break # run("fslmerge -t " + output_file + " " + " ".join(filenames_output)) from sct_concat_data import concat_data concat_data(','.join(filenames_output), output_file, dim=3) run("rm -rf tmp.*") printv('fslview ' + output_file + " &", 1, 'info')
def main(): # Initialization fname_anat = '' fname_centerline = '' centerline_fitting = 'polynome' remove_temp_files = param.remove_temp_files interp = param.interp degree_poly = param.deg_poly # extract path of the script path_script = os.path.dirname(__file__)+'/' # Parameters for debug mode if param.debug == 1: print '\n*** WARNING: DEBUG MODE ON ***\n' status, path_sct_data = commands.getstatusoutput('echo $SCT_TESTING_DATA_DIR') fname_anat = path_sct_data+'/t2/t2.nii.gz' fname_centerline = path_sct_data+'/t2/t2_seg.nii.gz' else: # Check input param try: opts, args = getopt.getopt(sys.argv[1:],'hi:c:r:d:f:s:') except getopt.GetoptError as err: print str(err) usage() if not opts: usage() for opt, arg in opts: if opt == '-h': usage() elif opt in ('-i'): fname_anat = arg elif opt in ('-c'): fname_centerline = arg elif opt in ('-r'): remove_temp_files = int(arg) elif opt in ('-d'): degree_poly = int(arg) elif opt in ('-f'): centerline_fitting = str(arg) elif opt in ('-s'): interp = str(arg) # display usage if a mandatory argument is not provided if fname_anat == '' or fname_centerline == '': usage() # check existence of input files sct.check_file_exist(fname_anat) sct.check_file_exist(fname_centerline) # extract path/file/extension path_anat, file_anat, ext_anat = sct.extract_fname(fname_anat) # Display arguments print '\nCheck input arguments...' print ' Input volume ...................... '+fname_anat print ' Centerline ........................ '+fname_centerline print '' # Get input image orientation input_image_orientation = get_orientation(fname_anat) # Reorient input data into RL PA IS orientation set_orientation(fname_anat, 'RPI', 'tmp.anat_orient.nii') set_orientation(fname_centerline, 'RPI', 'tmp.centerline_orient.nii') # Open centerline #========================================================================================== print '\nGet dimensions of input centerline...' nx, ny, nz, nt, px, py, pz, pt = Image('tmp.centerline_orient.nii').dim print '.. matrix size: '+str(nx)+' x '+str(ny)+' x '+str(nz) print '.. voxel size: '+str(px)+'mm x '+str(py)+'mm x '+str(pz)+'mm' print '\nOpen centerline volume...' file = nibabel.load('tmp.centerline_orient.nii') data = file.get_data() X, Y, Z = (data>0).nonzero() min_z_index, max_z_index = min(Z), max(Z) # loop across z and associate x,y coordinate with the point having maximum intensity x_centerline = [0 for iz in range(min_z_index, max_z_index+1, 1)] y_centerline = [0 for iz in range(min_z_index, max_z_index+1, 1)] z_centerline = [iz for iz in range(min_z_index, max_z_index+1, 1)] # Two possible scenario: # 1. the centerline is probabilistic: each slices contains voxels with the probability of containing the centerline [0:...:1] # We only take the maximum value of the image to aproximate the centerline. # 2. The centerline/segmentation image contains many pixels per slice with values {0,1}. # We take all the points and approximate the centerline on all these points. X, Y, Z = ((data<1)*(data>0)).nonzero() # X is empty if binary image if (len(X) > 0): # Scenario 1 for iz in range(min_z_index, max_z_index+1, 1): x_centerline[iz-min_z_index], y_centerline[iz-min_z_index] = numpy.unravel_index(data[:,:,iz].argmax(), data[:,:,iz].shape) else: # Scenario 2 for iz in range(min_z_index, max_z_index+1, 1): x_seg, y_seg = (data[:,:,iz]>0).nonzero() if len(x_seg) > 0: x_centerline[iz-min_z_index] = numpy.mean(x_seg) y_centerline[iz-min_z_index] = numpy.mean(y_seg) # TODO: find a way to do the previous loop with this, which is more neat: # [numpy.unravel_index(data[:,:,iz].argmax(), data[:,:,iz].shape) for iz in range(0,nz,1)] # clear variable del data # Fit the centerline points with the kind of curve given as argument of the script and return the new smoothed coordinates if centerline_fitting == 'splines': try: x_centerline_fit, y_centerline_fit = b_spline_centerline(x_centerline,y_centerline,z_centerline) except ValueError: print "splines fitting doesn't work, trying with polynomial fitting...\n" x_centerline_fit, y_centerline_fit = polynome_centerline(x_centerline,y_centerline,z_centerline) elif centerline_fitting == 'polynome': x_centerline_fit, y_centerline_fit = polynome_centerline(x_centerline,y_centerline,z_centerline) #========================================================================================== # Split input volume print '\nSplit input volume...' from sct_split_data import split_data if not split_data('tmp.anat_orient.nii', 2, '_z'): sct.printv('ERROR in split_data.', 1, 'error') file_anat_split = ['tmp.anat_orient_z'+str(z).zfill(4) for z in range(0, nz, 1)] # initialize variables file_mat_inv_cumul = ['tmp.mat_inv_cumul_z'+str(z).zfill(4) for z in range(0,nz,1)] z_init = min_z_index displacement_max_z_index = x_centerline_fit[z_init-min_z_index]-x_centerline_fit[max_z_index-min_z_index] # write centerline as text file print '\nGenerate fitted transformation matrices...' file_mat_inv_cumul_fit = ['tmp.mat_inv_cumul_fit_z'+str(z).zfill(4) for z in range(0,nz,1)] for iz in range(min_z_index, max_z_index+1, 1): # compute inverse cumulative fitted transformation matrix fid = open(file_mat_inv_cumul_fit[iz], 'w') if (x_centerline[iz-min_z_index] == 0 and y_centerline[iz-min_z_index] == 0): displacement = 0 else: displacement = x_centerline_fit[z_init-min_z_index]-x_centerline_fit[iz-min_z_index] fid.write('%i %i %i %f\n' %(1, 0, 0, displacement) ) fid.write('%i %i %i %f\n' %(0, 1, 0, 0) ) fid.write('%i %i %i %i\n' %(0, 0, 1, 0) ) fid.write('%i %i %i %i\n' %(0, 0, 0, 1) ) fid.close() # we complete the displacement matrix in z direction for iz in range(0, min_z_index, 1): fid = open(file_mat_inv_cumul_fit[iz], 'w') fid.write('%i %i %i %f\n' %(1, 0, 0, 0) ) fid.write('%i %i %i %f\n' %(0, 1, 0, 0) ) fid.write('%i %i %i %i\n' %(0, 0, 1, 0) ) fid.write('%i %i %i %i\n' %(0, 0, 0, 1) ) fid.close() for iz in range(max_z_index+1, nz, 1): fid = open(file_mat_inv_cumul_fit[iz], 'w') fid.write('%i %i %i %f\n' %(1, 0, 0, displacement_max_z_index) ) fid.write('%i %i %i %f\n' %(0, 1, 0, 0) ) fid.write('%i %i %i %i\n' %(0, 0, 1, 0) ) fid.write('%i %i %i %i\n' %(0, 0, 0, 1) ) fid.close() # apply transformations to data print '\nApply fitted transformation matrices...' file_anat_split_fit = ['tmp.anat_orient_fit_z'+str(z).zfill(4) for z in range(0,nz,1)] for iz in range(0, nz, 1): # forward cumulative transformation to data sct.run(fsloutput+'flirt -in '+file_anat_split[iz]+' -ref '+file_anat_split[iz]+' -applyxfm -init '+file_mat_inv_cumul_fit[iz]+' -out '+file_anat_split_fit[iz]+' -interp '+interp) # Merge into 4D volume print '\nMerge into 4D volume...' from sct_concat_data import concat_data from glob import glob concat_data(glob('tmp.anat_orient_fit_z*.nii'), 'tmp.anat_orient_fit.nii', dim=2) # sct.run(fsloutput+'fslmerge -z tmp.anat_orient_fit tmp.anat_orient_fit_z*') # Reorient data as it was before print '\nReorient data back into native orientation...' set_orientation('tmp.anat_orient_fit.nii', input_image_orientation, 'tmp.anat_orient_fit_reorient.nii') # Generate output file (in current folder) print '\nGenerate output file (in current folder)...' sct.generate_output_file('tmp.anat_orient_fit_reorient.nii', file_anat+'_flatten'+ext_anat) # Delete temporary files if remove_temp_files == 1: print '\nDelete temporary files...' sct.run('rm -rf tmp.*') # to view results print '\nDone! To view results, type:' print 'fslview '+file_anat+ext_anat+' '+file_anat+'_flatten'+ext_anat+' &\n'
def main(args = None): orientation = '' change_header = '' fname_out = '' if not args: args = sys.argv[1:] # Building the command, do sanity checks parser = get_parser() arguments = parser.parse(sys.argv[1:]) fname_in = arguments['-i'] if '-o' in arguments: fname_out = arguments['-o'] if '-s' in arguments: orientation = arguments['-s'] if '-a' in arguments: change_header = arguments['-a'] remove_tmp_files = int(arguments['-r']) verbose = int(arguments['-v']) inversion = False # change orientation # create temporary folder sct.printv('\nCreate temporary folder...', verbose) path_tmp = 'tmp.'+time.strftime("%y%m%d%H%M%S/") status, output = sct.run('mkdir '+path_tmp, verbose) # copy file in temp folder sct.printv('\nCopy files to tmp folder...', verbose) convert(fname_in, path_tmp+'data.nii') # go to temp folder os.chdir(path_tmp) # Get dimensions of data sct.printv('\nGet dimensions of data...', verbose) nx, ny, nz, nt, px, py, pz, pt = Image('data.nii').dim sct.printv(str(nx) + ' x ' + str(ny) + ' x ' + str(nz)+ ' x ' + str(nt), verbose) # if data are 3d, directly set or get orientation if nt == 1: if orientation != '': # set orientation sct.printv('\nChange orientation...', verbose) if change_header == '': set_orientation('data.nii', orientation, 'data_orient.nii') else: set_orientation('data.nii', change_header, 'data_orient.nii', True) else: # get orientation sct.printv('\nGet orientation...', verbose) print get_orientation('data.nii') else: # split along T dimension sct.printv('\nSplit along T dimension...', verbose) from sct_split_data import split_data split_data('data.nii', 3, '_T') if orientation != '': # set orientation sct.printv('\nChange orientation...', verbose) for it in range(nt): file_data_split = 'data_T'+str(it).zfill(4)+'.nii' file_data_split_orient = 'data_orient_T'+str(it).zfill(4)+'.nii' set_orientation(file_data_split, orientation, file_data_split_orient) # Merge files back sct.printv('\nMerge file back...', verbose) from sct_concat_data import concat_data from glob import glob concat_data(glob('data_orient_T*.nii'), 'data_orient.nii', dim=3) else: sct.printv('\nGet orientation...', verbose) print get_orientation('data_T0000.nii') # come back to parent folder os.chdir('..') # Generate output files if orientation != '': # Build fname_out if fname_out == '': path_data, file_data, ext_data = sct.extract_fname(fname_in) fname_out = path_data+file_data+'_'+orientation+ext_data sct.printv('\nGenerate output files...', verbose) sct.generate_output_file(path_tmp+'data_orient.nii', fname_out) # Remove temporary files if remove_tmp_files == 1: sct.printv('\nRemove temporary files...', verbose) sct.run('rm -rf '+path_tmp, verbose)
def resample(): fsloutput = 'export FSLOUTPUTTYPE=NIFTI; ' # for faster processing, all outputs are in NIFTI ext = '.nii' # display usage if a mandatory argument is not provided if param.fname_data == '' or param.factor == '': sct.printv('\nERROR: All mandatory arguments are not provided. See usage (add -h).\n', 1, 'error') # check existence of input files sct.printv('\nCheck existence of input files...', param.verbose) sct.check_file_exist(param.fname_data, param.verbose) # extract resampling factor sct.printv('\nParse resampling factor...', param.verbose) factor_split = param.factor.split('x') factor = [float(factor_split[i]) for i in range(len(factor_split))] # check if it has three values if not len(factor) == 3: sct.printv('\nERROR: factor should have three dimensions. E.g., 2x2x1.\n', 1, 'error') else: fx, fy, fz = [float(factor_split[i]) for i in range(len(factor_split))] # check interpolation if param.interpolation not in ['NearestNeighbor','Linear','Cubic','Sinc','Gaussian']: sct.printv('\nERROR: interpolation should be one of those:NearestNeighbor|Linear|Cubic|Sinc|Gaussian.\n', 1, 'error') # display input parameters sct.printv('\nInput parameters:', param.verbose) sct.printv(' data ..................'+param.fname_data, param.verbose) sct.printv(' resampling factor .....'+param.factor, param.verbose) # Extract path/file/extension path_data, file_data, ext_data = sct.extract_fname(param.fname_data) path_out, file_out, ext_out = '', file_data, ext_data # create temporary folder sct.printv('\nCreate temporary folder...', param.verbose) path_tmp = sct.slash_at_the_end('tmp.'+time.strftime("%y%m%d%H%M%S"), 1) sct.run('mkdir '+path_tmp, param.verbose) # Copying input data to tmp folder and convert to nii # NB: cannot use c3d here because c3d cannot convert 4D data. sct.printv('\nCopying input data to tmp folder and convert to nii...', param.verbose) sct.run('cp '+param.fname_data+' '+path_tmp+'data'+ext_data, param.verbose) # go to tmp folder os.chdir(path_tmp) # convert to nii format convert('data'+ext_data, 'data.nii') # Get dimensions of data sct.printv('\nGet dimensions of data...', param.verbose) nx, ny, nz, nt, px, py, pz, pt = Image('data.nii').dim sct.printv(' ' + str(nx) + ' x ' + str(ny) + ' x ' + str(nz)+ ' x ' + str(nt), param.verbose) dim = 4 # by default, will be adjusted later if nt == 1: dim = 3 if nz == 1: dim = 2 sct.run('ERROR (sct_resample): Dimension of input data is different from 3 or 4. Exit program', param.verbose, 'error') # Calculate new dimensions sct.printv('\nCalculate new dimensions...', param.verbose) nx_new = int(round(nx*fx)) ny_new = int(round(ny*fy)) nz_new = int(round(nz*fz)) sct.printv(' ' + str(nx_new) + ' x ' + str(ny_new) + ' x ' + str(nz_new)+ ' x ' + str(nt), param.verbose) # if dim=4, split data if dim == 4: # Split into T dimension sct.printv('\nSplit along T dimension...', param.verbose) from sct_split_data import split_data split_data('data.nii', 3, '_T') elif dim == 3: # rename file to have compatible code with 4d status, output = sct.run('cp data.nii data_T0000.nii', param.verbose) for it in range(nt): # identify current volume file_data_splitT = 'data_T'+str(it).zfill(4) file_data_splitT_resample = file_data_splitT+'r' # resample volume sct.printv(('\nResample volume '+str((it+1))+'/'+str(nt)+':'), param.verbose) sct.run('isct_c3d '+file_data_splitT+ext+' -interpolation '+param.interpolation+' -resample '+str(nx_new)+'x'+str(ny_new)+'x'+str(nz_new)+'vox -o '+file_data_splitT_resample+ext) # pad data (for ANTs) # # TODO: check if need to pad also for the estimate_and_apply # if program == 'ants' and todo == 'estimate' and slicewise == 0: # sct.run('isct_c3d '+file_data_splitT_num[it]+' -pad 0x0x3vox 0x0x3vox 0 -o '+file_data_splitT_num[it]+'_pad.nii') # file_data_splitT_num[it] = file_data_splitT_num[it]+'_pad' # merge data back along T file_data_resample = file_data+param.file_suffix sct.printv('\nMerge data back along T...', param.verbose) from sct_concat_data import concat_data import glob concat_data(glob.glob('data_T*r.nii'), file_data_resample, dim=3) # come back to parent folder os.chdir('..') # Generate output files sct.printv('\nGenerate output files...', param.verbose) if not param.fname_out: param.fname_out = path_out+file_out+param.file_suffix+ext_out sct.generate_output_file(path_tmp+file_data_resample+ext, param.fname_out) # Remove temporary files if param.remove_tmp_files == 1: print('\nRemove temporary files...') sct.run('rm -rf '+path_tmp, param.verbose) # to view results sct.printv('\nDone! To view results, type:', param.verbose) sct.printv('fslview '+param.fname_out+' &', param.verbose, 'info') print
def apply(self): # Initialization fname_src = self.input_filename # source image (moving) fname_warp_list = self.warp_input # list of warping fields fname_out = self.output_filename # output fname_dest = self.fname_dest # destination image (fix) verbose = self.verbose remove_temp_files = self.remove_temp_files crop_reference = self.crop # if = 1, put 0 everywhere around warping field, if = 2, real crop interp = sct.get_interpolation('isct_antsApplyTransforms', self.interp) # Parse list of warping fields sct.printv('\nParse list of warping fields...', verbose) use_inverse = [] fname_warp_list_invert = [] # fname_warp_list = fname_warp_list.replace(' ', '') # remove spaces # fname_warp_list = fname_warp_list.split(",") # parse with comma for i in range(len(fname_warp_list)): # Check if inverse matrix is specified with '-' at the beginning of file name if fname_warp_list[i].find('-') == 0: use_inverse.append('-i ') fname_warp_list[i] = fname_warp_list[i][1:] # remove '-' else: use_inverse.append('') sct.printv(' Transfo #'+str(i)+': '+use_inverse[i]+fname_warp_list[i], verbose) fname_warp_list_invert.append(use_inverse[i]+fname_warp_list[i]) # need to check if last warping field is an affine transfo isLastAffine = False path_fname, file_fname, ext_fname = sct.extract_fname(fname_warp_list_invert[-1]) if ext_fname in ['.txt', '.mat']: isLastAffine = True # Check file existence sct.printv('\nCheck file existence...', verbose) sct.check_file_exist(fname_src, self.verbose) sct.check_file_exist(fname_dest, self.verbose) for i in range(len(fname_warp_list)): # check if file exist sct.check_file_exist(fname_warp_list[i], self.verbose) # check if destination file is 3d if not sct.check_if_3d(fname_dest): sct.printv('ERROR: Destination data must be 3d') # N.B. Here we take the inverse of the warp list, because sct_WarpImageMultiTransform concatenates in the reverse order fname_warp_list_invert.reverse() # Extract path, file and extension path_src, file_src, ext_src = sct.extract_fname(fname_src) path_dest, file_dest, ext_dest = sct.extract_fname(fname_dest) # Get output folder and file name if fname_out == '': path_out = '' # output in user's current directory file_out = file_src+'_reg' ext_out = ext_src fname_out = path_out+file_out+ext_out # Get dimensions of data sct.printv('\nGet dimensions of data...', verbose) from msct_image import Image nx, ny, nz, nt, px, py, pz, pt = Image(fname_src).dim # nx, ny, nz, nt, px, py, pz, pt = sct.get_dimension(fname_src) sct.printv(' ' + str(nx) + ' x ' + str(ny) + ' x ' + str(nz)+ ' x ' + str(nt), verbose) # if 3d if nt == 1: # Apply transformation sct.printv('\nApply transformation...', verbose) sct.run('isct_antsApplyTransforms -d 3 -i '+fname_src+' -o '+fname_out+' -t '+' '.join(fname_warp_list_invert)+' -r '+fname_dest+interp, verbose) # if 4d, loop across the T dimension else: # create temporary folder sct.printv('\nCreate temporary folder...', verbose) path_tmp = sct.slash_at_the_end('tmp.'+time.strftime("%y%m%d%H%M%S"), 1) # sct.run('mkdir '+path_tmp, verbose) sct.run('mkdir '+path_tmp, verbose) # convert to nifti into temp folder sct.printv('\nCopying input data to tmp folder and convert to nii...', verbose) from sct_convert import convert convert(fname_src, path_tmp+'data.nii') # split along T dimension sct.printv('\nSplit along T dimension...', verbose) from sct_split_data import split_data if not split_data(path_tmp+'data.nii', 3, '_T'): sct.printv('ERROR in split_data.', 1, 'error') # apply transfo sct.printv('\nApply transformation to each 3D volume...', verbose) for it in range(nt): file_data_split = path_tmp+'data_T'+str(it).zfill(4)+'.nii' file_data_split_reg = path_tmp+'data_reg_T'+str(it).zfill(4)+'.nii' sct.run('isct_antsApplyTransforms -d 3 -i '+file_data_split+' -o '+file_data_split_reg+' -t '+' '.join(fname_warp_list_invert)+' -r '+fname_dest+interp, verbose) # Merge files back sct.printv('\nMerge file back...', verbose) from sct_concat_data import concat_data import glob concat_data(glob.glob(path_tmp+'data_reg_T*.nii'), fname_out, dim=3) # Delete temporary folder if specified if int(remove_temp_files): sct.printv('\nRemove temporary files...', verbose) sct.run('rm -rf '+path_tmp, verbose) # 2. crop the resulting image using dimensions from the warping field warping_field = fname_warp_list_invert[-1] # if last warping field is an affine transfo, we need to compute the space of the concatenate warping field: if isLastAffine: sct.printv('WARNING: the resulting image could have wrong apparent results. You should use an affine transformation as last transformation...',verbose,'warning') elif crop_reference == 1: ImageCropper(input_file=fname_out, output_file=fname_out, ref=warping_field, background=0).crop() # sct.run('sct_crop_image -i '+fname_out+' -o '+fname_out+' -ref '+warping_field+' -b 0') elif crop_reference == 2: ImageCropper(input_file=fname_out, output_file=fname_out, ref=warping_field).crop() # sct.run('sct_crop_image -i '+fname_out+' -o '+fname_out+' -ref '+warping_field) # display elapsed time sct.printv('\nDone! To view results, type:', verbose) sct.printv('fslview '+fname_dest+' '+fname_out+' &\n', verbose, 'info')