def main(args=None): if args is None: args = sys.argv[1:] # create param objects param_seg = ParamSeg() param_data = ParamData() param_model = ParamModel() param = Param() # get parser parser = get_parser() arguments = parser.parse(args) # set param arguments ad inputted by user param_seg.fname_im = arguments["-i"] param_seg.fname_im_original = arguments["-i"] param_seg.fname_seg = arguments["-s"] if '-vertfile' in arguments: if extract_fname(arguments['-vertfile'])[1].lower() == "none": param_seg.fname_level = None elif os.path.isfile(arguments['-vertfile']): param_seg.fname_level = arguments['-vertfile'] else: param_seg.fname_level = None printv('WARNING: -vertfile input file: "' + arguments['-vertfile'] + '" does not exist.\nSegmenting GM without using vertebral information', 1, 'warning') if '-denoising' in arguments: param_data.denoising = bool(int(arguments['-denoising'])) if '-normalization' in arguments: param_data.normalization = bool(int(arguments['-normalization'])) if '-p' in arguments: param_data.register_param = arguments['-p'] if '-w-levels' in arguments: param_seg.weight_level = arguments['-w-levels'] if '-w-coordi' in arguments: param_seg.weight_coord = arguments['-w-coordi'] if '-thr-sim' in arguments: param_seg.thr_similarity = arguments['-thr-sim'] if '-model' in arguments: param_model.path_model_to_load = os.path.abspath(arguments['-model']) if '-res-type' in arguments: param_seg.type_seg = arguments['-res-type'] if '-ref' in arguments: param_seg.fname_manual_gmseg = arguments['-ref'] if '-ofolder' in arguments: param_seg.path_results = os.path.abspath(arguments['-ofolder']) param_seg.qc = arguments.get("-qc", None) if '-r' in arguments: param.rm_tmp = bool(int(arguments['-r'])) param.verbose = int(arguments.get('-v')) sct.init_sct(log_level=param.verbose, update=True) # Update log level start_time = time.time() seg_gm = SegmentGM(param_seg=param_seg, param_data=param_data, param_model=param_model, param=param) seg_gm.segment() elapsed_time = time.time() - start_time printv('\nFinished! Elapsed time: ' + str(int(np.round(elapsed_time))) + 's', param.verbose) # save quality control and sct.printv(info) if param_seg.type_seg == 'bin': wm_col = 'red' gm_col = 'blue' b = '0,1' else: wm_col = 'blue-lightblue' gm_col = 'red-yellow' b = '0.4,1' if param_seg.qc is not None: generate_qc(param_seg.fname_im_original, seg_gm.fname_res_gmseg, seg_gm.fname_res_wmseg, param_seg, args, os.path.abspath(param_seg.qc)) if param.rm_tmp: # remove tmp_dir sct.rmtree(seg_gm.tmp_dir) sct.display_viewer_syntax([param_seg.fname_im_original, seg_gm.fname_res_gmseg, seg_gm.fname_res_wmseg], colormaps=['gray', gm_col, wm_col], minmax=['', b, b], opacities=['1', '0.7', '0.7'], verbose=param.verbose)
def get_parser(): # Initialize the parser parser = Parser(__file__) parser.usage.set_description('Segmentation of the white and gray matter.' ' The segmentation is based on a multi-atlas method that uses a dictionary of pre-segmented gray matter images (already included in SCT) and finds the most similar images for identifying the gray matter using label fusion approach. The model used by this method contains: a template of the white/gray matter segmentation along the cervical spinal cord, and a PCA reduced space to describe the variability of intensity in that template.' ' This method was inspired from [Asman et al., Medical Image Analysis 2014] and features the following additions:\n' '- possibility to add information from vertebral levels for improved accuracy\n' '- intensity normalization of the image to segment (allows the segmentation of any kind of contrast)\n' '- pre-registration based on non-linear transformations') parser.add_option(name="-i", type_value="file", description="Image to segment", mandatory=True, example='t2star.nii.gz') parser.add_option(name="-s", type_value="file", description="Spinal cord segmentation", mandatory=True, example='sc_seg.nii.gz') parser.add_option(name="-vertfile", type_value="str", description='Labels of vertebral levels. This could either be an image (e.g., label/template/PAM50_levels.nii.gz) or a text file that specifies "slice,level" at each line. Example:\n' "0,3\n" "1,3\n" "2,4\n" "3,4\n" "4,4\n", mandatory=False, default_value=ParamSeg().fname_level) parser.add_option(name="-vert", mandatory=False, deprecated_by='-vertfile') parser.add_option(name="-l", mandatory=False, deprecated_by='-vertfile') parser.usage.addSection('SEGMENTATION OPTIONS') parser.add_option(name="-denoising", type_value='multiple_choice', description="1: Adaptative denoising from F. Coupe algorithm, 0: no WARNING: It affects the model you should use (if denoising is applied to the target, the model should have been computed with denoising too)", mandatory=False, default_value=int(ParamData().denoising), example=['0', '1']) parser.add_option(name="-normalization", type_value='multiple_choice', description="Normalization of the target image's intensity using median intensity values of the WM and the GM, recomended with MT images or other types of contrast than T2*", mandatory=False, default_value=int(ParamData().normalization), example=['0', '1']) parser.add_option(name="-p", type_value='str', description="Registration parameters to register the image to segment on the model data. Use the same format as for sct_register_to_template and sct_register_multimodal.", mandatory=False, default_value=ParamData().register_param, example='step=1,type=seg,algo=centermassrot,metric=MeanSquares,smooth=2,iter=1:step=2,type=seg,algo=columnwise,metric=MeanSquares,smooth=3,iter=1:step=3,type=seg,algo=bsplinesyn,metric=MeanSquares,iter=3') parser.add_option(name="-w-levels", type_value='float', description="Weight parameter on the level differences to compute the similarities", mandatory=False, default_value=ParamSeg().weight_level, example=2.0) parser.add_option(name="-w-coordi", type_value='float', description="Weight parameter on the euclidean distance (based on images coordinates in the reduced sapce) to compute the similarities ", mandatory=False, default_value=ParamSeg().weight_coord, example=0.005) parser.add_option(name="-thr-sim", type_value='float', description="Threshold to select the dictionary slices most similar to the slice to segment (similarities are normalized to 1)", mandatory=False, default_value=ParamSeg().thr_similarity, example=0.6) parser.add_option(name="-model", type_value="folder", description="Path to the computed model", mandatory=False, example='/home/jdoe/gm_seg_model/') parser.usage.addSection('\nOUTPUT OTIONS') parser.add_option(name="-res-type", type_value='multiple_choice', description="Type of result segmentation : binary or probabilistic", mandatory=False, default_value=ParamSeg().type_seg, example=['bin', 'prob']) parser.add_option(name="-ratio", type_value='multiple_choice', description="Compute GM/WM CSA ratio by slice or by vertebral level (average across levels)", mandatory=False, default_value=ParamSeg().ratio, example=['0', 'slice', 'level']) parser.add_option(name="-ref", type_value="file", description="Reference segmentation of the gray matter for segmentation validation --> output Dice coefficient and Hausdorff's and median distances)", mandatory=False, example='manual_gm_seg.nii.gz') parser.add_option(name="-ofolder", type_value="folder_creation", description="Output folder", mandatory=False, default_value=ParamSeg().path_results, example='gm_segmentation_results/') parser.usage.addSection('MISC') parser.add_option(name='-qc', type_value='multiple_choice', description='Output images for quality control.', mandatory=False, example=['0', '1'], default_value=str(int(ParamSeg().qc))) parser.add_option(name="-r", type_value="multiple_choice", description='Remove temporary files.', mandatory=False, default_value=str(int(Param().rm_tmp)), example=['0', '1']) parser.add_option(name="-v", type_value='multiple_choice', description="Verbose: 0 = nothing, 1 = classic, 2 = expended", mandatory=False, example=['0', '1', '2'], default_value=str(Param().verbose)) return parser
def main(args=None): if args is None: args = sys.argv[1:] # create param objects param_seg = ParamSeg() param_data = ParamData() param_model = ParamModel() param = Param() # get parser parser = get_parser() arguments = parser.parse(args) # set param arguments ad inputted by user param_seg.fname_im = arguments["-i"] param_seg.fname_im_original = arguments["-i"] param_seg.fname_seg = arguments["-s"] if '-vertfile' in arguments: if sct.extract_fname(arguments['-vertfile'])[1].lower() == "none": param_seg.fname_level = None elif os.path.isfile(arguments['-vertfile']): param_seg.fname_level = arguments['-vertfile'] else: sct.printv(parser.usage.generate(error='ERROR: -vertfile input file: "'+arguments['-vertfile']+'" does not exist.')) if '-denoising' in arguments: param_data.denoising = bool(int(arguments['-denoising'])) if '-normalization' in arguments: param_data.normalization = arguments['-normalization'] if '-p' in arguments: param_data.register_param = arguments['-p'] if '-w-levels' in arguments: param_seg.weight_level = arguments['-w-levels'] if '-w-coordi' in arguments: param_seg.weight_coord = arguments['-w-coordi'] if '-thr-sim' in arguments: param_seg.thr_similarity = arguments['-thr-sim'] if '-model' in arguments: param_model.path_model_to_load = os.path.abspath(arguments['-model']) if '-res-type' in arguments: param_seg.type_seg= arguments['-res-type'] if '-ratio' in arguments: param_seg.ratio = arguments['-ratio'] if '-ref' in arguments: param_seg.fname_manual_gmseg = arguments['-ref'] if '-ofolder' in arguments: param_seg.path_results= arguments['-ofolder'] if '-qc' in arguments: param_seg.qc = bool(int(arguments['-qc'])) if '-r' in arguments: param.rm_tmp= bool(int(arguments['-r'])) if '-v' in arguments: param.verbose= arguments['-v'] seg_gm = SegmentGM(param_seg=param_seg, param_data=param_data, param_model=param_model, param=param) start = time.time() seg_gm.segment() end = time.time() t = end - start printv('Done in ' + str(int(round(t / 60))) + ' min, ' + str(round(t % 60,1)) + ' sec', param.verbose, 'info')