def __init__(self, fname_im, contrast, fname_seg, path_out, verbose): self.fname_im = fname_im self.contrast = contrast self.fname_seg = fname_seg self.path_out = path_out self.verbose = verbose self.tmp_dir = sct.tmp_create(verbose=self.verbose) # path to tmp directory self.orientation_im = Image(self.fname_im).orientation # to re-orient the data at the end self.slice2D_im = sct.extract_fname(self.fname_im)[1] + '_midSag.nii' # file used to do the detection, with only one slice self.dection_map_pmj = sct.extract_fname(self.fname_im)[1] + '_map_pmj' # file resulting from the detection # path to the pmj detector self.pmj_model = os.path.join(sct.__data_dir__, 'pmj_models', '{}_model'.format(self.contrast)) self.threshold = -0.75 if self.contrast == 't1' else 0.8 # detection map threshold, depends on the contrast self.fname_out = sct.extract_fname(self.fname_im)[1] + '_pmj.nii.gz' self.fname_qc = 'qc_pmj.png'
def post_processing(self): square_mask = Image(self.preprocessed.square_mask) tmp_res_names = [] for res_im in [self.gm_seg.res_wm_seg, self.gm_seg.res_gm_seg, self.gm_seg.corrected_wm_seg]: res_im_original_space = inverse_square_crop(res_im, square_mask) res_im_original_space.save() res_im_original_space = set_orientation(res_im_original_space, self.preprocessed.original_orientation) res_im_original_space.save() res_fname_original_space = res_im_original_space.file_name ext = res_im_original_space.ext # crop from the same pad size output_crop = res_fname_original_space+'_crop' sct.run('sct_crop_image -i '+res_fname_original_space+ext+' -dim 0,1,2 -start '+self.preprocessed.pad[0]+','+self.preprocessed.pad[1]+','+self.preprocessed.pad[2]+' -end -'+self.preprocessed.pad[0]+',-'+self.preprocessed.pad[1]+',-'+self.preprocessed.pad[2]+' -o '+output_crop+ext) res_fname_original_space = output_crop target_path, target_name, target_ext = sct.extract_fname(self.target_fname) res_name = target_name + res_im.file_name[len(sct.extract_fname(self.preprocessed.processed_target)[1]):] + '.nii.gz' if self.seg_param.res_type == 'binary': bin = True else: bin = False old_res_name = resample_image(res_fname_original_space+ext, npx=self.preprocessed.original_px, npy=self.preprocessed.original_py, binary=bin) if self.seg_param.res_type == 'prob': # sct.run('fslmaths ' + old_res_name + ' -thr 0.05 ' + old_res_name) sct.run('sct_maths -i ' + old_res_name + ' -thr 0.05 -o ' + old_res_name) sct.run('cp ' + old_res_name + ' '+res_name) tmp_res_names.append(res_name) self.res_names['wm_seg'] = tmp_res_names[0] self.res_names['gm_seg'] = tmp_res_names[1] self.res_names['corrected_wm_seg'] = tmp_res_names[2]
def orient2pir(self): """Orient input data to PIR orientation.""" if self.orientation_im != 'PIR': # open image and re-orient it to PIR if needed Image(self.fname_im).change_orientation("PIR").save(''.join(sct.extract_fname(self.fname_im)[1:])) if self.fname_seg is not None: Image(self.fname_seg).change_orientation('PIR').save(''.join(sct.extract_fname(self.fname_seg)[1:]))
def ifolder2tmp(self): # copy input image if self.fname_mask is not None: sct.copy(self.fname_mask, self.tmp_dir) self.fname_mask = ''.join(extract_fname(self.fname_mask)[1:]) else: printv('ERROR: No input image', self.verbose, 'error') # copy seg image if self.fname_sc is not None: sct.copy(self.fname_sc, self.tmp_dir) self.fname_sc = ''.join(extract_fname(self.fname_sc)[1:]) # copy ref image if self.fname_ref is not None: sct.copy(self.fname_ref, self.tmp_dir) self.fname_ref = ''.join(extract_fname(self.fname_ref)[1:]) # copy registered template if self.path_template is not None: sct.copy(self.path_levels, self.tmp_dir) self.path_levels = ''.join(extract_fname(self.path_levels)[1:]) self.atlas_roi_lst = [] for fname_atlas_roi in os.listdir(self.path_atlas): if fname_atlas_roi.endswith('.nii.gz'): tract_id = int(fname_atlas_roi.split('_')[-1].split('.nii.gz')[0]) if tract_id < 36: # Not interested in CSF sct.copy(os.path.join(self.path_atlas, fname_atlas_roi), self.tmp_dir) self.atlas_roi_lst.append(fname_atlas_roi) os.chdir(self.tmp_dir) # go to tmp directory
def register_data(im_src, im_dest, param_reg, path_copy_warp=None, rm_tmp=True): ''' Parameters ---------- im_src: class Image: source image im_dest: class Image: destination image param_reg: str: registration parameter path_copy_warp: path: path to copy the warping fields Returns: im_src_reg: class Image: source image registered on destination image ------- ''' # im_src and im_dest are already preprocessed (in theory: im_dest = mean_image) # binarize images to get seg im_src_seg = binarize(im_src, thr_min=1, thr_max=1) im_dest_seg = binarize(im_dest) # create tmp dir and go in it tmp_dir = tmp_create() os.chdir(tmp_dir) # save image and seg fname_src = 'src.nii.gz' im_src.setFileName(fname_src) im_src.save() fname_src_seg = 'src_seg.nii.gz' im_src_seg.setFileName(fname_src_seg) im_src_seg.save() fname_dest = 'dest.nii.gz' im_dest.setFileName(fname_dest) im_dest.save() fname_dest_seg = 'dest_seg.nii.gz' im_dest_seg.setFileName(fname_dest_seg) im_dest_seg.save() # do registration using param_reg sct_register_multimodal.main(args=['-i', fname_src, '-d', fname_dest, '-iseg', fname_src_seg, '-dseg', fname_dest_seg, '-param', param_reg]) # get registration result fname_src_reg = add_suffix(fname_src, '_reg') im_src_reg = Image(fname_src_reg) # get out of tmp dir os.chdir('..') # copy warping fields if path_copy_warp is not None and os.path.isdir(os.path.abspath(path_copy_warp)): path_copy_warp = os.path.abspath(path_copy_warp) file_src = extract_fname(fname_src)[1] file_dest = extract_fname(fname_dest)[1] fname_src2dest = 'warp_' + file_src +'2' + file_dest +'.nii.gz' fname_dest2src = 'warp_' + file_dest +'2' + file_src +'.nii.gz' shutil.copy(tmp_dir +'/' + fname_src2dest, path_copy_warp + '/') shutil.copy(tmp_dir + '/' + fname_dest2src, path_copy_warp + '/') if rm_tmp: # remove tmp dir shutil.rmtree(tmp_dir) # return res image return im_src_reg, fname_src2dest, fname_dest2src
def niigz2volviewer(fname_data,fname_out): print "Converting from nifti to volume viewer" path_in, file_in, ext_in = sct.extract_fname(fname_data) path_out, file_out, ext_out = sct.extract_fname(fname_out) fname_data_mnc = path_out+"tmp."+file_out+'.mnc' niigz2mnc(fname_data,fname_data_mnc) mnc2volviewer(fname_data_mnc,path_out+file_out)
def _measure_within_im(self, im_lesion, im_ref, label_lst): printv('\nCompute reference image features...', self.verbose, 'normal') for lesion_label in label_lst: im_label_data_cur = im_lesion == lesion_label im_label_data_cur[np.where(im_ref == 0)] = 0 # if the ref object is eroded compared to the labeled object mean_cur, std_cur = np.mean(im_ref[np.where(im_label_data_cur)]), np.std(im_ref[np.where(im_label_data_cur)]) label_idx = self.measure_pd[self.measure_pd.label == lesion_label].index self.measure_pd.loc[label_idx, 'mean_' + extract_fname(self.fname_ref)[1]] = mean_cur self.measure_pd.loc[label_idx, 'std_' + extract_fname(self.fname_ref)[1]] = std_cur printv('Mean+/-std of lesion #' + str(lesion_label) + ' in ' + extract_fname(self.fname_ref)[1] + ' file: ' + str(np.round(mean_cur, 2)) + '+/-' + str(np.round(std_cur, 2)), self.verbose, type='info')
def __init__(self, fname_mask, fname_sc, fname_ref, path_template, path_ofolder, verbose): self.fname_mask = fname_mask self.fname_sc = fname_sc self.fname_ref = fname_ref self.path_template = path_template self.path_ofolder = path_ofolder self.verbose = verbose self.wrk_dir = os.getcwd() if not set(np.unique(Image(fname_mask).data)) == set([0.0, 1.0]): if set(np.unique(Image(fname_mask).data)) == set([0.0]): printv('WARNING: Empty masked image', self.verbose, 'warning') else: printv("ERROR input file %s is not binary file with 0 and 1 values" % fname_mask, 1, 'error') # create tmp directory self.tmp_dir = tmp_create(verbose=verbose) # path to tmp directory # lesion file where each lesion has a different value self.fname_label = extract_fname(self.fname_mask)[1] + '_label' + extract_fname(self.fname_mask)[2] # initialization of measure sheet measure_lst = ['label', 'volume [mm3]', 'length [mm]', 'max_equivalent_diameter [mm]'] if self.fname_ref is not None: for measure in ['mean', 'std']: measure_lst.append(measure + '_' + extract_fname(self.fname_ref)[1]) measure_dct = {} for column in measure_lst: measure_dct[column] = None self.measure_pd = pd.DataFrame(data=measure_dct, index=range(0), columns=measure_lst) # orientation of the input image self.orientation = None # volume object self.volumes = None # initialization of proportion measures, related to registrated atlas if self.path_template is not None: self.path_atlas = os.path.join(self.path_template, "atlas") self.path_levels = os.path.join(self.path_template, "template", "PAM50_levels.nii.gz") else: self.path_atlas, self.path_levels = None, None self.vert_lst = None self.atlas_roi_lst = None self.distrib_matrix_dct = {} # output names self.pickle_name = extract_fname(self.fname_mask)[1] + '_analyzis.pkl' self.excel_name = extract_fname(self.fname_mask)[1] + '_analyzis.xls'
def __init__(self, target_fname, sc_seg_fname, t2_data, level_fname, ref_gm_seg=None, model=None, param=None): before = time.time() self.param = param sct.printv('\nBuilding the appearance model...', verbose=self.param.verbose, type='normal') if model is None: self.model = Model(model_param=self.param, k=0.8) else: self.model = model sct.printv('\n--> OK !', verbose=self.param.verbose, type='normal') self.target_fname = check_file_to_niigz(target_fname) self.sc_seg_fname = check_file_to_niigz(sc_seg_fname) self.t2_data = t2_data self.ref_gm_seg_fname = ref_gm_seg self.tmp_dir = 'tmp_' + sct.extract_fname(self.target_fname)[1] + '_' + time.strftime("%y%m%d%H%M%S") sct.run('mkdir ' + self.tmp_dir) os.chdir(self.tmp_dir) self.level_to_use = None if level_fname is not None: t2_data = None if check_file_to_niigz('../' + level_fname): sct.run('cp ../' + level_fname + ' .') level_fname = sct.extract_fname(level_fname)[1]+sct.extract_fname(level_fname)[2] sct.run('sct_orientation -i ' + level_fname + ' -s IRP') self.level_to_use = sct.extract_fname(level_fname)[1] + '_IRP.nii.gz' else: self.level_to_use = level_fname self.gm_seg = None self.res_names = {} self.dice_name = None self.hausdorff_name = None self.segmentation_pipeline() os.chdir('..') after = time.time() sct.printv('Done! (in ' + str(after-before) + ' sec) \nTo see the result, type :') if self.param.res_type == 'binary': wm_col = 'Red' gm_col = 'Blue' b = '0,1' else: wm_col = 'Blue-Lightblue' gm_col = 'Red-Yellow' b = '0.5,1' sct.printv('fslview ' + self.target_fname + ' -b 0,700 ' + self.res_names['wm_seg'] + ' -l ' + wm_col + ' -t 0.4 -b ' + b + ' ' + self.res_names['gm_seg'] + ' -l ' + gm_col + ' -t 0.4 -b ' + b + ' &', param.verbose, 'info')
def ifolder2tmp(self): """Copy data to tmp folder.""" if self.fname_im is not None: # copy input image sct.copy(self.fname_im, self.tmp_dir) self.fname_im = ''.join(sct.extract_fname(self.fname_im)[1:]) else: sct.printv('ERROR: No input image', self.verbose, 'error') if self.fname_seg is not None: # copy segmentation image sct.copy(self.fname_seg, self.tmp_dir) self.fname_seg = ''.join(sct.extract_fname(self.fname_seg)[1:]) self.curdir = os.getcwd() os.chdir(self.tmp_dir) # go to tmp directory
def __init__(self, param=None, hdr=None, orientation=None, absolutepath="", verbose=1): from numpy import zeros, ndarray, generic from sct_utils import extract_fname from nibabel import AnalyzeHeader # initialization of all parameters self.verbose = verbose self.data = None self.absolutepath = "" self.path = "" self.file_name = "" self.ext = "" self.orientation = None if hdr == None: hdr = AnalyzeHeader() self.hdr = AnalyzeHeader() # an empty header else: self.hdr = hdr self.dim = None self.verbose = verbose # load an image from file if type(param) is str: self.loadFromPath(param, verbose) # copy constructor elif isinstance(param, type(self)): self.copy(param) # create an empty image (full of zero) of dimension [dim]. dim must be [x,y,z] or (x,y,z). No header. elif type(param) is list: self.data = zeros(param) self.dim = param self.hdr = hdr self.orientation = orientation self.absolutepath = absolutepath self.path, self.file_name, self.ext = extract_fname(absolutepath) # create a copy of im_ref elif isinstance(param, (ndarray, generic)): self.data = param self.dim = self.data.shape self.hdr = hdr self.orientation = orientation self.absolutepath = absolutepath self.path, self.file_name, self.ext = extract_fname(absolutepath) else: raise TypeError(" Image constructor takes at least one argument.")
def main(args=None): # check user arguments if not args: args = sys.argv[1:] # Get parser info parser = get_parser() arguments = parser.parse(sys.argv[1:]) fname_in = arguments["-i"] fname_seg = arguments['-seg'] contrast = arguments['-t'] if '-o' in arguments: fname_out = arguments["-o"] else: fname_out = '' param.verbose = int(arguments['-v']) # Build fname_out if fname_out == '': path_in, file_in, ext_in = extract_fname(fname_in) fname_out = path_in+file_in+'_mean'+ext_in # detect vertebral levels vertebral_detection(fname_in, fname_seg, contrast)
def init(param_test): """ Initialize class: param_test """ # initialization param_test.folder_data = ['mt/', 't2/', 'dmri/'] param_test.file_data = ['mtr.nii.gz', 't2.nii.gz', 'dmri.nii.gz'] # test padding param_test.pad = 2 # test concatenation of data path_fname, file_fname, ext_fname = sct.extract_fname(param_test.file_data[2]) param_test.dmri_t_slices = [os.path.join(param_test.folder_data[2], file_fname + '_T' + str(i).zfill(4) + ext_fname) for i in range(7)] input_concat = ','.join(param_test.dmri_t_slices) default_args = ['-i ' + os.path.join(param_test.folder_data[0], param_test.file_data[0]) + ' -o test.nii.gz' + ' -pad 0,0,'+str(param_test.pad), '-i ' + os.path.join(param_test.folder_data[1], param_test.file_data[1]) + ' -getorient', # 3D '-i ' + os.path.join(param_test.folder_data[2], param_test.file_data[2]) + ' -getorient', # 4D '-i ' + os.path.join(param_test.folder_data[2], param_test.file_data[2]) + ' -split t -o dmri.nii.gz', '-i ' + input_concat + ' -concat t -o dmri_concat.nii.gz'] # assign default params if not param_test.args: param_test.args = default_args return param_test
def main(args = None): dim_list = ['x', 'y', 'z', 't'] if not args: args = sys.argv[1:] # Get parser info parser = get_parser() arguments = parser.parse(sys.argv[1:]) fname_in = arguments["-i"] fname_out = arguments["-o"] verbose = int(arguments['-v']) # Build fname_out if fname_out == '': path_in, file_in, ext_in = extract_fname(fname_in) fname_out = path_in+file_in+'_mean'+ext_in # Open file. nii = Image(fname_in) data = nii.data # run command if '-otsu' in arguments: param = arguments['-otsu'] data_out = otsu(data, param) elif '-otsu_adap' in arguments: param = arguments['-otsu_adap'] data_out = otsu_adap(data, param[0], param[1]) elif '-otsu_median' in arguments: param = arguments['-otsu_median'] data_out = otsu_median(data, param[0], param[1]) elif '-thr' in arguments: param = arguments['-thr'] data_out = threshold(data, param) elif '-percent' in arguments: param = arguments['-percent'] data_out = perc(data, param) elif '-mean' in arguments: dim = dim_list.index(arguments['-mean']) data_out = compute_mean(data, dim) elif '-std' in arguments: dim = dim_list.index(arguments['-std']) data_out = compute_std(data, dim) elif '-dilate' in arguments: data_out = dilate(data, arguments['-dilate']) elif '-erode' in arguments: data_out = erode(data, arguments['-dilate']) else: printv('No process applied.', 1, 'warning') return # Write output nii.data = data_out nii.setFileName(fname_out) nii.save() # display message printv('Created file:\n--> '+fname_out+'\n', verbose, 'info')
def post_treatments(self): square_mask = Image(self.pretreat.square_mask) tmp_res_names = [] for res_im in [self.gm_seg.res_wm_seg, self.gm_seg.res_gm_seg, self.gm_seg.corrected_wm_seg]: res_im_original_space = inverse_square_crop(res_im, square_mask) res_im_original_space.save() sct.run("sct_orientation -i " + res_im_original_space.file_name + ".nii.gz -s RPI") res_name = ( sct.extract_fname(self.target_fname)[1] + res_im.file_name[len(self.pretreat.treated_target[:-7]) :] + ".nii.gz" ) if self.param.res_type == "binary": bin = True else: bin = False old_res_name = resample_image( res_im_original_space.file_name + "_RPI.nii.gz", npx=self.pretreat.original_px, npy=self.pretreat.original_py, binary=bin, ) if self.param.res_type == "prob": sct.run("fslmaths " + old_res_name + " -thr 0.05 " + old_res_name) sct.run("cp " + old_res_name + " ../" + res_name) tmp_res_names.append(res_name) self.res_names["wm_seg"] = tmp_res_names[0] self.res_names["gm_seg"] = tmp_res_names[1] self.res_names["corrected_wm_seg"] = tmp_res_names[2]
def apply_transfo(im_src, im_dest, warp, interp='spline', rm_tmp=True): # create tmp dir and go in it tmp_dir = tmp_create() # copy warping field to tmp dir shutil.copy(warp, tmp_dir) warp = ''.join(extract_fname(warp)[1:]) # go to tmp dir os.chdir(tmp_dir) # save image and seg fname_src = 'src.nii.gz' im_src.setFileName(fname_src) im_src.save() fname_dest = 'dest.nii.gz' im_dest.setFileName(fname_dest) im_dest.save() # apply warping field fname_src_reg = add_suffix(fname_src, '_reg') sct_apply_transfo.main(args=['-i', fname_src, '-d', fname_dest, '-w', warp, '-x', interp]) im_src_reg = Image(fname_src_reg) # get out of tmp dir os.chdir('..') if rm_tmp: # remove tmp dir shutil.rmtree(tmp_dir) # return res image return im_src_reg
def reg_multimodal_warp(anat, target, anat_seg, target_seg, warp_template2anat, param): status, output = sct.run('sct_register_multimodal -i '+anat+' -d '+target+' -iseg '+anat_seg+' -dseg '+target_seg+' -p '+param.p) if status != 0: sct.printv('WARNING: an error occurred ...', verbose, 'warning') sct.printv(output, verbose, 'normal') return None else: warp_template2target = 'warp_template2target.nii.gz' warp_anat2target = 'warp_'+sct.extract_fname(anat)[1]+'2'+sct.extract_fname(target)[1]+'.nii.gz' warp_target2anat = 'warp_'+sct.extract_fname(target)[1]+'2'+sct.extract_fname(anat)[1]+'.nii.gz' sct.run('sct_concat_transfo -w '+warp_template2anat+','+warp_anat2target+' -d '+target+' -o '+warp_template2target) sct.run('sct_warp_template -d '+target+' -w '+warp_template2target) label_folder = 'label_original_reg' sct.run('mv label/ '+label_folder) return warp_anat2target, warp_target2anat, label_folder
def split_data(fname_in, dim, suffix): """ Split data :param fname_in: input file. :param dim: dimension: 0, 1, 2, 3. :return: True/False """ # Parse file name path_in, file_in, ext_in = extract_fname(fname_in) # Open first file. im = Image(fname_in) data = im.data if dim+1 > len(shape(data)): # in case input volume is 3d and dim=t data = data[..., newaxis] # Split data into list data_split = array_split(data, data.shape[dim], dim) # Write each file for i in range(len(data_split)): # Build suffix suffix_output = suffix+str(i).zfill(4) # Write file im_split = im im_split.data = data_split[i] im_split.setFileName(path_in+file_in+suffix_output+ext_in) im_split.save() return True
def add_noise_gaussian(file_to_noise): img = nib.load(file_to_noise) hdr_0 = img.get_header() data = img.get_data() path, file, ext = sct.extract_fname(file_to_noise) s=data.shape sigma=10 t = time() for j in range(s[0]): for i in range(s[1]): for k in range(s[2]): v = int(math.floor(data[j][i][k]+random.gauss(0,sigma))) if v > 2**16: v = 2**16 if v<0: v = 0 data[j][i][k] = v print("total time", time() - t) print("vol size", data.shape) img_noise = nib.Nifti1Image(data, None, hdr_0) nib.save(img_noise, file + '_noise' +ext)
def plot(x_centerline_fit, y_centerline_fit, z_centerline_fit, x, y, z, fname, nbptctl): fig=plt.figure() plt.subplot(2,2,1) plt.plot(x_centerline_fit,y_centerline_fit,'r-') plt.plot(x,y,'b:') plt.xlabel('x') plt.ylabel('y') plt.subplot(2,2,2) #plt.close() plt.plot(x_centerline_fit,z_centerline_fit,'r-') plt.plot(x,z,'b:') plt.axis([55.0,57.0,0.0,140.0]) plt.xlabel('x') plt.ylabel('z') plt.subplot(2,2,3) plt.plot(y_centerline_fit,z_centerline_fit,'r-') plt.plot(y,z,'b:') plt.axis([221.0,225.5,0.0,140.0]) plt.xlabel('y') plt.ylabel('z') #fig.close() path, file_name, ext_fname = sct_utils.extract_fname(fname) plt.savefig('./curve_'+file_name+'_'+str(nbptctl),dpi=267)
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 main(): # Get parser info parser = get_parser() arguments = parser.parse(sys.argv[1:]) fname_bval_list = arguments["-i"] # Build fname_out if "-o" in arguments: fname_out = arguments["-o"] else: path_in, file_in, ext_in = extract_fname(fname_bval_list[0]) fname_out = path_in+'bvals_concat'+ext_in # Open bval files and concatenate bvals_concat = '' # for file_i in fname_bval_list: # f = open(file_i, 'r') # for line in f: # bvals_concat += line # f.close() for i_fname in fname_bval_list: bval_i, bvec_i = read_bvals_bvecs(i_fname, None) bvals_concat += ' '.join(str(v) for v in bval_i) bvals_concat += ' ' # Write new bval new_f = open(fname_out, 'w') new_f.write(bvals_concat) new_f.close()
def main(args=None): if not args: args = sys.argv[1:] # Get parser info parser = get_parser() arguments = parser.parse(sys.argv[1:]) fname_in = arguments['-bvec'] if '-o' in arguments: fname_out = arguments['-o'] else: fname_out = '' verbose = int(arguments['-v']) # get bvecs in proper orientation from dipy.io import read_bvals_bvecs bvals, bvecs = read_bvals_bvecs(None, fname_in) # # Transpose bvecs # printv('Transpose bvecs...', verbose) # # from numpy import transpose # bvecs = bvecs.transpose() # Write new file if fname_out == '': path_in, file_in, ext_in = extract_fname(fname_in) fname_out = path_in+file_in+ext_in fid = open(fname_out, 'w') for iLine in range(bvecs.shape[0]): fid.write(' '.join(str(i) for i in bvecs[iLine, :])+'\n') fid.close() # display message printv('Created file:\n--> '+fname_out+'\n', verbose, 'info')
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 load_level(list_slices_target, fname_level): verbose = 1 path_level, file_level, ext_level = extract_fname(fname_level) # ####### Check if the level file is an image or a text file # Level file is an image if ext_level in ['.nii', '.nii.gz']: im_level = Image(fname_level) im_level.change_orientation('IRP') list_level = [] list_med_level = [] for slice_level in im_level.data: try: # vertebral level of the slice l = np.mean(slice_level[slice_level > 0]) # median of the vertebral level of the slice: if all voxels are int, med will be an int. med = np.median(slice_level[slice_level > 0]) # change med in int if it is an int med = int(med) if int(med)==med else med except Exception, e: printv('WARNING: ' + str(e) + '\nNo level label found. Level will be set to 0 for this slice', verbose, 'warning') l = 0 med = 0 list_level.append(l) list_med_level.append(med) # if all median of level are int for all slices : consider level as int if all([isinstance(med, int) for med in list_med_level]): # level as int are placed in the middle of each vertebra (that's why there is a "+0.5") list_level = [int(round(l))+0.5 for l in list_level]
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 main(file_to_denoize, param, output_file_name) : path, file, ext = sct.extract_fname(file_to_denoize) img = nib.load(file_to_denoize) hdr_0 = img.get_header() data = img.get_data() aff = img.get_affine() mask = data[:, :, :] > 80 data = data[:, :, :] print("vol size", data.shape) t = time() sigma = np.std(data[~mask]) if param.parameter == 'Rician': den = nlmeans(data, sigma=sigma, mask=mask, rician=True) else : den = nlmeans(data, sigma=sigma, mask=mask, rician=False) print("total time", time() - t) print("vol size", den.shape) axial_middle = data.shape[2] / 2 before = data[:, :, axial_middle].T after = den[:, :, axial_middle].T diff_3d = np.absolute(den.astype('f8') - data.astype('f8')) difference = np.absolute(after.astype('f8') - before.astype('f8')) difference[~mask[:, :, axial_middle].T] = 0 if param.verbose == 2 : fig, ax = plt.subplots(1, 3) ax[0].imshow(before, cmap='gray', origin='lower') ax[0].set_title('before') ax[1].imshow(after, cmap='gray', origin='lower') ax[1].set_title('after') ax[2].imshow(difference, cmap='gray', origin='lower') ax[2].set_title('difference') for i in range(3): ax[i].set_axis_off() plt.show() plt.savefig('denoised_S0.png', bbox_inches='tight') #Save files img_denoize = nib.Nifti1Image(den, None, hdr_0) img_diff = nib.Nifti1Image(diff_3d, None, hdr_0) if output_file_name != None : output_file_name =output_file_name else: output_file_name = file + '_denoized' + ext nib.save(img_denoize,output_file_name) nib.save(img_diff, file + '_difference' +ext)
def setFileName(self, filename): """ :param filename: file name with extension :return: """ from sct_utils import extract_fname self.absolutepath = filename self.path, self.file_name, self.ext = extract_fname(filename)
def main(): for file in glob.glob('./t250/t*'): print file path, file_name, ext_fname = sct_utils.extract_fname(file) cmd = 'fslmaths '+file+' -s 1 ./t250/smooth'+file_name print cmd status, output = commands.getstatusoutput(cmd)
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_3d(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' sct.run('sct_resample -i ' + fname + ' -mm ' + str(npx) + 'x' + str(npy) + 'x' + str(pz) + ' -o ' + name_resample + ' -x ' + interpolation) if binary: # sct.run('sct_maths -i ' + name_resample + ' -thr ' + str(thr) + ' -o ' + name_resample) 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 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 __init__(self, input_file, command, args, orientation, dest_folder, dpi=300, dataset=None, subject=None): """ Parameters :param input_file: str: the input nifti file name :param command: str: command name :param args: str: the command's arguments :param orientation: str: The anatomical orientation :param dest_folder: str: The absolute path of the QC root :param dpi: int: Output resolution of the image :param dataset: str: Dataset name :param subject: str: Subject name """ path_in, file_in, ext_in = sct.extract_fname( os.path.abspath(input_file)) # Assuming BIDS convention, we derive the value of the dataset, subject and contrast from the `input_file` # by splitting it into `[dataset]/[subject]/[contrast]/input_file` abs_input_path, contrast = os.path.split(path_in) abs_input_path, subject_tmp = os.path.split(abs_input_path) _, dataset_tmp = os.path.split(abs_input_path) if dataset is None: dataset = dataset_tmp if subject is None: subject = subject_tmp if isinstance(args, list): args = sct.list2cmdline(args) self.fname_in = file_in + ext_in self.dataset = dataset self.subject = subject self.cwd = os.getcwd() self.contrast = contrast self.command = command self.sct_version = sct.__version__ self.args = args self.orientation = orientation self.dpi = dpi self.root_folder = dest_folder self.mod_date = datetime.datetime.strftime(datetime.datetime.now(), '%Y_%m_%d_%H%M%S.%f') self.qc_results = os.path.join(dest_folder, '_json/qc_' + self.mod_date + '.json') self.bkg_img_path = os.path.join(dataset, subject, contrast, command, self.mod_date, 'bkg_img.png') self.overlay_img_path = os.path.join(dataset, subject, contrast, command, self.mod_date, 'overlay_img.png')
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 centerline2roi(fname_image, folder_output='./', verbose=0): """ Tis method converts a binary centerline image to a .roi centerline file Args: fname_image: filename of the binary centerline image, in RPI orientation folder_output: path to output folder where to copy .roi centerline verbose: adjusts the verbosity of the logging. Returns: filename of the .roi centerline that has been created """ path_data, file_data, ext_data = sct.extract_fname(fname_image) fname_output = file_data + '.roi' date_now = datetime.now() ROI_TEMPLATE = 'Begin Marker ROI\n' \ ' Build version="7.0_33"\n' \ ' Annotation=""\n' \ ' Colour=0\n' \ ' Image source="{fname_segmentation}"\n' \ ' Created "{creation_date}" by Operator ID="SCT"\n' \ ' Slice={slice_num}\n' \ ' Begin Shape\n' \ ' X={position_x}; Y={position_y}\n' \ ' End Shape\n' \ 'End Marker ROI\n' im = Image(fname_image) nx, ny, nz, nt, px, py, pz, pt = im.dim coordinates_centerline = im.getNonZeroCoordinates(sorting='z') f = open(fname_output, "w") sct.printv('\nWriting ROI file...', verbose) for coord in coordinates_centerline: coord_phys_center = im.transfo_pix2phys([[(nx - 1) / 2.0, (ny - 1) / 2.0, coord.z]])[0] coord_phys = im.transfo_pix2phys([[coord.x, coord.y, coord.z]])[0] f.write( ROI_TEMPLATE.format( fname_segmentation=fname_image, creation_date=date_now.strftime("%d %B %Y %H:%M:%S.%f %Z"), slice_num=coord.z + 1, position_x=coord_phys_center[0] - coord_phys[0], position_y=coord_phys_center[1] - coord_phys[1])) f.close() if os.path.abspath(folder_output) != os.getcwd(): shutil.copy(fname_output, folder_output) return fname_output
def main(): """Main function.""" parser = get_parser() args = parser.parse_args(args=None if sys.argv[1:] else ['--help']) fname_image = args.i contrast_type = args.c ctr_algo = args.centerline brain_bool = bool(args.brain) if args.brain is None and contrast_type in ['t2s', 't2_ax']: brain_bool = False output_folder = args.ofolder if ctr_algo == 'file' and args.file_centerline is None: sct.printv('Please use the flag -file_centerline to indicate the centerline filename.', 1, 'error') sys.exit(1) if args.file_centerline is not None: manual_centerline_fname = args.file_centerline ctr_algo = 'file' else: manual_centerline_fname = None remove_temp_files = args.r verbose = args.v sct.init_sct(log_level=verbose, update=True) # Update log level algo_config_stg = '\nMethod:' algo_config_stg += '\n\tCenterline algorithm: ' + str(ctr_algo) algo_config_stg += '\n\tAssumes brain section included in the image: ' + str(brain_bool) + '\n' sct.printv(algo_config_stg) # Segment image from spinalcordtoolbox.image import Image from spinalcordtoolbox.deepseg_lesion.core import deep_segmentation_MSlesion im_image = Image(fname_image) im_seg, im_labels_viewer, im_ctr = deep_segmentation_MSlesion(im_image, contrast_type, ctr_algo=ctr_algo, ctr_file=manual_centerline_fname, brain_bool=brain_bool, remove_temp_files=remove_temp_files, verbose=verbose) # Save segmentation fname_seg = os.path.abspath(os.path.join(output_folder, sct.extract_fname(fname_image)[1] + '_lesionseg' + sct.extract_fname(fname_image)[2])) im_seg.save(fname_seg) if ctr_algo == 'viewer': # Save labels fname_labels = os.path.abspath(os.path.join(output_folder, sct.extract_fname(fname_image)[1] + '_labels-centerline' + sct.extract_fname(fname_image)[2])) im_labels_viewer.save(fname_labels) if verbose == 2: # Save ctr fname_ctr = os.path.abspath(os.path.join(output_folder, sct.extract_fname(fname_image)[1] + '_centerline' + sct.extract_fname(fname_image)[2])) im_ctr.save(fname_ctr) sct.display_viewer_syntax([fname_image, fname_seg], colormaps=['gray', 'red'], opacities=['', '0.7'])
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 segmentation(fname_input, output_dir, image_type): # parameters path_in, file_in, ext_in = sct.extract_fname(fname_input) # define command cmd = 'sct_propseg_test -i ' + fname_input \ + ' -o ' + output_dir \ + ' -t ' + image_type \ + ' -detect-nii' \ status, output = sct.run(cmd) # check if spinal cord is correctly detected # sct_propseg return one point # check existence of input files segmentation_filename = path_in + file_in + '_seg' + ext_in manual_segmentation_filename = path_in + 'manual_' + file_in + ext_in detection_filename = path_in + file_in + '_detection' + ext_in sct.check_file_exist(detection_filename) sct.check_file_exist(segmentation_filename) # read nifti input file img = nibabel.load(detection_filename) # 3d array for each x y z voxel values for the input nifti image data = img.get_data() # read nifti input file img_seg = nibabel.load(manual_segmentation_filename) # 3d array for each x y z voxel values for the input nifti image data_seg = img_seg.get_data() X, Y, Z = (data > 0).nonzero() status = 0 for i in range(0, len(X)): if data_seg[X[i], Y[i], Z[i]] == 0: status = 1 break if status is not 0: sct.printv('ERROR: detected point is not in segmentation', 1, 'warning') else: sct.printv('OK: detected point is in segmentation') cmd_validation = 'sct_dice_coefficient ' + segmentation_filename \ + ' ' + manual_segmentation_filename \ + ' -bzmax' status_validation, output = sct.run(cmd_validation) print output return status
def copy(self, image=None): from copy import deepcopy from sct_utils import extract_fname if image is not None: self.data = deepcopy(image.data) self.dim = deepcopy(image.dim) self.hdr = deepcopy(image.hdr) self.orientation = deepcopy(image.orientation) self.absolutepath = deepcopy(image.absolutepath) self.path, self.file_name, self.ext = extract_fname( self.absolutepath) else: return deepcopy(self)
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 = run_proc(['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') run_proc(['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) run_proc(['sct_apply_transfo', '-i', fname_grid, '-d', fname_grid, '-w', fname_warp, '-o', grid_warped]) if rm_tmp: sct.rmtree(tmp_dir)
def visualize_warp(fname_warp, fname_grid=None, step=3, rm_tmp=True): if fname_grid is None: from numpy import zeros tmp_dir = tmp_create() im_warp = Image(fname_warp) status, out = run('fslhd ' + fname_warp) from os import chdir 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.setFileName(fname_grid) im_grid.save() fname_grid_resample = add_suffix(fname_grid, '_resample') run('sct_resample -i ' + fname_grid + ' -f 3x3x1 -x nn -o ' + fname_grid_resample) fname_grid = tmp_dir + fname_grid_resample chdir('..') path_warp, file_warp, ext_warp = extract_fname(fname_warp) grid_warped = path_warp + extract_fname(fname_grid)[1] + '_' + file_warp + ext_warp run('sct_apply_transfo -i ' + fname_grid + ' -d ' + fname_grid + ' -w ' + fname_warp + ' -o ' + grid_warped) if rm_tmp: run('rm -rf ' + tmp_dir, error_exit='warning')
def check_data_segmentation_landmarks_same_space(fname_data, fname_seg, fname_landmarks, verbose): sct.printv( '\nCheck if data, segmentation and landmarks are in the same space...') path_data, file_data, ext_data = sct.extract_fname(fname_data) if not sct.check_if_same_space(fname_data, fname_seg): sct.printv( 'ERROR: Data image and segmentation are not in the same space. Please check space and orientation of your files', verbose, 'error') if not sct.check_if_same_space(fname_data, fname_landmarks): sct.printv( 'ERROR: Data image and landmarks are not in the same space. Please check space and orientation of your files', verbose, 'error') return (ext_data, path_data, file_data)
def _measure_within_im(self, im_lesion, im_ref, label_lst): printv('\nCompute reference image features...', self.verbose, 'normal') for lesion_label in label_lst: im_label_data_cur = im_lesion == lesion_label im_label_data_cur[np.where( im_ref == 0 )] = 0 # if the ref object is eroded compared to the labeled object mean_cur, std_cur = np.mean( im_ref[np.where(im_label_data_cur)]), np.std( im_ref[np.where(im_label_data_cur)]) label_idx = self.measure_pd[self.measure_pd.label == lesion_label].index self.measure_pd.loc[label_idx, 'mean_' + extract_fname(self.fname_ref)[1]] = mean_cur self.measure_pd.loc[label_idx, 'std_' + extract_fname(self.fname_ref)[1]] = std_cur printv('Mean+/-std of lesion #' + str(lesion_label) + ' in ' + extract_fname(self.fname_ref)[1] + ' file: ' + str(round(mean_cur, 2)) + '+/-' + str(round(std_cur, 2)), self.verbose, type='info')
def main(): i = 25 b = [5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25] for file in glob.glob('./t250/smoooooth*'): #for file in glob.glob('./t250/t250*'): path, file_name, ext_fname = sct_utils.extract_fname(file) cmd1 = 'mkdir ../curves/' + file_name print cmd1 status, output = commands.getstatusoutput(cmd1) print status, output for bc in b: spline.main(file, bc)
def copy_data_to_tmp(self): # copy input image if self.param_seg.fname_im is not None: shutil.copy(self.param_seg.fname_im, self.tmp_dir) self.param_seg.fname_im = ''.join(extract_fname(self.param_seg.fname_im)[1:]) else: printv('ERROR: No input image', self.param.verbose, 'error') # copy sc seg image if self.param_seg.fname_seg is not None: shutil.copy(self.param_seg.fname_seg, self.tmp_dir) self.param_seg.fname_seg = ''.join(extract_fname(self.param_seg.fname_seg)[1:]) else: printv('ERROR: No SC segmentation image', self.param.verbose, 'error') # copy level file if self.param_seg.fname_level is not None: shutil.copy(self.param_seg.fname_level, self.tmp_dir) self.param_seg.fname_level = ''.join(extract_fname(self.param_seg.fname_level)[1:]) if self.param_seg.fname_manual_gmseg is not None: shutil.copy(self.param_seg.fname_manual_gmseg, self.tmp_dir) self.param_seg.fname_manual_gmseg = ''.join(extract_fname(self.param_seg.fname_manual_gmseg)[1:])
def test_integrity(param_test): """ Test integrity of function """ try: # extraction of results output_split = param_test.output.split('Maximum x-y error = ')[1].split(' mm') result_dist_max = float(output_split[0]) result_rmse = float(output_split[1].split('Accuracy of straightening (MSE) = ')[1]) duration_accuracy_results = float(param_test.output.split('\nincluding ')[1].split(' s')[0]) # integrity testing if result_dist_max > param_test.th_result_dist_max: param_test.status = 99 param_test.output += '\nWARNING: Maximum x-y error = ' + str(result_dist_max) + ' < ' + str(param_test.th_result_dist_max) if result_rmse > param_test.th_result_rmse: param_test.status = 99 param_test.output += '\nWARNING: RMSE = ' + str(result_rmse) + ' < ' + str(param_test.th_result_rmse) # apply curved2straight, then straight2curve, then compared results path_input, file_input, ext_input = sct.extract_fname(param_test.file_input) sct.run('sct_apply_transfo -i ' + param_test.path_data + param_test.fname_segmentation + ' -d ' + param_test.path_output + file_input + '_straight' + ext_input + ' -w ' + param_test.path_output + 'warp_curve2straight.nii.gz -o ' + param_test.path_output + 'tmp_seg_straight.nii.gz -x linear', 0) sct.run('sct_apply_transfo -i ' + param_test.path_output + 'tmp_seg_straight.nii.gz -d ' + param_test.path_data + param_test.fname_segmentation + ' -w ' + param_test.path_output + 'warp_straight2curve.nii.gz -o ' + param_test.path_output + 'tmp_seg_straight_curved.nii.gz -x nn',0) # threshold and binarize sct.run('sct_maths -i ' + param_test.path_output + 'tmp_seg_straight_curved.nii.gz -bin 0.5 -o ' + param_test.path_output + 'tmp_seg_straight_curved.nii.gz', 0) # compute DICE cmd = 'sct_dice_coefficient -i ' + param_test.path_output + 'tmp_seg_straight_curved.nii.gz -d ' + param_test.path_data + param_test.fname_segmentation status2, output2 = sct.run(cmd, 0) # parse output and compare to acceptable threshold result_dice = float(output2.split('3D Dice coefficient = ')[1].split('\n')[0]) if result_dice < param_test.th_dice: param_test.status = 99 param_test.output += '\nWARNING: DICE = ' + str(result_dice) + ' < ' + str(param_test.th_dice) # transform results into Pandas structure param_test.results = DataFrame(data={'status': param_test.status, 'output': param_test.output, 'rmse': result_rmse, 'dist_max': result_dist_max, 'dice': result_dice, 'duration': param_test.duration, 'duration_accuracy_results': duration_accuracy_results}, index=[param_test.path_data]) except Exception as e: param_test.status = 99 param_test.output += 'Error on line {}'.format(sys.exc_info()[-1].tb_lineno) param_test.output += str(e) return param_test
def main(): # Get parser info parser = get_parser() arguments = parser.parse_args(args=None if sys.argv[1:] else ['--help']) fname_bvecs_list = arguments.i # Build fname_out if arguments.o is not None: fname_out = arguments.o else: path_in, file_in, ext_in = sct.extract_fname(fname_bvecs_list[0]) fname_out = path_in + 'bvecs_concat' + ext_in # # Open bvec files and collect values # nb_files = len(fname_bvecs_list) # bvecs_all = [] # for i_fname in fname_bvecs_list: # bvecs = [] # with open(i_fname) as f: # for line in f: # bvec_line = map(float, line.split()) # bvecs.append(bvec_line) # bvecs_all.append(bvecs) # f.close() # # Concatenate # bvecs_concat = '' # for i in range(0, 3): # for j in range(0, nb_files): # bvecs_concat += ' '.join(str(v) for v in bvecs_all[j][i]) # bvecs_concat += ' ' # bvecs_concat += '\n' # # Open bvec files and collect values bvecs_all = ['', '', ''] for i_fname in fname_bvecs_list: from dipy.data.fetcher import read_bvals_bvecs bval_i, bvec_i = read_bvals_bvecs(None, i_fname) for i in range(0, 3): bvecs_all[i] += ' '.join( str(v) for v in map(lambda n: '%.16f' % n, bvec_i[:, i])) bvecs_all[i] += ' ' # Concatenate bvecs_concat = '\n'.join(str(v) for v in bvecs_all) # Write new bvec new_f = open(fname_out, 'w') new_f.write(bvecs_concat) new_f.close()
def compute_length(fname_segmentation, remove_temp_files, verbose=0): from math import sqrt # Extract path, file and extension fname_segmentation = os.path.abspath(fname_segmentation) path_data, file_data, ext_data = sct.extract_fname(fname_segmentation) # create temporary folder path_tmp = 'tmp.' + time.strftime("%y%m%d%H%M%S") sct.run('mkdir ' + path_tmp) # copy files into tmp folder sct.run('cp ' + fname_segmentation + ' ' + path_tmp) # go to tmp folder os.chdir(path_tmp) # Change orientation of the input centerline into RPI sct.printv('\nOrient centerline to RPI orientation...', param.verbose) fname_segmentation_orient = 'segmentation_rpi' + ext_data set_orientation(file_data + ext_data, 'RPI', fname_segmentation_orient) # Get dimension sct.printv('\nGet dimensions...', param.verbose) nx, ny, nz, nt, px, py, pz, pt = Iamge(fname_segmentation_orient).dim sct.printv( '.. matrix size: ' + str(nx) + ' x ' + str(ny) + ' x ' + str(nz), param.verbose) sct.printv( '.. voxel size: ' + str(px) + 'mm x ' + str(py) + 'mm x ' + str(pz) + 'mm', param.verbose) # smooth segmentation/centerline #x_centerline_fit, y_centerline_fit, z_centerline, x_centerline_deriv,y_centerline_deriv,z_centerline_deriv = smooth_centerline(fname_segmentation_orient, param, 'hanning', 1) x_centerline_fit, y_centerline_fit, z_centerline, x_centerline_deriv, y_centerline_deriv, z_centerline_deriv = smooth_centerline( fname_segmentation_orient, type_window='hanning', window_length=80, algo_fitting='hanning', verbose=verbose) # compute length of centerline result_length = 0.0 for i in range(len(x_centerline_fit) - 1): result_length += sqrt( ((x_centerline_fit[i + 1] - x_centerline_fit[i]) * px)**2 + ((y_centerline_fit[i + 1] - y_centerline_fit[i]) * py)**2 + ((z_centerline[i + 1] - z_centerline[i]) * pz)**2) return result_length
def __init__(self, fname_im, contrast, fname_seg, path_out, quality_control, verbose): self.fname_im = fname_im self.contrast = contrast self.fname_seg = fname_seg self.path_out = path_out self.quality_control = quality_control self.verbose = verbose self.tmp_dir = tmp_create( verbose=self.verbose) # path to tmp directory self.orientation_im = get_orientation(Image( self.fname_im)) # to re-orient the data at the end self.slice2D_im = extract_fname( self.fname_im )[1] + '_midSag.nii' # file used to do the detection, with only one slice self.dection_map_pmj = extract_fname( self.fname_im)[1] + '_map_pmj' # file resulting from the detection # path to the pmj detector self.pmj_model = os.path.join( commands.getstatusoutput('echo $SCT_DIR')[1], 'data/pmj_models', '{}_model'.format(self.contrast)) self.threshold = -0.75 if self.contrast == 't1' else 0.8 # detection map threshold, depends on the contrast self.fname_out = extract_fname(self.fname_im)[1] + '_pmj.nii.gz' self.fname_qc = 'qc_pmj.png'
def post_processing(self): square_mask = Image(self.preprocessed.square_mask) tmp_res_names = [] for res_im in [ self.gm_seg.res_wm_seg, self.gm_seg.res_gm_seg, self.gm_seg.corrected_wm_seg ]: res_im_original_space = inverse_square_crop(res_im, square_mask) res_im_original_space.save() sct.run('sct_orientation -i ' + res_im_original_space.file_name + '.nii.gz -s ' + self.preprocessed.original_orientation) res_name = sct.extract_fname( self.target_fname)[1] + res_im.file_name[len( sct.extract_fname(self.preprocessed.treated_target)[1] ):] + '.nii.gz' if self.param.res_type == 'binary': bin = True else: bin = False old_res_name = resample_image(res_im_original_space.file_name + '_RPI.nii.gz', npx=self.preprocessed.original_px, npy=self.preprocessed.original_py, binary=bin) if self.param.res_type == 'prob': sct.run('fslmaths ' + old_res_name + ' -thr 0.05 ' + old_res_name) sct.run('cp ' + old_res_name + ' ../' + res_name) tmp_res_names.append(res_name) self.res_names['wm_seg'] = tmp_res_names[0] self.res_names['gm_seg'] = tmp_res_names[1] self.res_names['corrected_wm_seg'] = tmp_res_names[2]
def mean_angle(self): im_metric_lst = [self.fname_metric_lst[f].split('_' + str(self.param_glcm.distance) + '_')[0] + '_' for f in self.fname_metric_lst] im_metric_lst = list(set(im_metric_lst)) printv('\nMean across angles...', self.param.verbose, 'normal') extension = extract_fname(self.param.fname_im)[2] for im_m in im_metric_lst: # Loop across GLCM texture properties # List images to mean im2mean_lst = [im_m + str(self.param_glcm.distance) + '_' + a + extension for a in self.param_glcm.angle.split(',')] # Average across angles and save it as wrk_folder/fnameIn_feature_distance_mean.extension fname_out = im_m + str(self.param_glcm.distance) + '_mean' + extension run('sct_image -i ' + ','.join(im2mean_lst) + ' -concat t -o ' + fname_out) run('sct_maths -i ' + fname_out + ' -mean t -o ' + fname_out) self.fname_metric_lst[im_m + str(self.param_glcm.distance) + '_mean'] = fname_out
def validation(self): name_ref_gm_seg = sct.extract_fname(self.ref_gm_seg) im_ref_gm_seg = Image('../' + self.ref_gm_seg) res_gm_seg_bin = Image('../' + self.res_names['gm_seg']) res_wm_seg_bin = Image('../' + self.res_names['wm_seg']) sct.run('cp ../' + self.ref_gm_seg + ' ./ref_gm_seg.nii.gz') im_ref_wm_seg = inverse_gmseg_to_wmseg(im_ref_gm_seg, Image('../' + self.sc_seg_fname), 'ref_gm_seg') im_ref_wm_seg.file_name = 'ref_wm_seg' im_ref_wm_seg.ext = '.nii.gz' im_ref_wm_seg.save() if self.param.res_type == 'prob': res_gm_seg_bin.data = np.asarray((res_gm_seg_bin.data >= 0.5).astype(int)) res_wm_seg_bin.data = np.asarray((res_wm_seg_bin.data >= 0.50001).astype(int)) res_gm_seg_bin.path = './' res_gm_seg_bin.file_name = 'res_gm_seg_bin' res_gm_seg_bin.ext = '.nii.gz' res_gm_seg_bin.save() res_wm_seg_bin.path = './' res_wm_seg_bin.file_name = 'res_wm_seg_bin' res_wm_seg_bin.ext = '.nii.gz' res_wm_seg_bin.save() try: status_gm, output_gm = sct.run('sct_dice_coefficient ref_gm_seg.nii.gz res_gm_seg_bin.nii.gz -2d-slices 2', error_exit='warning', raise_exception=True) except Exception: sct.run('c3d res_gm_seg_bin.nii.gz ref_gm_seg.nii.gz -reslice-identity -o ref_in_res_space_gm.nii.gz ') status_gm, output_gm = sct.run('sct_dice_coefficient ref_in_res_space_gm.nii.gz res_gm_seg_bin.nii.gz -2d-slices 2', error_exit='warning') try: status_wm, output_wm = sct.run('sct_dice_coefficient ref_wm_seg.nii.gz res_wm_seg_bin.nii.gz -2d-slices 2', error_exit='warning', raise_exception=True) except Exception: sct.run('c3d res_wm_seg_bin.nii.gz ref_wm_seg.nii.gz -reslice-identity -o ref_in_res_space_wm.nii.gz ') status_wm, output_wm = sct.run('sct_dice_coefficient ref_in_res_space_wm.nii.gz res_wm_seg_bin.nii.gz -2d-slices 2', error_exit='warning') dice_name = 'dice_' + self.param.res_type + '.txt' dice_fic = open('../' + dice_name, 'w') if self.param.res_type == 'prob': dice_fic.write('WARNING : the probabilistic segmentations were binarized with a threshold at 0.5 to compute the dice coefficient \n') dice_fic.write('\n--------------------------------------------------------------\nDice coefficient on the Gray Matter segmentation:\n') dice_fic.write(output_gm) dice_fic.write('\n\n--------------------------------------------------------------\nDice coefficient on the White Matter segmentation:\n') dice_fic.write(output_wm) dice_fic.close() # sct.run(' mv ./' + dice_name + ' ../') return dice_name
def MSE(self, threshold_mse=0): """ Compute the Mean Square Distance Error between two sets of labels (input and ref). Moreover, a warning is generated for each label mismatch. If the MSE is above the threshold provided (by default = 0mm), a log is reported with the filenames considered here. """ coordinates_input = self.image_input.getNonZeroCoordinates() coordinates_ref = self.image_ref.getNonZeroCoordinates() # check if all the labels in both the images match if len(coordinates_input) != len(coordinates_ref): sct.printv('ERROR: labels mismatch', 1, 'warning') for coord in coordinates_input: if np.round(coord.value) not in [ np.round(coord_ref.value) for coord_ref in coordinates_ref ]: sct.printv('ERROR: labels mismatch', 1, 'warning') for coord_ref in coordinates_ref: if np.round(coord_ref.value) not in [ np.round(coord.value) for coord in coordinates_input ]: sct.printv('ERROR: labels mismatch', 1, 'warning') result = 0.0 for coord in coordinates_input: for coord_ref in coordinates_ref: if np.round(coord_ref.value) == np.round(coord.value): result += (coord_ref.z - coord.z)**2 break result = np.sqrt(result / len(coordinates_input)) sct.printv('MSE error in Z direction = ' + str(result) + ' mm') if result > threshold_mse: parent, stem, ext = sct.extract_fname( self.image_input.absolutepath) fname_report = os.path.join(parent, 'error_log_{}.txt'.format(stem)) with open(fname_report, 'w') as f: f.write( 'The labels error (MSE) between {} and {} is: {}\n'.format( os.path.relpath(self.image_input.absolutepath, os.path.dirname(fname_report)), os.path.relpath(self.image_ref.absolutepath, os.path.dirname(fname_report)), result)) return result
def generate_mask_pmj(self): """Output the PMJ mask.""" if self.pa_coord != -1: # If PMJ has been detected im = Image(''.join(sct.extract_fname( self.fname_im)[1:])) # image in PIR orientation im_mask = msct_image.zeros_like(im) im_mask.data[self.pa_coord, self.is_coord, self.rl_coord] = 50 # voxel with value = 50 im_mask.change_orientation(self.orientation_im).save( self.fname_out) x_pmj, y_pmj, z_pmj = np.where(im_mask.data == 50) sct.printv('\tx_pmj = ' + str(x_pmj[0]), self.verbose, 'info') sct.printv('\ty_pmj = ' + str(y_pmj[0]), self.verbose, 'info') sct.printv('\tz_pmj = ' + str(z_pmj[0]), self.verbose, 'info')
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.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, '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 test_integrity(param_test): """ Test integrity of function """ # find the test that is performed and check the integrity of the output index_args = param_test.default_args.index(param_test.args) # checking the integrity of padding an image if index_args == 0: nx, ny, nz, nt, px, py, pz, pt = Image(os.path.join(param_test.path_data, param_test.folder_data[0], param_test.file_data[0])).dim nx2, ny2, nz2, nt2, px2, py2, pz2, pt2 = Image(os.path.join(param_test.path_output, 'test.nii.gz')).dim if nz2 != nz + 2 * param_test.pad: param_test.status = 99 param_test.output += '\nResulting pad image\'s dimension differs from expected:\n' param_test.output += 'dim : ' + str(nx2) + 'x' + str(ny2) + 'x' + str(nz2) + '\n' param_test.output += 'expected : ' + str(nx) + 'x' + str(ny) + 'x' + str(nz + 2 * param_test.pad) + '\n' elif index_args == 3: threshold = 1e-3 try: path_fname, file_fname, ext_fname = sct.extract_fname(os.path.join(param_test.path_data, param_test.folder_data[2], param_test.file_data[2])) ref = Image(os.path.join(param_test.path_data, param_test.dmri_t_slices[0])) new = Image(os.path.join(param_test.path_output, file_fname + '_T0000' + ext_fname)) diff = ref.data - new.data if np.sum(diff) > threshold: param_test.status = 99 param_test.output += '\nResulting split image differs from gold-standard.\n' except Exception as e: param_test.status = 99 param_test.output += 'ERROR: ' + str(e) elif index_args == 4: try: threshold = 1e-3 ref = Image(os.path.join(param_test.path_data, param_test.folder_data[2], param_test.file_data[2])) new = Image(os.path.join(param_test.path_output, 'dmri_concat.nii.gz')) diff = ref.data - new.data if np.sum(diff) > threshold: param_test.status = 99 param_test.output += '\nResulting concatenated image differs from gold-standard (original dmri image).\n' except Exception as e: param_test.status = 99 param_test.output += 'ERROR: ' + str(e) return param_test
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: if filename: sct.run([ 'isct_orientation3d', '-i', im, '-orientation', orientation, '-o', fname_out ], verbose=0) im_out = fname_out else: fname_in = im.absolutepath if not os.path.exists(fname_in): im.save() sct.run([ 'isct_orientation3d', '-i', im.absolutepath, '-orientation', orientation, '-o', fname_out ], verbose=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 returnCenterline(fname=None, nurbs=0, div=0): if fname == None: fname = 't250_half_sup_straight_seg.nii.gz' file = nibabel.load(fname) data = file.get_data() hdr_seg = file.get_header() nx, ny, nz = spline_app.getDim(fname) x = [0 for iz in range(0, nz, 1)] y = [0 for iz in range(0, nz, 1)] z = [iz for iz in range(0, nz, 1)] for iz in range(0, nz, 1): x[iz], y[iz] = ndimage.measurements.center_of_mass( numpy.array(data[:, :, iz])) points = [[x[n], y[n], z[n]] for n in range(len(x))] p1, p2, p3 = spline_app.getPxDimensions(fname) size = spline_app.getSize(x, y, z, p1, p2, p3) data = data * 0 if nurbs: if check_nurbs(div, size, points) != 0: x_centerline_fit = P[0] y_centerline_fit = P[1] z_centerline_fit = P[2] for i in range(len(z_centerline_fit)): data[int(round(x_centerline_fit[i])), int(round(y_centerline_fit[i])), int(z_centerline_fit[i])] = 1 else: return 1 else: for i in range(len(z)): data[int(round(x[i])), int(round(y[i])), int(z[i])] = 1 path, file_name, ext_fname = sct_utils.extract_fname(fname) img = nibabel.Nifti1Image(data, None, hdr_seg) #return img saveFile(file_name, img, div) return size
def __init__(self, input_file, command, args, orientation, dest_folder, dpi=300): """ Parameters :param input_file: str: the input nifti file name :param command: str: command name :param args: str: the command's arguments :param orientation: str: The anatomical orientation :param dest_folder: str: The absolute path of the QC root :param dpi: int: Output resolution of the image """ path_in, file_in, ext_in = sct.extract_fname( os.path.abspath(input_file)) # abs_input_path = os.path.dirname(os.path.abspath(input_file)) abs_input_path, contrast = os.path.split(path_in) abs_input_path, subject = os.path.split(abs_input_path) _, dataset = os.path.split(abs_input_path) if isinstance(args, list): args = sct.list2cmdline(args) self.fname_in = file_in + ext_in self.dataset = dataset self.subject = subject self.cwd = os.getcwd() self.contrast = contrast self.command = command self.sct_version = sct.__version__ self.args = args self.orientation = orientation self.dpi = dpi self.root_folder = dest_folder self.mod_date = datetime.datetime.strftime(datetime.datetime.now(), '%Y_%m_%d_%H%M%S.%f') self.qc_results = os.path.join(dest_folder, 'qc_results.json') self.bkg_img_path = os.path.join(dataset, subject, contrast, command, self.mod_date, 'bkg_img.png') self.overlay_img_path = os.path.join(dataset, subject, contrast, command, self.mod_date, 'overlay_img.png')
def addfiles(self, file): path_data, file_data, ext_data = sct.extract_fname(file) #check that files are same size if len(self.list_file) > 0 : self.dimension = sct.get_dimension(self.list_file[0]) nx, ny, nz, nt, px, py, pz, pt = sct.get_dimension(file) #if self.dimension != (nx, ny, nz, nt, px, py, pz, pt) : if self.dimension[0:3] != (nx, ny, nz) or self.dimension[4:7] != (px, py, pz) : # Return error and exit programm if not same size print('\nError: Files are not of the same size.') sys.exit() # Add file if same size self.list_file.append(file) image_input = Image(file) self.list_image.append(image_input) print('\nFile', file_data+ext_data,' added to the list.')