def main(): # Initialization fname_output = '' fname_mask = param.fname_mask fname_src_seg = '' fsloutput = 'export FSLOUTPUTTYPE=NIFTI; ' # for faster processing, all outputs are in NIFTI' start_time = time.time() # get path of the toolbox status, path_sct = commands.getstatusoutput('echo $SCT_DIR') # get default registration parameters # step1 = Paramreg(step='1', type='im', algo='syn', metric='MI', iter='5', shrink='1', smooth='0', gradStep='0.5') step0 = Paramreg(step='0', type='im', algo='syn', metric='MI', iter='0', shrink='1', smooth='0', gradStep='0.5') # only used to put src into dest space step1 = Paramreg() paramreg = ParamregMultiStep([step0, step1]) # Initialize the parser parser = Parser(__file__) parser.usage.set_description( 'This program co-registers two 3D volumes. The deformation is non-rigid and is ' 'constrained along Z direction (i.e., axial plane). Hence, this function assumes ' 'that orientation of the destination image is axial (RPI). If you need to register ' 'two volumes with large deformations and/or different contrasts, it is recommended to ' 'input spinal cord segmentations (binary mask) in order to achieve maximum robustness.' ' The program outputs a warping field that can be used to register other images to the' ' destination image. To apply the warping field to another image, use ' 'sct_apply_transfo') parser.add_option(name="-i", type_value="file", description="Image source.", mandatory=True, example="src.nii.gz") parser.add_option(name="-d", type_value="file", description="Image destination.", mandatory=True, example="dest.nii.gz") parser.add_option(name="-iseg", type_value="file", description="Segmentation source.", mandatory=False, example="src_seg.nii.gz") parser.add_option(name="-dseg", type_value="file", description="Segmentation destination.", mandatory=False, example="dest_seg.nii.gz") parser.add_option( name="-m", type_value="file", description= "Mask that can be created with sct_create_mask to improve accuracy over region of interest. " "This mask will be used on the destination image.", mandatory=False, example="mask.nii.gz") parser.add_option(name="-o", type_value="file_output", description="Name of output file.", mandatory=False, example="src_reg.nii.gz") parser.add_option( name="-p", type_value=[[':'], 'str'], description= """Parameters for registration. Separate arguments with ",". Separate steps with ":".\nstep: <int> Step number (starts at 1).\ntype: {im,seg} type of data used for registration.\nalgo: Default=""" + paramreg.steps['1'].algo + """\n global registration: {rigid, affine, syn, bsplinesyn}\n Slice By Slice registration: {slicereg: regularized translations (see: goo.gl/Sj3ZeU), slicereg2d_translation: regularized using moving average (Hanning window), slicereg2d_rigid, slicereg2d_affine, slicereg2d_pointwise: registration based on the Center of Mass of each slice (use only with type:Seg. Designed for centerlines), slicereg2d_bsplinesyn, slicereg2d_syn}\nmetric: {CC,MI,MeanSquares}. Default=""" + paramreg.steps['1'].metric + """\niter: <int> Number of iterations. Default=""" + paramreg.steps['1'].iter + """\nshrink: <int> Shrink factor (only for SyN). Default=""" + paramreg.steps['1'].shrink + """\nsmooth: <int> Smooth factor (only for SyN). Default=""" + paramreg.steps['1'].smooth + """\ngradStep: <float> Gradient step. Default=""" + paramreg.steps['1'].gradStep + """\npoly: <int> Polynomial degree (only for slicereg). Default=""" + paramreg.steps['1'].poly + """\nwindow_length: <int> size of hanning window for smoothing along z for slicereg2d_pointwise, slicereg2d_translation, slicereg2d_rigid, slicereg2d_affine, slicereg2d_syn and slicereg2d_bsplinesyn.. Default=""" + paramreg.steps['1'].window_length, mandatory=False, example= "step=1,type=seg,algo=slicereg,metric=MeanSquares:step=2,type=im,algo=syn,metric=MI,iter=5,shrink=2" ) parser.add_option( name="-z", type_value="int", description= """size of z-padding to enable deformation at edges when using SyN.""", mandatory=False, default_value=param.padding) parser.add_option(name="-x", type_value="multiple_choice", description="""Final interpolation.""", mandatory=False, default_value='linear', example=['nn', 'linear', 'spline']) parser.add_option(name="-r", type_value="multiple_choice", description="""Remove temporary files.""", mandatory=False, default_value='1', example=['0', '1']) parser.add_option(name="-v", type_value="multiple_choice", description="""Verbose.""", mandatory=False, default_value='1', example=['0', '1', '2']) arguments = parser.parse(sys.argv[1:]) # get arguments fname_src = arguments['-i'] fname_dest = arguments['-d'] if '-iseg' in arguments: fname_src_seg = arguments['-iseg'] if '-dseg' in arguments: fname_dest_seg = arguments['-dseg'] if '-o' in arguments: fname_output = arguments['-o'] if "-m" in arguments: fname_mask = arguments['-m'] padding = arguments['-z'] if "-p" in arguments: paramreg_user = arguments['-p'] # update registration parameters for paramStep in paramreg_user: paramreg.addStep(paramStep) interp = arguments['-x'] remove_temp_files = int(arguments['-r']) verbose = int(arguments['-v']) # Parameters for debug mode if param.debug: print '\n*** WARNING: DEBUG MODE ON ***\n' status, path_sct_data = commands.getstatusoutput( 'echo $SCT_TESTING_DATA_DIR') fname_dest = path_sct_data + '/mt/mt1.nii.gz' fname_src = path_sct_data + '/t2/t2.nii.gz' param_user = '******' remove_temp_files = '0' verbose = 1 # print arguments print '\nInput parameters:' print ' Source .............. ' + fname_src print ' Destination ......... ' + fname_dest print ' Mask ................ ' + fname_mask print ' Output name ......... ' + fname_output # print ' Algorithm ........... '+paramreg.algo # print ' Number of iterations '+paramreg.iter # print ' Metric .............. '+paramreg.metric print ' Remove temp files ... ' + str(remove_temp_files) print ' Verbose ............. ' + str(verbose) # update param param.verbose = verbose param.padding = padding param.fname_mask = fname_mask param.remove_temp_files = remove_temp_files # Get if input is 3D sct.printv('\nCheck if input data are 3D...', verbose) sct.check_if_3d(fname_src) sct.check_if_3d(fname_dest) # check if destination data is RPI sct.printv('\nCheck if destination data is RPI...', verbose) sct.check_if_rpi(fname_dest) # 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) # define output folder and file name if fname_output == '': path_out = '' # output in user's current directory file_out = file_src + "_reg" ext_out = ext_src else: path_out, file_out, ext_out = sct.extract_fname(fname_output) # 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 files to temporary folder sct.printv('\nCopy files...', verbose) sct.run('isct_c3d ' + fname_src + ' -o ' + path_tmp + '/src.nii', verbose) sct.run('isct_c3d ' + fname_dest + ' -o ' + path_tmp + '/dest.nii', verbose) if fname_src_seg: sct.run( 'isct_c3d ' + fname_src_seg + ' -o ' + path_tmp + '/src_seg.nii', verbose) sct.run( 'isct_c3d ' + fname_dest_seg + ' -o ' + path_tmp + '/dest_seg.nii', verbose) if not fname_mask == '': sct.run('isct_c3d ' + fname_mask + ' -o ' + path_tmp + '/mask.nii.gz', verbose) # go to tmp folder os.chdir(path_tmp) # Put source into destination space using header (no estimation -- purely based on header) # TODO: use c3d? # TODO: Check if necessary to do that # TODO: use that as step=0 # sct.printv('\nPut source into destination space using header...', verbose) # sct.run('isct_antsRegistration -d 3 -t Translation[0] -m MI[dest_pad.nii,src.nii,1,16] -c 0 -f 1 -s 0 -o [regAffine,src_regAffine.nii] -n BSpline[3]', verbose) # if segmentation, also do it for seg # loop across registration steps warp_forward = [] warp_inverse = [] for i_step in range(0, len(paramreg.steps)): sct.printv( '\nEstimate transformation for step #' + str(i_step) + '...', param.verbose) # identify which is the src and dest if paramreg.steps[str(i_step)].type == 'im': src = 'src.nii' dest = 'dest.nii' interp_step = 'linear' elif paramreg.steps[str(i_step)].type == 'seg': src = 'src_seg.nii' dest = 'dest_seg.nii' interp_step = 'nn' else: sct.run('ERROR: Wrong image type.', 1, 'error') # if step>0, apply warp_forward_concat to the src image to be used if i_step > 0: sct.run( 'sct_apply_transfo -i ' + src + ' -d ' + dest + ' -w ' + ','.join(warp_forward) + ' -o ' + sct.add_suffix(src, '_reg') + ' -x ' + interp_step, verbose) src = sct.add_suffix(src, '_reg') # register src --> dest warp_forward_out, warp_inverse_out = register(src, dest, paramreg, param, str(i_step)) warp_forward.append(warp_forward_out) warp_inverse.append(warp_inverse_out) # Put warp_forward_0 at the end of the list warp_forward_0 = warp_forward.pop(0) warp_forward.append(warp_forward_0) # Concatenate transformations sct.printv('\nConcatenate transformations...', verbose) sct.run( 'sct_concat_transfo -w ' + ','.join(warp_forward) + ' -d dest.nii -o warp_src2dest.nii.gz', verbose) warp_inverse.reverse() sct.run( 'sct_concat_transfo -w ' + ','.join(warp_inverse) + ' -d dest.nii -o warp_dest2src.nii.gz', verbose) # Apply warping field to src data sct.printv('\nApply transfo source --> dest...', verbose) sct.run( 'sct_apply_transfo -i src.nii -o src_reg.nii -d dest.nii -w warp_src2dest.nii.gz -x ' + interp, verbose) sct.printv('\nApply transfo dest --> source...', verbose) sct.run( 'sct_apply_transfo -i dest.nii -o dest_reg.nii -d src.nii -w warp_dest2src.nii.gz -x ' + interp, verbose) # come back to parent folder os.chdir('..') # Generate output files sct.printv('\nGenerate output files...', verbose) fname_src2dest = sct.generate_output_file(path_tmp + '/src_reg.nii', path_out + file_out + ext_out, verbose) sct.generate_output_file( path_tmp + '/warp_src2dest.nii.gz', path_out + 'warp_' + file_src + '2' + file_dest + '.nii.gz', verbose) fname_dest2src = sct.generate_output_file( path_tmp + '/dest_reg.nii', path_out + file_dest + '_reg' + ext_dest, verbose) sct.generate_output_file( path_tmp + '/warp_dest2src.nii.gz', path_out + 'warp_' + file_dest + '2' + file_src + '.nii.gz', verbose) # sct.generate_output_file(path_tmp+'/warp_dest2src.nii.gz', path_out+'warp_dest2src.nii.gz') # Delete temporary files if remove_temp_files: sct.printv('\nRemove temporary files...', verbose) sct.run('rm -rf ' + path_tmp, verbose) # display elapsed time elapsed_time = time.time() - start_time sct.printv( '\nFinished! Elapsed time: ' + str(int(round(elapsed_time))) + 's', verbose) sct.printv('\nTo view results, type:', verbose) sct.printv('fslview ' + fname_dest + ' ' + fname_src2dest + ' &', verbose, 'info') sct.printv('fslview ' + fname_src + ' ' + fname_dest2src + ' &\n', verbose, 'info')
def main(): #Initialization fname = '' verbose = param.verbose output_name = param.output_name smoothness = param.smoothness try: opts, args = getopt.getopt(sys.argv[1:],'hi:o:s:v:') except getopt.GetoptError: usage() for opt, arg in opts : if opt == '-h': usage() elif opt in ("-i"): fname = arg elif opt in ("-o"): output_name = arg elif opt in ("-s"): smoothness = arg elif opt in ('-v'): verbose = int(arg) # display usage if a mandatory argument is not provided if fname == '' : usage() # check existence of input files print'\nCheck if file exists ...' sct.check_file_exist(fname) # check if RPI sct.check_if_rpi(fname) # Display arguments print'\nCheck input arguments...' print' Input volume ...................... '+fname print' Verbose ........................... '+str(verbose) file = load(fname) data = file.get_data() hdr = file.get_header() X,Y,Z = (data>0).nonzero() Z_new = linspace(min(Z),max(Z),(max(Z)-min(Z)+1)) # tck1 = interpolate.splrep(Z, X, s=200) # X_fit = interpolate.splev(Z_new, tck1) # # tck2 = interpolate.splrep(Z, Y, s=200) # Y_fit = interpolate.splev(Z_new, tck2) # f1 = interpolate.interp1d(Z, X, kind='cubic') # f2 = interpolate.interp1d(Z,Y, kind='cubic') # # sort X and Y arrays using Z X = [X[i] for i in Z[:].argsort()] Y = [Y[i] for i in Z[:].argsort()] Z = [Z[i] for i in Z[:].argsort()] print X, Y, Z # NURBS! #X_fit, Y_fit, Z_fit, x_deriv, y_deriv, z_deriv = b_spline_nurbs(X, Y, Z, degree=3, point_number=3000) #f_opt_x, f_opt_y = opt_f(X,Y,Z) #print "f_opt = "+str(f_opt_x)+" "+str(f_opt_y) #f1 = non_parametric(Z,X,f=0.8) #f2 = non_parametric(Z,Y,f=0.8) f1 = interpolate.UnivariateSpline(Z, X) f2 = interpolate.UnivariateSpline(Z, Y) #f1 = polynomial_fit(Z,X,smoothness) #f2 = polynomial_fit(Z,Y,smoothness) X_fit = f1(Z_new) Y_fit = f2(Z_new) print X_fit print Y_fit if verbose==2 : import matplotlib.pyplot as plt plt.figure() plt.plot(Z_new,X_fit) plt.plot(Z,X,'o',linestyle = 'None') plt.show() plt.figure() plt.plot(Z_new,Y_fit) plt.plot(Z,Y,'o',linestyle = 'None') plt.show() data =data*0 for i in xrange(len(X_fit)): data[X_fit[i],Y_fit[i],Z_new[i]] = 1 print '\nSave volume ...' hdr.set_data_dtype('float32') # set imagetype to uint8 # save volume #data = data.astype(float32, copy =False) img = Nifti1Image(data, None, hdr) file_name = output_name save(img,file_name) print '\nFile created : ' + output_name del data
def main(): # Initialization fname_output = '' fname_mask = param.fname_mask fname_src_seg = '' fsloutput = 'export FSLOUTPUTTYPE=NIFTI; ' # for faster processing, all outputs are in NIFTI' start_time = time.time() # get path of the toolbox status, path_sct = commands.getstatusoutput('echo $SCT_DIR') # get default registration parameters # step1 = Paramreg(step='1', type='im', algo='syn', metric='MI', iter='5', shrink='1', smooth='0', gradStep='0.5') step0 = Paramreg(step='0', type='im', algo='syn', metric='MI', iter='0', shrink='1', smooth='0', gradStep='0.5') # only used to put src into dest space step1 = Paramreg() paramreg = ParamregMultiStep([step0, step1]) # Initialize the parser parser = Parser(__file__) parser.usage.set_description('This program co-registers two 3D volumes. The deformation is non-rigid and is ' 'constrained along Z direction (i.e., axial plane). Hence, this function assumes ' 'that orientation of the destination image is axial (RPI). If you need to register ' 'two volumes with large deformations and/or different contrasts, it is recommended to ' 'input spinal cord segmentations (binary mask) in order to achieve maximum robustness.' ' The program outputs a warping field that can be used to register other images to the' ' destination image. To apply the warping field to another image, use ' 'sct_apply_transfo') parser.add_option(name="-i", type_value="file", description="Image source.", mandatory=True, example="src.nii.gz") parser.add_option(name="-d", type_value="file", description="Image destination.", mandatory=True, example="dest.nii.gz") parser.add_option(name="-iseg", type_value="file", description="Segmentation source.", mandatory=False, example="src_seg.nii.gz") parser.add_option(name="-dseg", type_value="file", description="Segmentation destination.", mandatory=False, example="dest_seg.nii.gz") parser.add_option(name="-m", type_value="file", description="Binary mask to improve accuracy over region of interest.", mandatory=False, example="mask.nii.gz") parser.add_option(name="-o", type_value="file_output", description="Name of output file.", mandatory=False, example="src_reg.nii.gz") parser.add_option(name="-p", type_value=[[':'],'str'], description="""Parameters for registration. Separate arguments with ",". Separate steps with ":".\nstep: <int> Step number (starts at 1).\ntype: {im,seg} type of data used for registration.\nalgo: {slicereg,rigid,affine,syn,bsplinesyn}. Default="""+paramreg.steps['1'].algo+"""\n For info about slicereg, see here: goo.gl/Sj3ZeU\nmetric: {CC,MI,MeanSquares}. Default="""+paramreg.steps['1'].metric+"""\niter: <int> Number of iterations. Default="""+paramreg.steps['1'].iter+"""\nshrink: <int> Shrink factor (only for SyN). Default="""+paramreg.steps['1'].shrink+"""\nsmooth: <int> Smooth factor (only for SyN). Default="""+paramreg.steps['1'].smooth+"""\ngradStep: <float> Gradient step (only for SyN). Default="""+paramreg.steps['1'].gradStep+"""\npoly: <int> Polynomial degree (only for slicereg). Default="""+paramreg.steps['1'].poly, mandatory=False, example="step=1,type=seg,algo=slicereg,metric=MeanSquares:step=2,type=im,algo=syn,metric=MI,iter=5,shrink=2") parser.add_option(name="-z", type_value="int", description="""size of z-padding to enable deformation at edges when using SyN.""", mandatory=False, default_value=param.padding) parser.add_option(name="-x", type_value="multiple_choice", description="""Final interpolation.""", mandatory=False, default_value='linear', example=['nn', 'linear', 'spline']) parser.add_option(name="-r", type_value="multiple_choice", description="""Remove temporary files.""", mandatory=False, default_value='1', example=['0', '1']) parser.add_option(name="-v", type_value="multiple_choice", description="""Verbose.""", mandatory=False, default_value='1', example=['0', '1', '2']) arguments = parser.parse(sys.argv[1:]) # get arguments fname_src = arguments['-i'] fname_dest = arguments['-d'] if '-iseg' in arguments: fname_src_seg = arguments['-iseg'] if '-dseg' in arguments: fname_dest_seg = arguments['-dseg'] if '-o' in arguments: fname_output = arguments['-o'] if "-m" in arguments: fname_mask = arguments['-m'] padding = arguments['-z'] if "-p" in arguments: paramreg_user = arguments['-p'] # update registration parameters for paramStep in paramreg_user: paramreg.addStep(paramStep) interp = arguments['-x'] remove_temp_files = int(arguments['-r']) verbose = int(arguments['-v']) # Parameters for debug mode if param.debug: print '\n*** WARNING: DEBUG MODE ON ***\n' status, path_sct_data = commands.getstatusoutput('echo $SCT_TESTING_DATA_DIR') fname_dest = path_sct_data+'/mt/mt1.nii.gz' fname_src = path_sct_data+'/t2/t2.nii.gz' param_user = '******' remove_temp_files = '0' verbose = 1 # print arguments print '\nInput parameters:' print ' Source .............. '+fname_src print ' Destination ......... '+fname_dest print ' Mask ................ '+fname_mask print ' Output name ......... '+fname_output # print ' Algorithm ........... '+paramreg.algo # print ' Number of iterations '+paramreg.iter # print ' Metric .............. '+paramreg.metric print ' Remove temp files ... '+str(remove_temp_files) print ' Verbose ............. '+str(verbose) # update param param.verbose = verbose param.padding = padding param.fname_mask = fname_mask # Get if input is 3D sct.printv('\nCheck if input data are 3D...', verbose) sct.check_if_3d(fname_src) sct.check_if_3d(fname_dest) # check if destination data is RPI sct.printv('\nCheck if destination data is RPI...', verbose) sct.check_if_rpi(fname_dest) # 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) # define output folder and file name if fname_output == '': path_out = '' # output in user's current directory file_out = file_src+"_reg" ext_out = ext_src else: path_out, file_out, ext_out = sct.extract_fname(fname_output) # 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 files to temporary folder sct.printv('\nCopy files...', verbose) sct.run('isct_c3d '+fname_src+' -o '+path_tmp+'/src.nii', verbose) sct.run('isct_c3d '+fname_dest+' -o '+path_tmp+'/dest.nii', verbose) if fname_src_seg: sct.run('isct_c3d '+fname_src_seg+' -o '+path_tmp+'/src_seg.nii', verbose) sct.run('isct_c3d '+fname_dest_seg+' -o '+path_tmp+'/dest_seg.nii', verbose) if not fname_mask == '': sct.run('isct_c3d '+fname_mask+' -o '+path_tmp+'/mask.nii.gz', verbose) # go to tmp folder os.chdir(path_tmp) # Put source into destination space using header (no estimation -- purely based on header) # TODO: use c3d? # TODO: Check if necessary to do that # TODO: use that as step=0 # sct.printv('\nPut source into destination space using header...', verbose) # sct.run('isct_antsRegistration -d 3 -t Translation[0] -m MI[dest_pad.nii,src.nii,1,16] -c 0 -f 1 -s 0 -o [regAffine,src_regAffine.nii] -n BSpline[3]', verbose) # if segmentation, also do it for seg # loop across registration steps warp_forward = [] warp_inverse = [] for i_step in range(0, len(paramreg.steps)): sct.printv('\nEstimate transformation for step #'+str(i_step)+'...', param.verbose) # identify which is the src and dest if paramreg.steps[str(i_step)].type == 'im': src = 'src.nii' dest = 'dest.nii' interp_step = 'linear' elif paramreg.steps[str(i_step)].type == 'seg': src = 'src_seg.nii' dest = 'dest_seg.nii' interp_step = 'nn' else: sct.run('ERROR: Wrong image type.', 1, 'error') # if step>0, apply warp_forward_concat to the src image to be used if i_step > 0: sct.run('sct_apply_transfo -i '+src+' -d '+dest+' -w '+','.join(warp_forward)+' -o '+sct.add_suffix(src, '_reg')+' -x '+interp_step, verbose) src = sct.add_suffix(src, '_reg') # register src --> dest warp_forward_out, warp_inverse_out = register(src, dest, paramreg, param, str(i_step)) warp_forward.append(warp_forward_out) warp_inverse.append(warp_inverse_out) # Concatenate transformations sct.printv('\nConcatenate transformations...', verbose) sct.run('sct_concat_transfo -w '+','.join(warp_forward)+' -d dest.nii -o warp_src2dest.nii.gz', verbose) warp_inverse.reverse() sct.run('sct_concat_transfo -w '+','.join(warp_inverse)+' -d dest.nii -o warp_dest2src.nii.gz', verbose) # Apply warping field to src data sct.printv('\nApply transfo source --> dest...', verbose) sct.run('sct_apply_transfo -i src.nii -o src_reg.nii -d dest.nii -w warp_src2dest.nii.gz -x '+interp, verbose) sct.printv('\nApply transfo dest --> source...', verbose) sct.run('sct_apply_transfo -i dest.nii -o dest_reg.nii -d src.nii -w warp_dest2src.nii.gz -x '+interp, verbose) # come back to parent folder os.chdir('..') # Generate output files sct.printv('\nGenerate output files...', verbose) fname_src2dest = sct.generate_output_file(path_tmp+'/src_reg.nii', path_out+file_out+ext_out, verbose) sct.generate_output_file(path_tmp+'/warp_src2dest.nii.gz', path_out+'warp_'+file_src+'2'+file_dest+'.nii.gz', verbose) fname_dest2src = sct.generate_output_file(path_tmp+'/dest_reg.nii', path_out+file_dest+'_reg'+ext_dest, verbose) sct.generate_output_file(path_tmp+'/warp_dest2src.nii.gz', path_out+'warp_'+file_dest+'2'+file_src+'.nii.gz', verbose) # sct.generate_output_file(path_tmp+'/warp_dest2src.nii.gz', path_out+'warp_dest2src.nii.gz') # Delete temporary files if remove_temp_files: sct.printv('\nRemove temporary files...', verbose) sct.run('rm -rf '+path_tmp, verbose) # display elapsed time elapsed_time = time.time() - start_time sct.printv('\nFinished! Elapsed time: '+str(int(round(elapsed_time)))+'s', verbose) sct.printv('\nTo view results, type:', verbose) sct.printv('fslview '+fname_dest+' '+fname_src2dest+' &', verbose, 'info') sct.printv('fslview '+fname_src+' '+fname_dest2src+' &\n', verbose, 'info')