def copy_to_tmp(self, target_fname, sc_seg_fname, t2_data=None): sct.run('cp ' + target_fname + ' ' + self.tmp_dir + '/' + self.original_target) sct.run('cp ' + sc_seg_fname + ' ' + self.tmp_dir + '/' + self.original_sc_seg) if self.t2 is not None: sct.run('cp ' + t2_data[0] + ' ' + self.tmp_dir + '/' + self.t2) sct.run('cp ' + t2_data[1] + ' ' + self.tmp_dir + '/' + self.t2_seg) sct.run('cp ' + t2_data[2] + ' ' + self.tmp_dir + '/' + self.t2_landmarks)
def pad_image(fname_in, file_out, padding): import sct_utils as sct sct.run( "isct_c3d " + fname_in + " -pad 0x0x" + str(padding) + "vox 0x0x" + str(padding) + "vox 0 -o " + file_out, 1 ) return
def __init__(self, target_fname, sc_seg_fname, tmp_dir='', t2_data=None, level_fname=None, denoising=True): # initiate de file names and copy the files into the temporary directory self.original_target = 'target.nii.gz' self.original_sc_seg = 'target_sc_seg.nii.gz' self.resample_to = 0.3 self.tmp_dir = tmp_dir self.denoising = denoising if level_fname is not None: t2_data = None level_fname_nii = check_file_to_niigz(level_fname) if level_fname_nii: path_level, file_level, ext_level = sct.extract_fname(level_fname_nii) self.fname_level = file_level + ext_level sct.run('cp ' + level_fname_nii + ' ' + tmp_dir + '/' + self.fname_level) else: self.fname_level = None if t2_data is not None: self.t2 = 't2.nii.gz' self.t2_seg = 't2_seg.nii.gz' self.t2_landmarks = 't2_landmarks.nii.gz' else: self.t2 = self.t2_seg = self.t2_landmarks = None # processes: self.copy_to_tmp(target_fname=target_fname, sc_seg_fname=sc_seg_fname, t2_data=t2_data)
def average_levels(contrast): print '\nGo to output folder '+ PATH_OUTPUT + '/labels_vertebral_' + contrast + '\n' os.chdir(PATH_OUTPUT +'/labels_vertebral_' + contrast) print'\nCalculate mean along subjects of files labels_vertebral and save it into '+PATH_OUTPUT +'/labels_vertebral_' + contrast +' as template_landmarks.nii.gz' template_shape = path_sct + '/dev/template_creation/template_shape.nii.gz' # this function looks at all files inside the folder "labels_vertebral_T*" and find the average vertebral levels across subjects sct.run('sct_average_levels.py -i ' +PATH_OUTPUT +'/labels_vertebral_' + contrast + ' -t '+ template_shape +' -n '+ str(number_labels_for_template))
def test(path_data): # parameters folder_data = 't2/' file_data = 't2_seg.nii.gz' # define command cmd = 'sct_process_segmentation -i ' + path_data + folder_data + file_data \ + ' -p centerline' \ + ' -v 1' output = '\n====================================================================================================\n'+cmd+'\n====================================================================================================\n\n' # copy command status, o = sct.run(cmd, 0) output += o # define command cmd = 'sct_process_segmentation -i ' + path_data + folder_data + file_data \ + ' -p length' output = '\n====================================================================================================\n'+cmd+'\n====================================================================================================\n\n' # copy command status, o = sct.run(cmd, 0) output += o # define command cmd = 'sct_process_segmentation -i ' + path_data + folder_data + file_data \ + ' -p csa' \ + ' -size 1'\ + ' -r 0'\ + ' -v 1' output = '\n====================================================================================================\n'+cmd+'\n====================================================================================================\n\n' # copy command status, o = sct.run(cmd, 0) output += o return status, output
def create_temporary_path(self): import time from sct_utils import slash_at_the_end path_tmp = slash_at_the_end("tmp." + time.strftime("%y%m%d%H%M%S"), 1) sct.run("mkdir " + path_tmp, self.verbose) return path_tmp
def resample_labels(fname_labels, fname_dest, fname_output): """ This function re-create labels into a space that has been resampled. It works by re-defining the location of each label using the old and new voxel size. """ # get dimensions of input and destination files nx, ny, nz, nt, px, py, pz, pt = sct.get_dimension(fname_labels) nxd, nyd, nzd, ntd, pxd, pyd, pzd, ptd = sct.get_dimension(fname_dest) sampling_factor = [float(nx)/nxd, float(ny)/nyd, float(nz)/nzd] # read labels from sct_label_utils import ProcessLabels processor = ProcessLabels(fname_labels) label_list = processor.display_voxel().split(':') # parse to get each label # TODO: modify sct_label_utils to output list of coordinates instead of string. label_new_list = [] for label in label_list: label_sub = label.split(',') label_sub_new = [] for i_label in range(0, 3): label_single = round(int(label_sub[i_label])/sampling_factor[i_label]) label_sub_new.append(str(int(label_single))) label_sub_new.append(str(int(float(label_sub[3])))) label_new_list.append(','.join(label_sub_new)) label_new_list = ':'.join(label_new_list) # create new labels sct.run('sct_label_utils -i '+fname_dest+' -t create -x '+label_new_list+' -v 1 -o '+fname_output)
def push_into_templace_space(contrast): for i in range(0,len(SUBJECTS_LIST)): subject = SUBJECTS_LIST[i][0] # go to output folder print '\nGo to output folder '+ PATH_OUTPUT + '/subjects/' + subject + '/' + contrast os.chdir(PATH_OUTPUT + '/subjects/' + subject + '/' + contrast ) # Push into template space print'\nPush into template space...' sct.run('sct_push_into_template_space.py -i data_RPI_crop_normalized_straight_crop.nii.gz -n landmark_native.nii.gz') sct.run('sct_push_into_template_space.py -i labels_vertebral_dilated_reg_2point_crop.nii.gz -n landmark_native.nii.gz -a nn') # Change image type from float64 to uint16 sct.run('sct_change_image_type.py -i data_RPI_crop_normalized_straight_crop_2temp.nii.gz -o data_RPI_crop_normalized_straight_crop_2temp.nii.gz -t uint16') # get center of mass of each label group print '\nGet center of mass of each label group due to affine transformation...' sct.run('sct_label_utils -i labels_vertebral_dilated_reg_2point_crop_2temp.nii.gz -o labels_vertebral_dilated_reg_2point_crop_2temp.nii.gz -t cubic-to-point') # Copy labels_vertebral_straight_in_template_space.nii.gz into a folder that will contain each subject labels_vertebral_straight_in_template_space.nii.gz file and rename them print'\nCheck if forlder '+PATH_OUTPUT +'/labels_vertebral_' + contrast+ ' exists and if not creates it ...' # check if folder exists and if not create it if not os.path.isdir(PATH_OUTPUT +'/labels_vertebral_' + contrast): os.makedirs(PATH_OUTPUT + '/labels_vertebral_' + contrast) sct.run('cp labels_vertebral_dilated_reg_2point_crop_2temp.nii.gz '+PATH_OUTPUT +'/labels_vertebral_' + contrast + '/'+subject+'.nii.gz')
def extract_sagital_slice(self): """Extract the sagital slice where the detection is done. If the segmentation is provided, the 2D sagital slice is choosen accoding to the segmentation. If the segmentation is not provided, the 2D sagital slice is choosen as the mid-sagital slice of the input image. """ if self.fname_seg is not None: img_seg = Image(self.fname_seg) z_mid_slice = img_seg.data[:, int(img_seg.dim[1] / 2), :] if 1 in z_mid_slice: # if SC segmentation available at this slice self.rl_coord = int(center_of_mass(z_mid_slice)[1]) # Right_left coordinate else: self.rl_coord = int(img_seg.dim[2] / 2) del img_seg else: img = Image(self.fname_im) self.rl_coord = int(img.dim[2] / 2) # Right_left coordinate del img sct.run(['sct_crop_image', '-i', self.fname_im, '-start', str(self.rl_coord), '-end', str(self.rl_coord), '-dim', '2', '-o', self.slice2D_im])
def segmentation_pipeline(self): sct.printv('\nDoing target pre-processing ...', verbose=self.seg_param.verbose, type='normal') self.preprocessed = Preprocessing(self.target_fname, self.sc_seg_fname, tmp_dir=self.tmp_dir, t2_data=self.t2_data, level_fname=self.level_fname, denoising=self.seg_param.target_denoising) self.preprocessed.process() os.chdir(self.tmp_dir) if self.preprocessed.fname_level is not None: self.level_to_use = self.preprocessed.fname_level else: self.level_to_use = None sct.printv('\nDoing target gray matter segmentation ...', verbose=self.seg_param.verbose, type='normal') self.gm_seg = SupervisedSegmentationMethod(self.preprocessed.processed_target, self.level_to_use, self.model, gm_seg_param=self.seg_param) sct.printv('\nDoing result post-processing ...', verbose=self.seg_param.verbose, type='normal') self.post_processing() if self.ref_gm_seg_fname is not None: os.chdir('..') ref_gmseg = 'ref_gmseg.nii.gz' sct.run('cp ' + self.ref_gm_seg_fname + ' ' + self.tmp_dir + '/' + ref_gmseg) os.chdir(self.tmp_dir) sct.printv('Computing Dice coefficient and Hausdorff distance ...', verbose=self.seg_param.verbose, type='normal') self.dice_name, self.hausdorff_name = self.validation(ref_gmseg) if compute_ratio: sct.printv('\nComputing ratio GM/WM ...', verbose=self.seg_param.verbose, type='normal') self.ratio_name = self.compute_ratio(type=compute_ratio) os.chdir('..')
def create_line(param, fname, coord, nz): """ Create vertical line in 3D volume :param param: :param fname: :param coord: :param nz: :return: """ # duplicate volume (assumes input file is nifti) sct.copy(fname, 'line.nii', verbose=param.verbose) # set all voxels to zero sct.run(['sct_maths', '-i', 'line.nii', '-mul', '0', '-o', 'line.nii'], param.verbose) cmd = ['sct_label_utils', '-i', 'line.nii', '-o', 'line.nii', '-create-add'] for iz in range(nz): if iz == nz - 1: cmd += [str(int(coord[0])) + ',' + str(int(coord[1])) + ',' + str(iz) + ',1'] else: cmd += [str(int(coord[0])) + ',' + str(int(coord[1])) + ',' + str(iz) + ',1:'] sct.run(cmd, param.verbose) return 'line.nii'
def set_orientation(im, orientation, data_inversion=False, filename=False, fname_out=''): """ Set orientation on image :param im: either Image object or file name. Carefully set param filename. :param orientation: :param data_inversion: :param filename: :return: """ if fname_out: pass elif filename: path, fname, ext = extract_fname(im) fname_out = fname+'_'+orientation+ext else: fname_out = im.file_name+'_'+orientation+im.ext if not data_inversion: from sct_utils import run if filename: run('isct_orientation3d -i '+im+' -orientation '+orientation+' -o '+fname_out, 0) im_out = fname_out else: run('isct_orientation3d -i '+im.absolutepath+' -orientation '+orientation+' -o '+fname_out, 0) im_out = Image(fname_out) else: im_out = im.copy() im_out.change_orientation(orientation, True) im_out.setFileName(fname_out) return im_out
def main(input_anatomy_file, list_files, param, remove_temp_files = 1, verbose = 0) : path, file, ext = sct.extract_fname(input_anatomy_file) # Image denoising print '\nDenoising image ' + input_anatomy_file +'...' sct.run('sct_denoising_onlm.py -i '+ input_anatomy_file + ' -p ' + type_noise + ' -r ' + str(remove_temp_files) + ' -v ' + str(verbose)) # Extract and fit centerline list_name_files = list_files[0] for i in range(1, len(list_files)): list_name_files = list_name_files + ',' + list_files[i] print '\nExtracting and fitting centerline...' sct.run('sct_get_centerline_from_labels -i '+ list_name_files + ' -r ' + str(remove_temp_files) + ' -v ' + str(verbose)) # Straighten the image using the fitted centerline print '\nStraightening the image ' + input_anatomy_file + ' using the fitted centerline ' + 'generated_centerline.nii.gz'+ ' ...' sct.run('sct_straighten_spinalcord -i ' + input_anatomy_file + ' -c ' + 'generated_centerline.nii.gz' + ' -r ' + str(remove_temp_files) + ' -v ' + str(verbose)) output_straighten_name = file + '_straight' +ext # Aplly transfo to the centerline print '\nApplying transformation to the centerline...' sct.run('sct_apply_transfo -i ' + 'generated_centerline.nii.gz' + ' -d ' + output_straighten_name + ' -w ' + 'warp_curve2straight.nii.gz' + ' -x ' + 'linear' + ' -v ' + str(verbose)) # Normalize intensity of the image using the straightened centerline print '\nNormalizing intensity of the straightened image...' sct.run('sct_normalize.py -i ' + output_straighten_name + ' -c generated_centerline_reg.nii.gz' + ' -v ' + str(verbose))
def main(): # Initialization path_data = '' xmin = '50' xsize = '100' ymin = '0' ysize = '-1' zmin = '0' zsize = '-1' fsloutput = 'export FSLOUTPUTTYPE=NIFTI; ' # for faster processing, all outputs are in NIFTI # Parameters for debug mode if param.debug: print '\n*** WARNING: DEBUG MODE ON ***\n' path_data = '/Volumes/folder_shared/template/t2' path_out = '/Volumes/folder_shared/template/t2_crop' else: # Check input parameters try: opts, args = getopt.getopt(sys.argv[1:], 'hi:o:') except getopt.GetoptError: usage() if not opts: usage() for opt, arg in opts: if opt == '-h': usage() elif opt in ("-i"): path_data = arg elif opt in ("-o"): path_out = arg # check input folder sct.check_folder_exist(path_data) # add slash path_data = sct.slash_at_the_end(path_data, 1) path_out = sct.slash_at_the_end(path_out, 1) # create output folder if os.path.exists(path_out): sct.printv('WARNING: Output folder exists. Deleting it.', 1, 'warning') # remove dir shutil.rmtree(path_out) # create dir os.makedirs(path_out) # list all files in folder files = [f for f in glob.glob(path_data+'*.nii.gz')] # for files in glob.glob(path_data+'*.nii.gz'): # print files # crop files one by one (to inform user) for f in files: path_f, file_f, ext_f = sct.extract_fname(f) sct.run('fslroi '+f+' '+path_out+file_f+' '+xmin+' '+xsize+' '+ymin+' '+ysize+' '+zmin+' '+zsize) # to view results print '\nDone!'
def downloaddata(): sct.printv('\nDownloading testing data...', param.verbose) # remove data folder if exist if os.path.exists('sct_testing_data'): sct.printv('WARNING: sct_testing_data already exists. Removing it...', param.verbose, 'warning') sct.run('rm -rf sct_testing_data') # clone git repos sct.run('git clone '+param.url_git)
def loocv(param): use_level, weight = param sct.run('mkdir ./' + registration + '_levels_' + str(use_level) + '_weight' + str(weight) ) sct.run('cp -r ' + path_dictionary + ' ./' + registration + '_levels_' + str(use_level) + '_weight' + str(weight) + '/dictionary') os.chdir('./' +registration + '_levels_' + str(use_level) + '_weight' + str(weight)) # leave_one_out_by_slice('dictionary/', reg=registration, target_reg=target_reg, use_levels=use_level, weight=weight) leave_one_out_by_subject('dictionary/', use_levels=use_level, weight=weight) os.chdir('..')
def crop(self): """ Crop image (change dimension) """ # create command line img_in = Image(self.input_filename) self.cmd = ["isct_crop_image", "-i", self.input_filename, "-o", self.output_filename] # Handling optional arguments # if mask is specified, find -start and -end arguments if self.mask is not None: # if user already specified -start or -end arguments, let him know they will be ignored if self.start is not None or self.end is not None: sct.printv('WARNING: Mask was specified for cropping. Arguments -start and -end will be ignored', 1, 'warning') self.start, self.end, self.dim = find_mask_boundaries(self.mask) if self.start is not None: self.cmd += ["-start", ','.join(map(str, self.start))] if self.end is not None: self.cmd += ["-end", ','.join(map(str, self.end))] if self.dim is not None: self.cmd += ["-dim", ','.join(map(str, self.dim))] if self.shift is not None: self.cmd += ["-shift", ','.join(map(str, self.shift))] if self.background is not None: self.cmd += ["-b", str(self.background)] if self.bmax is True: self.cmd += ["-bmax"] if self.ref is not None: self.cmd += ["-ref", self.ref] if self.mesh is not None: self.cmd += ["-mesh", self.mesh] verb = 0 if self.verbose == 1: verb = 2 if self.mask is not None and self.background is not None: self.crop_from_mask_with_background() else: # Run command line sct.run(self.cmd, verb, is_sct_binary=True) self.result = Image(self.output_filename, verbose=self.verbose) # removes the output file created by the script if it is not needed if self.rm_output_file: try: os.remove(self.output_filename) except OSError: sct.printv("WARNING : Couldn't remove output file. Either it is opened elsewhere or " "it doesn't exist.", self.verbose, 'warning') else: sct.display_viewer_syntax([self.output_filename]) return self.result
def crop(self): """ Crop image (change dimension) """ # create command line self.cmd = "isct_crop_image" + " -i " + self.input_filename + " -o " + self.output_filename # Handling optional arguments # if mask is specified, find -start and -end arguments if self.mask is not None: # if user already specified -start or -end arguments, let him know they will be ignored if self.start is not None or self.end is not None: sct.printv('WARNING: Mask was specified for cropping. Arguments -start and -end will be ignored', 1, 'warning') self.start, self.end, self.dim = find_mask_boundaries(self.mask) if self.start is not None: self.cmd += " -start " + ','.join(map(str, self.start)) if self.end is not None: self.cmd += " -end " + ','.join(map(str, self.end)) if self.dim is not None: self.cmd += " -dim " + ','.join(map(str, self.dim)) if self.shift is not None: self.cmd += " -shift " + ','.join(map(str, self.shift)) if self.background is not None: self.cmd += " -b " + str(self.background) if self.bmax is True: self.cmd += " -bmax" if self.ref is not None: self.cmd += " -ref " + self.ref if self.mesh is not None: self.cmd += " -mesh " + self.mesh verb = 0 if self.verbose == 1: verb = 2 if self.mask is not None and self.background is not None: self.crop_from_mask_with_background() else: # Run command line sct.run(self.cmd, verb) self.result = Image(self.output_filename, verbose=self.verbose) # removes the output file created by the script if it is not needed if self.rm_output_file: try: os.remove(self.output_filename) except OSError: sct.printv("WARNING : Couldn't remove output file. Either it is opened elsewhere or " "it doesn't exist.", self.verbose, 'warning') else: # Complete message sct.printv('\nDone! To view results, type:', self.verbose) sct.printv("fslview "+self.output_filename+" &\n", self.verbose, 'info') return self.result
def save_parameters(self, fname_out=''): pickle.dump(self.weights_contraction, open("unet-model-weights_contraction.p", "wb")) pickle.dump(self.weights_bottom_layer, open("unet-model-weights_bottom_layer.p", "wb")) pickle.dump(self.upconv_weights, open("unet-model-upconv_weights.p", "wb")) pickle.dump(self.weights_expansion, open("unet-model-weights_expansion.p", "wb")) pickle.dump(self.finalconv_weights, open("unet-model-finalconv_weights.p", "wb")) if not fname_out: fname_out = 'unet-model.gz' sct.run('gzip unet-model-* > ' + fname_out)
def prepare(list_images): fname_images, orientation_images = [], [] for fname_im in list_images: from sct_image import orientation orientation_images.append(orientation(Image(fname_im), get=True, verbose=False)) path_fname, file_fname, ext_fname = sct.extract_fname(fname_im) reoriented_image_filename = 'tmp.' + sct.add_suffix(file_fname + ext_fname, "_SAL") sct.run('sct_image -i ' + fname_im + ' -o ' + reoriented_image_filename + ' -setorient SAL -v 0', verbose=False) fname_images.append(reoriented_image_filename) return fname_images, orientation_images
def save_3D_nparray_nifti(np_matrix_3d, output_image, fname_atlas): # Save 3d numpy matrix to niftii image # np_matrix_3d is a 3D numpy ndarray # output_image is the name of the niftii image created, ex: '3D_matrix.nii.gz' img = nib.Nifti1Image(np_matrix_3d, np.eye(4)) affine = img.get_affine() np_matrix_3d_nii = nib.Nifti1Image(np_matrix_3d,affine) nib.save(np_matrix_3d_nii, output_image) # copy geometric information sct.run('fslcpgeom '+fname_atlas+' '+output_image, verbose=0)
def crop_file(fname_data, folder_out, zind): # extract file name path_list, file_list, ext_list = sct.extract_fname(fname_data) # crop file with fsl, and then merge back cmd = 'fslmerge -z '+os.path.join(folder_out, file_list) for i in zind: sct.run('fslroi '+fname_data+' z'+str(zind.index(i))+'_'+file_list+' 0 -1 0 -1 '+str(i)+' 1') cmd = cmd+' z'+str(zind.index(i))+'_'+file_list sct.run(cmd)
def smooth(fname, sigma): path, fname, ext_fname = sct.extract_fname(fname) print 'centerline smoothing...' fname_smooth = fname +'_smooth' print 'Gauss sigma: ', smooth cmd = 'fslmaths ' + fname + ' -s ' + str(sigma) + ' ' + fname_smooth + ext_fname sct.run(cmd) return fname_smooth + ext_fname
def main(): # initialization os_running = 'not identified' print # check OS print 'Check which OS is running... ' platform_running = sys.platform if (platform_running.find('darwin') != -1): os_running = 'osx' elif (platform_running.find('linux') != -1): os_running = 'linux' print ' '+os_running+' ('+platform.platform()+')' # fetch version of the toolbox print 'Fetch version of the toolbox... ' with open (path_sct+"/version.txt", "r") as myfile: version_sct = myfile.read().replace('\n', '') print " toolbox version: "+version_sct # fetch version of the patch print 'Fetch version of the patch... ' with open ("version.txt", "r") as myfile: version_patch = myfile.read().replace('\n', '') print " patch version: "+version_patch # if patch is not compatible with this release, send message and quit. print 'Check compatibility... ' version_sct_num = version_sct.split('.') version_patch_num = version_patch.split('.') if not ( ( version_sct_num[0] == version_patch_num[0] ) and ( version_sct_num[1] == version_patch_num[1] ) ): print " ERROR: Patch is not compatible with this release. Patch version X.Y.Z should correspond to release" \ " version X.Y. Exit program.\n" sys.exit(2) else: print " OK" # list all files in patch files = [os.path.join(dp, f) for dp, dn, filenames in os.walk('.') for f in filenames] # copy files one by one (to inform user) for f in files: path_name, file_name, ext_name = sct.extract_fname(f) # check if .DS_Store (could happen during package creation) if not file_name == ".DS_Store": # copy file # print path_name[2:]+' ++ '+file_name+' ++ '+ext_name file_src = path_name+file_name+ext_name file_dest = path_sct+path_name[1:]+file_name+ext_name sct.run('sudo cp '+file_src+' '+file_dest) print "Done!\n"
def compile_denoise(target_os, issudo=''): path_denoise = path_sct + '/dev/denoise/ornlm' # go to folder os.chdir(path_denoise) sct.run('python setup.py bdist_wheel') if target_os == 'darwin': # delocating is only for osx sct.run('delocate-listdeps dist/*.whl # lists library dependencies') sct.run('delocate-wheel dist/*.whl # copies library dependencies into wheel') sct.run('delocate-addplat --rm-orig -x 10_9 -x 10_10 dist/*.whl') sct.run(issudo + 'cp ' + path_denoise + '/dist/*.whl ' + path_sct + '/external/')
def concat_and_apply(inputs, dest, output_names, warps, interpolation='Linear'): # input = [input1, input2] # warps = [warp_1, warp_2] warp_str = '' for i in range(len(warps)): warp_str = ' '.join((warp_str, warps[-1-i])) cmd_0 = ('isct_ComposeMultiTransform 2 outwarp.nii.gz ' + warp_str + ' -R ' + dest) sct.run(cmd_0) for j in range(len(inputs)): cmd_1 = ('isct_antsApplyTransforms -d 2 -i ' + inputs[j] + ' -o '+ output_names[j] + ' -n '+interpolation+' -t outwarp.nii.gz -r '+ dest) sct.run(cmd_1)
def set_orientation(fname_in, orientation, fname_out, inversion=False): if not inversion: sct.run('isct_orientation3d -i '+fname_in+' -orientation '+orientation+' -o '+fname_out, 0) else: from msct_image import Image input_image = Image(fname_in) input_image.change_orientation(orientation, True) input_image.setFileName(fname_out) input_image.save() # return full path return os.path.abspath(fname_out)
def detect(self): """Run the classifier on self.slice2D_im.""" sct.printv('\nRun PMJ detector', self.verbose, 'normal') os.environ["FSLOUTPUTTYPE"] = "NIFTI_PAIR" cmd_pmj = ['isct_spine_detect', self.pmj_model, self.slice2D_im.split('.nii')[0], self.dection_map_pmj] print(cmd_pmj) sct.run(cmd_pmj, verbose=0, is_sct_binary=True) img = nib.load(self.dection_map_pmj + '_svm.hdr') # convert .img and .hdr files to .nii nib.save(img, self.dection_map_pmj + '.nii') self.dection_map_pmj += '.nii' # fname of the resulting detection map
def setup_debug_folder(self): """ Sets up the folder for the step by step files for this algorithm The folder's absolute path can be found in the self.debug_folder property :return: None """ if self.produce_output: import time from sct_utils import slash_at_the_end folder = slash_at_the_end('scad_output_'+time.strftime("%y%m%d%H%M%S"), 1) sct.run('mkdir '+folder, self.verbose) self.debug_folder = os.path.abspath(folder) conv.convert(str(self.input_image.absolutepath), str(self.debug_folder)+"/raw.nii.gz")
def produce_output_files(self): import time from sct_utils import slash_at_the_end path_tmp = slash_at_the_end('scad_output_'+time.strftime("%y%m%d%H%M%S"), 1) sct.run('mkdir '+path_tmp, self.verbose) # getting input image header os.chdir(path_tmp) try: img = self.input_image.copy() # saving body symmetry img.data = self.raw_symmetry img.change_orientation(self.raw_orientation) img.file_name += "body_symmetry" img.save() # saving minimum paths img.data = self.minimum_path_data img.change_orientation(self.raw_orientation) img.file_name = "min_path" img.save() img.data = self.J1_min_path img.change_orientation(self.raw_orientation) img.file_name = "J1_min_path" img.save() img.data = self.J2_min_path img.change_orientation(self.raw_orientation) img.file_name = "J2_min_path" img.save() # saving minimum path powered img.data = self.minimum_path_powered img.change_orientation(self.raw_orientation) img.file_name = "min_path_powered_"+str(self.minimum_path_exponent) img.save() # saving smoothed min path img = self.smoothed_min_path.copy() img.change_orientation(self.raw_orientation) img.file_name = "min_path_power_"+str(self.minimum_path_exponent)+"_smoothed" img.save() # save symmetry_weighted_minimal_path img.data = self.spine_detect_data img.change_orientation(self.raw_orientation) img.file_name = "symmetry_weighted_minimal_path" img.save() except Exception, e: raise e
def find_zmin_zmax(fname): import sct_utils as sct # crop image status, output = sct.run('sct_crop_image -i ' + fname + ' -dim 2 -bmax -o tmp.nii') # parse output zmin, zmax = output[output.find('Dimension 2: ') + 13:].split('\n')[0].split(' ') return int(zmin), int(zmax)
def test(path_data): folder_data = 't2/' file_data = [ 't2.nii.gz', 't2_seg.nii.gz', 't2_straight.nii.gz', 't2_seg_straight.nii.gz' ] dice_threshold = 0.99 cmd = 'sct_straighten_spinalcord -i ' + path_data + folder_data + file_data[0] \ + ' -c ' + path_data + folder_data + file_data[1] \ + ' -r 0' \ + ' -v 1' status, output = sct.run(cmd, 0) if status == 0: cmd_c2s = 'sct_apply_transfo -i ' + path_data + folder_data + file_data[1] + \ ' -d ' + file_data[2] + \ ' -w warp_curve2straight.nii.gz' + \ ' -o ' + file_data[3] + \ ' -x nn' status_c2s, output_c2s = sct.run(cmd_c2s, 0) if status_c2s != 0: return status_c2s, output_c2s cmd_s2c = 'sct_apply_transfo -i ' + file_data[3] + \ ' -d ' + path_data + folder_data + file_data[0] + \ ' -w warp_straight2curve.nii.gz' + \ ' -o image_test.nii.gz ' \ '-x nn' status_s2c, output_s2c = sct.run(cmd_s2c, 0) if status_s2c != 0: return status_s2c, output_s2c cmd_dice = 'sct_dice_coefficient ' + path_data + folder_data + file_data[1] + \ ' image_test.nii.gz -bzmax' status_dice, output_dice = sct.run(cmd_dice, 0) if float(output_dice.split('3D Dice coefficient = ') [1]) < dice_threshold: output += output_c2s + output_s2c + output_dice status = 5 return status, output
def resample_image(fname, suffix='_resampled.nii.gz', binary=False, npx=0.3, npy=0.3, thr=0.0, interpolation='spline'): """ Resampling function: add a padding, resample, crop the padding :param fname: name of the image file to be resampled :param suffix: suffix added to the original fname after resampling :param binary: boolean, image is binary or not :param npx: new pixel size in the x direction :param npy: new pixel size in the y direction :param thr: if the image is binary, it will be thresholded at thr (default=0) after the resampling :param interpolation: type of interpolation used for the resampling :return: file name after resampling (or original fname if it was already in the correct resolution) """ im_in = Image(fname) orientation = im_in.orientation if orientation != 'RPI': fname = im_in.change_orientation(im_in, 'RPI', generate_path=True).save().absolutepath nx, ny, nz, nt, px, py, pz, pt = im_in.dim if np.round(px, 2) != np.round(npx, 2) or np.round(py, 2) != np.round(npy, 2): name_resample = sct.extract_fname(fname)[1] + suffix if binary: interpolation = 'nn' if nz == 1: # when data is 2d: we convert it to a 3d image in order to avoid conversion problem with 2d data # TODO: check if this above problem is still present (now that we are using nibabel instead of nipy) sct.run(['sct_image', '-i', ','.join([fname, fname]), '-concat', 'z', '-o', fname]) sct.run(['sct_resample', '-i', fname, '-mm', str(npx) + 'x' + str(npy) + 'x' + str(pz), '-o', name_resample, '-x', interpolation]) if nz == 1: # when input data was 2d: re-convert data 3d-->2d sct.run(['sct_image', '-i', name_resample, '-split', 'z']) im_split = Image(name_resample.split('.nii.gz')[0] + '_Z0000.nii.gz') im_split.save(name_resample) if binary: sct.run(['sct_maths', '-i', name_resample, '-bin', str(thr), '-o', name_resample]) if orientation != 'RPI': name_resample = Image(name_resample) \ .change_orientation(orientation, generate_path=True) \ .save() \ .absolutepath return name_resample else: if orientation != 'RPI': fname = sct.add_suffix(fname, "_RPI") im_in = msct_image.change_orientation(im_in, orientation).save(fname) sct.printv('Image resolution already ' + str(npx) + 'x' + str(npy) + 'xpz') return fname
def get_orientation_3d(im, filename=False): """ Get orientation from 3D data :param im: :return: """ from sct_utils import run string_out = 'Input image orientation : ' # get orientation if filename: status, output = run('isct_orientation3d -i ' + im + ' -get ', 0) else: status, output = run('isct_orientation3d -i ' + im.absolutepath + ' -get ', 0) # check status if status != 0: printv('ERROR in get_orientation.', 1, 'error') orientation = output[output.index(string_out) + len(string_out):] # orientation = output[26:] return orientation
def align_vertebrae(contrast): for i in range(0,len(SUBJECTS_LIST)): subject = SUBJECTS_LIST[i][0] # go to output folder print '\nGo to output folder '+ PATH_OUTPUT + '/subjects/'+subject+ '/' + contrast + '\n' os.chdir(PATH_OUTPUT + '/subjects/' + subject + '/' + contrast) print '\nAligning vertebrae for subject '+subject+'...' sct.printv('\nsct_align_vertebrae.py -i data_RPI_crop_normalized_straight_crop_2temp.nii.gz -l ' + PATH_OUTPUT + '/subjects/' + subject + '/' + contrast + '/labels_vertebral_dilated_reg_2point_crop_2temp.nii.gz -R ' +PATH_OUTPUT +'/labels_vertebral_' + contrast + '/template_landmarks.nii.gz -o '+ subject+'_aligned.nii.gz -t SyN -w spline') os.system('sct_align_vertebrae.py -i data_RPI_crop_normalized_straight_crop_2temp.nii.gz -l ' + PATH_OUTPUT + '/subjects/' + subject + '/' + contrast + '/labels_vertebral_dilated_reg_2point_crop_2temp.nii.gz -R ' +PATH_OUTPUT +'/labels_vertebral_' + contrast + '/template_landmarks.nii.gz -o '+ subject+'_aligned.nii.gz -t SyN -w spline') # Change image type from float64 to uint16 sct.run('sct_change_image_type.py -i ' + subject+'_aligned.nii.gz -o ' + subject+'_aligned.nii.gz -t uint16') # Inform that results for the subject is ready print'\nThe results for subject '+subject+' are ready. You can visualize them by tapping: fslview '+subject+'_aligned_normalized.nii.gz' # Copy final results into final results if not os.path.isdir(PATH_OUTPUT +'/Final_results'): os.makedirs(PATH_OUTPUT +'/Final_results') sct.run('cp '+subject+'_aligned.nii.gz ' +PATH_OUTPUT +'/Final_results/'+subject+'_aligned_' + contrast + '.nii.gz') #Save png images of the results into a different folder print '\nSaving png image of the final result into ' + PATH_OUTPUT +'/Image_results...' if not os.path.isdir(PATH_OUTPUT +'/Image_results'): os.makedirs(PATH_OUTPUT +'/Image_results') f = nibabel.load(PATH_OUTPUT +'/Final_results/'+subject+'_aligned_' + contrast + '.nii.gz') data = f.get_data() nx, ny, nz, nt, px, py, pz, pt = sct.get_dimension(PATH_OUTPUT +'/Final_results/'+subject+'_aligned_' + contrast + '.nii.gz') sagital_middle = nx / 2 coronal_middle = ny / 2 sagittal = data[sagital_middle, :, :].T coronal = data[:, coronal_middle, :].T fig, ax = plt.subplots(1, 2) ax[0].imshow(sagittal, cmap='gray', origin='lower') ax[0].set_title('sagittal') ax[1].imshow(coronal, cmap='gray', origin='lower') ax[1].set_title('coronal') for i in range(2): ax[i].set_axis_off() fig1 = plt.gcf() fig1.savefig(PATH_OUTPUT +'/Image_results'+'/'+subject+'_aligned_' + contrast + '.png', format='png')
def get_orientation_3d(im, filename=False): """ Get orientation from 3D data :param im: :return: """ string_out = 'Input image orientation : ' # get orientation if filename: status, output = sct.run(['isct_orientation3d', '-i', im, '-get'], 0) else: status, output = sct.run( ['isct_orientation3d', '-i', im.absolutepath, '-get'], 0) # check status if status != 0: printv('ERROR in get_orientation.', 1, 'error') orientation = output[output.index(string_out) + len(string_out):] # orientation = output[26:] return orientation
def resample_image(fname, suffix='_resampled.nii.gz', binary=False, npx=0.3, npy=0.3, thr=0.0, interpolation='spline'): """ Resampling function: add a padding, resample, crop the padding :param fname: name of the image file to be resampled :param suffix: suffix added to the original fname after resampling :param binary: boolean, image is binary or not :param npx: new pixel size in the x direction :param npy: new pixel size in the y direction :param thr: if the image is binary, it will be thresholded at thr (default=0) after the resampling :param interpolation: type of interpolation used for the resampling :return: file name after resampling (or original fname if it was already in the correct resolution) """ im_in = Image(fname) orientation = get_orientation(im_in) if orientation != 'RPI': im_in = set_orientation(im_in, 'RPI') im_in.save() fname = im_in.absolutepath nx, ny, nz, nt, px, py, pz, pt = im_in.dim if round(px, 2) != round(npx, 2) or round(py, 2) != round(npy, 2): name_resample = sct.extract_fname(fname)[1] + suffix if binary: interpolation = 'nn' if nz == 1: # when data is 2d: we convert it to a 3d image in order to avoid nipy problem of conversion nifti-->nipy with 2d data sct.run(['sct_image', '-i', ','.join([fname, fname]), '-concat', 'z', '-o', fname]) sct.run(['sct_resample', '-i', fname, '-mm', str(npx) + 'x' + str(npy) + 'x' + str(pz), '-o', name_resample, '-x', interpolation]) if nz == 1: # when input data was 2d: re-convert data 3d-->2d sct.run(['sct_image', '-i', name_resample, '-split', 'z']) im_split = Image(name_resample.split('.nii.gz')[0] + '_Z0000.nii.gz') im_split.setFileName(name_resample) im_split.save() if binary: sct.run(['sct_maths', '-i', name_resample, '-bin', str(thr), '-o', name_resample]) if orientation != 'RPI': im_resample = Image(name_resample) im_resample = set_orientation(im_resample, orientation) im_resample.save() name_resample = im_resample.absolutepath return name_resample else: if orientation != 'RPI': im_in = set_orientation(im_in, orientation) im_in.save() fname = im_in.absolutepath sct.printv('Image resolution already ' + str(npx) + 'x' + str(npy) + 'xpz') return fname
def set_orientation(im, orientation, data_inversion=False, filename=False, fname_out=''): """ Set orientation on image :param im: either Image object or file name. Carefully set param filename. :param orientation: :param data_inversion: :param filename: :return: """ if fname_out: pass elif filename: path, fname, ext = extract_fname(im) fname_out = fname + '_' + orientation + ext else: fname_out = im.file_name + '_' + orientation + im.ext if not data_inversion: from sct_utils import run if filename: run( 'isct_orientation3d -i ' + im + ' -orientation ' + orientation + ' -o ' + fname_out, 0) im_out = fname_out else: fname_in = im.absolutepath if not os.path.exists(fname_in): im.save() run( 'isct_orientation3d -i ' + im.absolutepath + ' -orientation ' + orientation + ' -o ' + fname_out, 0) im_out = Image(fname_out) else: im_out = im.copy() im_out.change_orientation(orientation, True) im_out.setFileName(fname_out) return im_out
def straighten_all_subjects(dataset_info, normalized=False, contrast='t1'): """ This function straighten all images based on template centerline :param dataset_info: dictionary containing dataset information :param normalized: True if images were normalized before straightening :param contrast: {'t1', 't2'} """ path_data = dataset_info['path_data'] path_template = dataset_info['path_template'] list_subjects = dataset_info['subjects'] if normalized: fname_in = contrast + '_norm.nii.gz' fname_out = contrast + '_straight_norm.nii.gz' else: fname_in = contrast + '.nii.gz' fname_out = contrast + '_straight.nii.gz' # straightening of each subject on the new template timer_straightening = sct.Timer(len(list_subjects)) timer_straightening.start() for subject_name in list_subjects: path_data_subject = path_data + subject_name + '/' + contrast + '/' # go to output folder sct.printv('\nStraightening ' + path_data_subject) os.chdir(path_data_subject) sct.run('sct_straighten_spinalcord' ' -i ' + fname_in + ' -s ' + contrast + dataset_info['suffix_centerline'] + '.nii.gz' ' -disks-input ' + contrast + dataset_info['suffix_disks'] + '.nii.gz' ' -ref ' + path_template + 'template_centerline.nii.gz' ' -disks-ref ' + path_template + 'template_disks.nii.gz' ' -disable-straight2curved' ' -param threshold_distance=1', verbose=1) image_straight = Image(sct.add_suffix(fname_in, '_straight')) image_straight.setFileName(fname_out) image_straight.save(type='float32') timer_straightening.add_iteration() timer_straightening.stop()
def compute_contrast(file_data, file_mask1, file_mask2): """ Compute contrast in image between two regions :param file_data: image :param file_mask1: mask for region 1 :param file_mask2: mask for region 2 :return: float: contrast in percent (rounded at 2 decimals) """ print("Compute contrast...") # Get mean value within mask sct.run("sct_extract_metric -i " + file_data + " -f " + file_mask1 + " -method bin -o mean_mask1.pickle") sct.run("sct_extract_metric -i " + file_data + " -f " + file_mask2 + " -method bin -o mean_mask2.pickle") # Retrieve values from saved pickle mean_mask1 = pickle.load(io.open("mean_mask1.pickle"))["Metric value"][0] mean_mask2 = pickle.load(io.open("mean_mask2.pickle"))["Metric value"][0] # Compute contrast in percentage contrast = abs(mean_mask1 - mean_mask2) / min(mean_mask1, mean_mask2) * 100 return round(contrast, 2) # round at 2 decimals
def warp_label(path_label, folder_label, file_label, fname_src, fname_transfo, path_out): """ Warp label files according to info_label.txt file :param path_label: :param folder_label: :param file_label: :param fname_src: :param fname_transfo: :param path_out: :return: """ try: # Read label file template_label_ids, template_label_names, template_label_file, combined_labels_ids, combined_labels_names, \ combined_labels_id_groups, clusters_apriori = \ spinalcordtoolbox.metadata.read_label_file(os.path.join(path_label, folder_label), file_label) except Exception as error: sct.printv( '\nWARNING: Cannot warp label ' + folder_label + ': ' + str(error), 1, 'warning') raise else: # create output folder if not os.path.exists(os.path.join(path_out, folder_label)): os.makedirs(os.path.join(path_out, folder_label)) # Warp label for i in range(0, len(template_label_file)): fname_label = os.path.join(path_label, folder_label, template_label_file[i]) # apply transfo sct.run( 'isct_antsApplyTransforms -d 3 -i %s -r %s -t %s -o %s -n %s' % (fname_label, fname_src, fname_transfo, os.path.join(path_out, folder_label, template_label_file[i]), get_interp(template_label_file[i])), is_sct_binary=True, verbose=param.verbose) # Copy list.txt sct.copy(os.path.join(path_label, folder_label, param.file_info_label), os.path.join(path_out, folder_label))
def straighten_all_subjects(dataset_info, normalized=False, contrast='t1'): """ This function straighten all images based on template centerline :param dataset_info: dictionary containing dataset information :param normalized: True if images were normalized before straightening :param contrast: {'t1', 't2'} """ path_data = dataset_info['path_data'] path_template = dataset_info['path_template'] list_subjects = dataset_info['subjects'] if normalized: fname_in = contrast + '_norm.nii.gz' fname_out = contrast + '_straight_norm.nii.gz' else: fname_in = contrast + '.nii.gz' fname_out = contrast + '_straight.nii.gz' # straightening of each subject on the new template tqdm_bar = tqdm(total=len(list_subjects), unit='B', unit_scale=True, desc="Status", ascii=True) for subject_name in list_subjects: path_data_subject = path_data + subject_name + '/' + contrast + '/' # go to output folder sct.printv('\nStraightening ' + path_data_subject) os.chdir(path_data_subject) if not os.path.isfile(fname_out): sct.run('sct_straighten_spinalcord' ' -i ' + fname_in + ' -s ' + contrast + dataset_info['suffix_centerline'] + '.nii.gz' ' -ldisc_input ' + contrast + dataset_info['suffix_disks'] + '.nii.gz' ' -dest ' + path_template + 'template_centerline.nii.gz' ' -ldisc_dest ' + path_template + 'template_disks.nii.gz' ' -disable-straight2curved' ' -param threshold_distance=1', verbose=1) image_straight = Image(sct.add_suffix(fname_in, '_straight')) image_straight.save(fname_out, dtype='float32') tqdm_bar.update(1) tqdm_bar.close()
def warp_label(path_label, folder_label, file_label, fname_src, fname_transfo, path_out): """ Warp label files according to info_label.txt file :param path_label: :param folder_label: :param file_label: :param fname_src: :param fname_transfo: :param path_out: :return: """ # read label file and check if file exists sct.printv('\nRead label file...', param.verbose) try: template_label_ids, template_label_names, template_label_file, combined_labels_ids, combined_labels_names, combined_labels_id_groups, clusters_apriori = spinalcordtoolbox.metadata.read_label_file( os.path.join(path_label, folder_label), file_label) except Exception as error: sct.printv( '\nWARNING: Cannot warp label ' + folder_label + ': ' + str(error), 1, 'warning') raise else: # create output folder if not os.path.exists(os.path.join(path_out, folder_label)): os.makedirs(os.path.join(path_out, folder_label)) # Warp label for i in range(0, len(template_label_file)): fname_label = os.path.join(path_label, folder_label, template_label_file[i]) # check if file exists # sct.check_file_exist(fname_label) # apply transfo sct.run( 'sct_apply_transfo -i ' + fname_label + ' -o ' + os.path.join(path_out, folder_label, template_label_file[i]) + ' -d ' + fname_src + ' -w ' + fname_transfo + ' -x ' + get_interp(template_label_file[i]), param.verbose) # Copy list.txt sct.copy(os.path.join(path_label, folder_label, param.file_info_label), os.path.join(path_out, folder_label))
def compute_snr_diff(file_data1, file_data2, file_mask): """ Compute SNR based on two input data and a mask :param file_data1: image 1 :param file_data2: image 2 :param file_mask: mask where to compute SNR :return: float: SNR_diff rounded at 2 decimals """ print("Compute SNR_diff...") sct.run("sct_image -i " + file_data1 + "," + file_data2 + " -concat t -o data_concat.nii.gz") status, output = sct.run( "sct_compute_snr -i data_concat.nii.gz -vol 0,1 -m " + file_mask) # parse SNR info # TODO: run sct_compute_snr as Python module try: outstring = output[output.index("SNR_diff =") + 11:] snr_diff = np.float(outstring[:outstring.index("\n")]) except Exception as e: print(e) return round(snr_diff, 2) # round at 2 decimals
def get_version_requirements_pip(): status, path_sct = sct.run('echo $SCT_DIR', 0) file = open(path_sct + "/install/requirements/requirementsPip.txt") dict = {} while True: line = file.readline() if line == "": break # OH GOD HELP arg = line.split("==") dict[arg[0]] = arg[1].rstrip("\n") file.close() return dict
def heatmap2optic(fname_heatmap, lambda_value, fname_out, z_max, algo='dpdt'): """Run OptiC on the heatmap computed by CNN_1.""" import nibabel as nib os.environ["FSLOUTPUTTYPE"] = "NIFTI_PAIR" optic_input = fname_heatmap.split('.nii')[0] cmd_optic = 'isct_spine_detect -ctype="%s" -lambda="%s" "%s" "%s" "%s"' % \ (algo, str(lambda_value), "NONE", optic_input, optic_input) sct.run(cmd_optic, verbose=1) optic_hdr_filename = optic_input + '_ctr.hdr' img = nib.load(optic_hdr_filename) nib.save(img, fname_out) # crop the centerline if z_max < data.shape[2] and -brain == 1 if z_max is not None: sct.printv('Cropping brain section.') ctr_nii = Image(fname_out) ctr_nii.data[:, :, z_max:] = 0 ctr_nii.save()
def scad_propseg_validation(folder_input, contrast): from sct_get_centerline import ind2sub import time import math import numpy import sct_convert as cnv t0 = time.time() current_folder = os.getcwd() os.chdir(folder_input) try: patients = next(os.walk('.'))[1] for i in patients: directory = i + "/" + str(contrast) try: os.chdir(directory) except Exception, e: print str(i)+" : "+contrast+" directory not found" try: if os.path.isfile(i+"_"+contrast+".nii.gz"): raw_image = Image(i+"_"+contrast+".nii.gz") elif os.path.isfile(contrast+".nii.gz"): raw_image = Image(contrast+".nii.gz") else: raise Exception("Patient scan not found") if os.path.isfile(i+"_"+contrast+"_manual_segmentation.nii.gz"): manual_segmentation = i+"_"+contrast+"_manual_segmentation.nii.gz" # Using propseg default sct.run("sct_propseg -i "+raw_image.absolutepath+" -t "+contrast) cnv.convert(raw_image.file_name+"_seg.nii.gz", "propseg_default.nii.gz") # Using scad scad = SCAD(raw_image, contrast=contrast, rm_tmp_file=1, verbose=1) scad.execute() # Using propseg with scad sct.run("sct_propseg -i "+raw_image.absolutepath+" -t "+contrast+" -init-centerline "+scad.output_filename) cnv.convert(raw_image.file_name+"_seg.nii.gz", "propseg_scad.nii.gz") # Calculate dice of propseg_default sct.run("sct_dice_coefficient propseg_default.nii.gz "+manual_segmentation+" -o propseg_default_result.txt") # Calculate dice of propseg_scad sct.run("sct_dice_coefficient propseg_scad.nii.gz "+manual_segmentation+" -o propseg_scad_result.txt") else: printv("Cannot find the manual segmentation", type="warning") except Exception, e: print e.message os.chdir(folder_input)
def make_labels_image_from_list_points(mask_points,reoriented_image_filename,image_input_orientation): if check_mask_point_not_empty(mask_points): import sct_image # create the mask containing either the three-points or centerline mask for initialization sct.run("sct_label_utils -i " + reoriented_image_filename + " -create " + mask_points ,verbose=False) sct.run('sct_image -i ' + 'labels.nii.gz'+ ' -o ' + 'labels_ground_truth.nii.gz' + ' -setorient ' + image_input_orientation + ' -v 0',verbose=False) sct.run('rm -rf ' + 'labels.nii.gz')
def main(): # params # Old atlas created from the registration of all slices to the reference slice # folder_in = '/home/django/cnaaman/data/data_marc/WMtracts_outputstest/final_results/' # path of atlas # New atlas created from the registration of all slices to the adjacent slice #folder_in = '/home/django/cnaaman/data/data_marc/WMtracts_outputsc_julien/final_results/' #folder_out = '/home/django/cnaaman/code/stage/cropped_atlas/' verbose = 1 #zind = 10,110,210,310,410 try: opts, args = getopt.getopt(sys.argv[1:], 'hf:o:z:') # define flag except getopt.GetoptError as err: # check if the arguments are defined print str(err) # error usage() for opt, arg in opts: if opt == '-h': usage() if opt == '-f': folder_in = str(arg) if opt == '-o': folder_out = str(arg) if opt == '-z': zind = arg zind = zind.split(',') # create output folder if os.path.exists(folder_out): sct.printv('WARNING: Output folder already exists. Deleting it...', verbose) sct.run('rm -rf '+folder_out) sct.run('mkdir '+folder_out) # get atlas files status, output = sct.run('ls '+folder_in+'*.nii.gz', verbose) fname_list = output.split() # loop across atlas for i in xrange(0, len(fname_list)): path_list, file_list, ext_list = sct.extract_fname(fname_list[i]) crop_file(fname_list[i], folder_out, zind)
def run_crop(fname_in, fname_out, nb_slice_average=1.0): img = Image(fname_in).change_orientation('RPI') if len(list(np.where(img.data == 3)[2])) == 1: # if label file x_start, x_end = str(np.where(img.data == 3)[0][0]), str( np.where(img.data == 3)[0][0]) nb_slice_average_each_side = 0 img.data[np.where(img.data != 3)] = 0 img.data[np.where(img.data == 3)] = 1 img.change_orientation('PIR') img.save(fname_out) del img else: # if grayscale image file x_med = int(np.rint(img.dim[0] * 1.0 / 2)) nb_slice_average_each_side = int(nb_slice_average / 2 / img.dim[4]) x_start, x_end = str(x_med - nb_slice_average_each_side), str( x_med + nb_slice_average_each_side) del img cmd_orient = [ 'sct_image', '-i', fname_in, '-setorient', 'PIR', '-o', fname_out ] sct.run(cmd_orient) cmd_crop = [ 'sct_crop_image', '-i', fname_out, '-zmin', x_start, '-zmax', x_end, '-o', fname_out ] sct.run(cmd_crop) if nb_slice_average_each_side: cmd_mean = [ 'sct_maths', '-i', fname_out, '-mean', 'z', '-o', fname_out ] sct.run(cmd_mean)
def clean_labeled_segmentation(fname_labeled_seg, fname_seg, fname_labeled_seg_new): """ Clean labeled segmentation by: (i) removing voxels in segmentation_labeled that are not in segmentation and (ii) adding voxels in segmentation that are not in segmentation_labeled :param fname_labeled_seg: :param fname_seg: :param fname_labeled_seg_new: output :return: none """ # remove voxels in segmentation_labeled that are not in segmentation sct.run('sct_maths -i ' + fname_labeled_seg + ' -mul ' + fname_seg + ' -o segmentation_labeled_mul.nii.gz') # add voxels in segmentation that are not in segmentation_labeled sct.run('sct_maths -i ' + fname_labeled_seg + ' -dilate 2 -o segmentation_labeled_dilate.nii.gz' ) # dilate labeled segmentation data_label_dilate = Image('segmentation_labeled_dilate.nii.gz').data sct.run( 'sct_maths -i segmentation_labeled_mul.nii.gz -bin 0 -o segmentation_labeled_mul_bin.nii.gz' ) data_label_bin = Image('segmentation_labeled_mul_bin.nii.gz').data data_seg = Image(fname_seg).data data_diff = data_seg - data_label_bin ind_nonzero = np.where(data_diff) im_label = Image('segmentation_labeled_mul.nii.gz') for i_vox in range(len(ind_nonzero[0])): # assign closest label value for this voxel ix, iy, iz = ind_nonzero[0][i_vox], ind_nonzero[1][i_vox], ind_nonzero[ 2][i_vox] im_label.data[ix, iy, iz] = data_label_dilate[ix, iy, iz] # save new label file (overwrite) im_label.setFileName(fname_labeled_seg_new) im_label.save()
def getSize(x, y, z, file_name=None): from math import sqrt # get pixdim if file_name is not None: cmd1 = ['fslval', file_name, 'pixdim1'] status, output = sct.run(cmd1) p1 = float(output) cmd2 = ['fslval', file_name, 'pixdim2'] status, output = sct.run(cmd2) p2 = float(output) cmd3 = ['fslval', file_name, 'pixdim3'] status, output = sct.run(cmd3) p3 = float(output) else: p1, p2, p3 = 1.0, 1.0, 1.0 # Centerline size s = 0 for i in range(len(x) - 1): s += sqrt((p1 * (x[i + 1] - x[i]))**2 + (p2 * (y[i + 1] - y[i]))**2 + (p3 * (z[i + 1] - z[i])**2)) # sct.printv("centerline size: ", s) return s
def main(input_anatomy_file, list_files, param, remove_temp_files=1, verbose=0): path, file, ext = sct.extract_fname(input_anatomy_file) # Image denoising print '\nDenoising image ' + input_anatomy_file + '...' sct.run('sct_denoising_onlm.py -i ' + input_anatomy_file + ' -p ' + type_noise + ' -r ' + str(remove_temp_files) + ' -v ' + str(verbose)) # Extract and fit centerline list_name_files = list_files[0] for i in range(1, len(list_files)): list_name_files = list_name_files + ',' + list_files[i] print '\nExtracting and fitting centerline...' sct.run('sct_get_centerline_from_labels -i ' + list_name_files + ' -r ' + str(remove_temp_files) + ' -v ' + str(verbose)) # Straighten the image using the fitted centerline print '\nStraightening the image ' + input_anatomy_file + ' using the fitted centerline ' + 'generated_centerline.nii.gz' + ' ...' sct.run('sct_straighten_spinalcord -i ' + input_anatomy_file + ' -c ' + 'generated_centerline.nii.gz' + ' -r ' + str(remove_temp_files) + ' -v ' + str(verbose)) output_straighten_name = file + '_straight' + ext # Aplly transfo to the centerline print '\nApplying transformation to the centerline...' sct.run('sct_apply_transfo -i ' + 'generated_centerline.nii.gz' + ' -d ' + output_straighten_name + ' -w ' + 'warp_curve2straight.nii.gz' + ' -x ' + 'linear' + ' -v ' + str(verbose)) # Normalize intensity of the image using the straightened centerline print '\nNormalizing intensity of the straightened image...' sct.run('sct_normalize.py -i ' + output_straighten_name + ' -c generated_centerline_reg.nii.gz' + ' -v ' + str(verbose))
def train_model(df, model_name): sct.printv("Training...") train_txt = 'train_lst.txt' train_gt_txt = 'train_gt_lst.txt' if os.path.isfile(train_txt) or os.path.isfile(train_gt_txt): sct.rm(train_txt) sct.rm(train_gt_txt) stg_train = '\n'.join([os.path.abspath(f).split('.nii')[0] for f in df['train'].values if str(f) != 'nan']) stg_gt_train = '\n'.join([os.path.abspath(f).split('.nii')[0] for f in df['gt'].values if str(f) != 'nan']) with open(train_txt, 'w') as text_file: text_file.write(stg_train) text_file.close() with open(train_gt_txt, 'w') as text_file: text_file.write(stg_gt_train) text_file.close() model_path = os.getcwd() + '/trained_model_t1.yml' if os.path.isfile(model_path): sct.rm(model_path) cmd_train = 'isct_train_svm -hogsg -incr=20 ' + model_name + ' ' + train_txt + ' ' + train_gt_txt + ' --list True' sct.run(cmd_train, verbose=0, raise_exception=False)
def crop_im(fname_im, fname_mask): fname_im_crop = sct.add_suffix(fname_im, '_crop') status, output_crop = sct.run(['sct_crop_image', '-i', fname_im, '-m', fname_mask, '-o', fname_im_crop]) output_list = output_crop.split('\n') xi, xf, yi, yf, zi, zf = 0, 0, 0, 0, 0, 0 for line in output_list: if 'Dimension 0' in line: dim, i, xi, xf = line.split(' ') if 'Dimension 1' in line: dim, i, yi, yf = line.split(' ') if 'Dimension 2' in line: dim, i, zi, zf = line.split(' ') return fname_im_crop, int(xi), int(xf), int(yi), int(yf), int(zi), int(zf)
def visualize_warp(fname_warp, fname_grid=None, step=3, rm_tmp=True): if fname_grid is None: from numpy import zeros tmp_dir = sct.tmp_create() im_warp = Image(fname_warp) curdir = os.getcwd() os.chdir(tmp_dir) assert len(im_warp.data.shape) == 5, 'ERROR: Warping field does bot have 5 dimensions...' nx, ny, nz, nt, ndimwarp = im_warp.data.shape # nx, ny, nz, nt, px, py, pz, pt = im_warp.dim # This does not work because dimensions of a warping field are not correctly read : it would be 1,1,1,1,1,1,1,1 sq = zeros((step, step)) sq[step - 1] = 1 sq[:, step - 1] = 1 dat = zeros((nx, ny, nz)) for i in range(0, dat.shape[0], step): for j in range(0, dat.shape[1], step): for k in range(dat.shape[2]): if dat[i:i + step, j:j + step, k].shape == (step, step): dat[i:i + step, j:j + step, k] = sq fname_grid = 'grid_' + str(step) + '.nii.gz' im_grid = Image(param=dat) grid_hdr = im_warp.hdr im_grid.hdr = grid_hdr im_grid.setFileName(fname_grid) im_grid.save() fname_grid_resample = sct.add_suffix(fname_grid, '_resample') sct.run(['sct_resample', '-i', fname_grid, '-f', '3x3x1', '-x', 'nn', '-o', fname_grid_resample]) fname_grid = os.path.join(tmp_dir, fname_grid_resample) os.chdir(curdir) path_warp, file_warp, ext_warp = sct.extract_fname(fname_warp) grid_warped = os.path.join(path_warp, 'grid_warped_gm' + ext_warp) sct.run(['sct_apply_transfo', '-i', fname_grid, '-d', fname_grid, '-w', fname_warp, '-o', grid_warped]) if rm_tmp: sct.rmtree(tmp_dir) return grid_warped
def compute_mean_csa(z_dct): csa_lst_lst = [] for img_fold, z_min, z_max in zip(z_dct['img_fold_path'], z_dct['z_min'], z_dct['z_max']): csa_pickle = os.path.join(img_fold, 'csa', 'csa_per_slice.pickle') if not os.path.isfile(csa_pickle): sc_path = os.path.join( img_fold, img_fold.split('/')[-1] + '_seg_manual.nii.gz') sct.run([ 'sct_process_segmentation', '-i', sc_path, '-p', 'csa', '-ofolder', os.path.join(img_fold, 'csa') ]) csa_pd = pd.read_pickle(csa_pickle) csa_lst = csa_pd[csa_pd['Slice (z)'].isin(range( z_min, z_max + 1))]['CSA (mm^2)'].values csa_lst_lst.append(csa_lst) return np.mean([csa for sublst in csa_lst_lst for csa in sublst])
def visualize_warp(fname_warp, fname_grid=None, step=3, rm_tmp=True): if fname_grid is None: from numpy import zeros tmp_dir = sct.tmp_create() im_warp = Image(fname_warp) status, out = sct.run(['fslhd', fname_warp]) curdir = os.getcwd() os.chdir(tmp_dir) dim1 = 'dim1 ' dim2 = 'dim2 ' dim3 = 'dim3 ' nx = int(out[out.find(dim1):][len(dim1):out[out.find(dim1):].find('\n')]) ny = int(out[out.find(dim2):][len(dim2):out[out.find(dim2):].find('\n')]) nz = int(out[out.find(dim3):][len(dim3):out[out.find(dim3):].find('\n')]) sq = zeros((step, step)) sq[step - 1] = 1 sq[:, step - 1] = 1 dat = zeros((nx, ny, nz)) for i in range(0, dat.shape[0], step): for j in range(0, dat.shape[1], step): for k in range(dat.shape[2]): if dat[i:i + step, j:j + step, k].shape == (step, step): dat[i:i + step, j:j + step, k] = sq fname_grid = 'grid_' + str(step) + '.nii.gz' im_grid = Image(param=dat) grid_hdr = im_warp.hdr im_grid.hdr = grid_hdr im_grid.absolutepath = fname_grid im_grid.save() fname_grid_resample = sct.add_suffix(fname_grid, '_resample') sct.run(['sct_resample', '-i', fname_grid, '-f', '3x3x1', '-x', 'nn', '-o', fname_grid_resample]) fname_grid = os.path.join(tmp_dir, fname_grid_resample) os.chdir(curdir) path_warp, file_warp, ext_warp = sct.extract_fname(fname_warp) grid_warped = os.path.join(path_warp, sct.extract_fname(fname_grid)[1] + '_' + file_warp + ext_warp) sct.run(['sct_apply_transfo', '-i', fname_grid, '-d', fname_grid, '-w', fname_warp, '-o', grid_warped]) if rm_tmp: sct.rmtree(tmp_dir)
def resample_labels(fname_labels, fname_dest, fname_output): """ This function re-create labels into a space that has been resampled. It works by re-defining the location of each label using the old and new voxel size. """ # get dimensions of input and destination files nx, ny, nz, nt, px, py, pz, pt = Image(fname_labels).dim nxd, nyd, nzd, ntd, pxd, pyd, pzd, ptd = Image(fname_dest).dim sampling_factor = [float(nx) / nxd, float(ny) / nyd, float(nz) / nzd] # read labels from sct_label_utils import ProcessLabels processor = ProcessLabels(fname_labels) label_list = processor.display_voxel() label_new_list = [] for label in label_list: label_sub_new = [str(int(round(int(label.x) / sampling_factor[0]))), str(int(round(int(label.y) / sampling_factor[1]))), str(int(round(int(label.z) / sampling_factor[2]))), str(int(float(label.value)))] label_new_list.append(','.join(label_sub_new)) label_new_list = ':'.join(label_new_list) # create new labels sct.run('sct_label_utils -i ' + fname_dest + ' -create ' + label_new_list + ' -v 1 -o ' + fname_output)
def resample_labels(fname_labels, fname_dest, fname_output): """ This function re-create labels into a space that has been resampled. It works by re-defining the location of each label using the old and new voxel size. IMPORTANT: this function assumes that the origin and FOV of the two images are the SAME. """ # get dimensions of input and destination files nx, ny, nz, nt, px, py, pz, pt = Image(fname_labels).dim nxd, nyd, nzd, ntd, pxd, pyd, pzd, ptd = Image(fname_dest).dim sampling_factor = [float(nx) / nxd, float(ny) / nyd, float(nz) / nzd] # read labels processor = sct_label_utils.ProcessLabels(fname_labels) label_list = processor.display_voxel() label_new_list = [] for label in label_list: label_sub_new = [str(int(np.round(int(label.x) / sampling_factor[0]))), str(int(np.round(int(label.y) / sampling_factor[1]))), str(int(np.round(int(label.z) / sampling_factor[2]))), str(int(float(label.value)))] label_new_list.append(','.join(label_sub_new)) label_new_list = ':'.join(label_new_list) # create new labels sct.run(['sct_label_utils', '-i', fname_dest, '-create', label_new_list, '-v', '1', '-o', fname_output])