def main(): #logger = logging.getLogger(__name__) logger = logging.getLogger() logger.setLevel(logging.WARNING) ch = logging.StreamHandler() logger.addHandler(ch) #logger.debug('input params') print 'version: ', qmisc.getVersionString() ### # Configuration is has three sources: # * Default function values # * Config file 'organ_segmentation.config' in directory with application # * Config file 'organ_segmentation.config' in output data directory # # It is read in this order so the last one has highest priority ### ## read confguraton from file, use default values from OrganSegmentation cfgplus = { 'datapath': None, 'viewermax': 300, 'viewermin': -100, 'output_datapath': os.path.expanduser("~/lisa_data"), 'lisa_operator_identifier': "", 'experiment_caption': '' } cfg = config.get_default_function_config(OrganSegmentation.__init__) cfg.update(cfgplus) # now is in cfg default values cfg = config.get_config("organ_segmentation.config", cfg) # read user defined config in user data cfg = config.get_config( os.path.join(cfg['output_datapath'], "organ_segmentation.config"), cfg ) # input parser parser = argparse.ArgumentParser( description='Segment vessels from liver \n\ \npython organ_segmentation.py\n\ \npython organ_segmentation.py -mroi -vs 0.6') parser.add_argument('-dd', '--datapath', default=cfg["datapath"], help='path to data dir') parser.add_argument('-d', '--debug', action='store_true', help='run in debug mode') parser.add_argument( '-vs', '--working_voxelsize_mm', default=cfg["working_voxelsize_mm"], type=eval, # type=str, help='Insert working voxelsize. It can be number or \ array of three numbers. It is possible use original \n \ resolution or half of original resolution. \n \ -vs 3 \n \ -vs [3,3,5] \n \ -vs orig \n \ -vs orig*2 \n \ -vs orig*4 \n \ ' ) parser.add_argument('-mroi', '--manualroi', action='store_true', help='manual crop before data processing', default=cfg["manualroi"]) parser.add_argument('-op', '--output_datapath', default=cfg["output_datapath"], help='path for output data') parser.add_argument('-ol', '--output_label', default=1, help='label for segmented data') parser.add_argument( '--slab', default=cfg["slab"], type=eval, help='labels for segmentation,\ example -slab "{\'liver\':1, \'lesions\':6}"') parser.add_argument( '-acr', '--autocrop', help='automatic crop after data processing', default=cfg["autocrop"]) parser.add_argument( '-iparams', '--iparams', default=None, help='filename of ipars file with stored interactivity') parser.add_argument( '-sp', '--segparams', type=eval, default=cfg["segparams"], help='params for segmentation,\ example -sp "{\'pairwise_alpha_per_mm2\':90}"') parser.add_argument( '-tx', '--texture_analysis', action='store_true', help='run with texture analysis') parser.add_argument('-exd', '--exampledata', action='store_true', help='run unittest') parser.add_argument('-ed', '--edit_data', action='store_true', help='Run data editor') parser.add_argument( '-vmax', '--viewermax', type=eval, # type=int, help='Maximum of viewer window, set None for automatic maximum.', default=cfg["viewermax"]) parser.add_argument( '-vmin', '--viewermin', type=eval, # type=int, help='Minimum of viewer window, set None for automatic minimum.', default=cfg["viewermin"]) parser.add_argument( '-so', '--show_output', action='store_true', help='Show output data in viewer') parser.add_argument('-a', '--arg', nargs='+', type=float) parser.add_argument( '-ec', '--experiment_caption', type=str, # type=int, help='Short caption of experiment. No special characters.', default=cfg["experiment_caption"]) parser.add_argument( '-oi', '--lisa_operator_identifier', type=str, # type=int, help='Identifier of Lisa operator.', default=cfg["experiment_caption"]) parser.add_argument( '-ss', '--segmentation_smoothing', action='store_true', help='Smoothing of output segmentation', default=cfg["segmentation_smoothing"] ) args_obj = parser.parse_args() args = vars(args_obj) #print args["arg"] oseg_argspec_keys = config.get_function_keys(OrganSegmentation.__init__) # voxelsize_mm can be number or array #if args.voxelsize_mm != 'orig': #TODO easy way to set half of resolution # if isinstance(args["working_voxelsize_mm"], numbers.Number) # if args["working_voxelsize_mm"] == -1: # args["working_voxelsize_mm"] = 'orig' ## todo and so on # if not args["working_voxelsize_mm"].startswith('orig'): # #import pdb; pdb.set_trace() # args["working_voxelsize_mm"] = eval(args["working_voxelsize_mm"]) # #args["segparams"] = eval(args["segparams"]) #args["slab"] = eval(args["slab"]) #args["viewermin"] = eval(args["viewermin"]) #args["viewermax"] = eval(args["viewermax"]) if args["debug"]: logger.setLevel(logging.DEBUG) if args["exampledata"]: args["datapath"] = '../sample_data/\ matlab/examples/sample_data/DICOM/digest_article/' if args["iparams"] is not None: iparams = misc.obj_from_file(args["iparams"], filetype='pickle') oseg = OrganSegmentation(**iparams) else: #else: #dcm_read_from_dir('/home/mjirik/data/medical/data_orig/46328096/') #data3d, metadata = dcmreaddata.dcm_read_from_dir() data3d, metadata, qt_app = readData3d(args["datapath"]) args['datapath'] = metadata['datadir'] oseg_params = config.subdict(args, oseg_argspec_keys) oseg_params["data3d"] = data3d oseg_params["metadata"] = metadata oseg_params['qt_app'] = qt_app oseg = OrganSegmentation(**oseg_params) oseg.interactivity(args["viewermin"], args["viewermax"]) #igc = pycut.ImageGraphCut(data3d, zoom = 0.5) #igc.interactivity() #igc.make_gc() #igc.show_segmentation() # volume #volume_mm3 = np.sum(oseg.segmentation > 0) * np.prod(oseg.voxelsize_mm) audiosupport.beep() print( "Volume " + str(oseg.get_segmented_volume_size_mm3() / 1000000.0) + ' [l]') #pyed = py3DSeedEditor.py3DSeedEditor(oseg.data3d, contour = # oseg.segmentation) #pyed.show() print("Total time: " + str(oseg.processing_time)) if args["show_output"]: oseg.show_output() #print savestring save_outputs(args, oseg, qt_app) # import pdb; pdb.set_trace() return
def save_outputs(args, oseg, qt_app): from PyQt4.QtGui import QInputDialog savestring_qt, ok = QInputDialog.getText( None, "Save", 'Save output data? Yes/No/All+Dicom with input data (y/n/a/ad):', text="a" ) savestring = str(savestring_qt) #import pdb; pdb.set_trace() #savestring = raw_input( # 'Save output data? Yes/No/All with input data (y/n/a): ' #) if savestring in ['Y', 'y', 'a', 'A', 'ad']: if not os.path.exists(args["output_datapath"]): os.makedirs(args['output_datapath']) op = args['output_datapath'] # rename data = oseg.export() data['version'] = qmisc.getVersionString() data['experiment_caption'] = args['experiment_caption'] data['lisa_operator_identifier'] = args['lisa_operator_identifier'] #data['organ_segmentation_time'] = t1 iparams = oseg.get_iparams() #import pdb; pdb.set_trace() pth, filename = os.path.split(os.path.normpath(args['datapath'])) filename += "-" + args['experiment_caption'] if savestring in ['a', 'A', 'ad']: # save renamed file too filepath = 'ob-' + filename + '.pklz' filepath = os.path.join(op, filepath) filepath = misc.suggest_filename(filepath) misc.obj_to_file(data, filepath, filetype='pklz') filepath = 'organ.pklz' filepath = os.path.join(op, filepath) #filepath = misc.suggest_filename(filepath) misc.obj_to_file(data, filepath, filetype='pklz') filepath = 'organ_iparams.pklz' filepath = os.path.join(op, filepath) misc.obj_to_file(iparams, filepath, filetype='pklz') data['data3d'] = None filepath = 'organ_small-' + filename + '.pklz' filepath = os.path.join(op, filepath) filepath = misc.suggest_filename(filepath) misc.obj_to_file(data, filepath, filetype='pklz') #output = segmentation.vesselSegmentation(oseg.data3d, # oseg.orig_segmentation) # print "uf" if savestring in ['ad']: # save to DICOM filepath = 'dicom-' + filename filepath = os.path.join(op, filepath) filepath = misc.suggest_filename(filepath) output_dicom_dir = filepath #import ipdb; ipdb.set_trace() # BREAKPOINT overlays = { 3: (data['segmentation'] == args['output_label']).astype(np.int8) } saveOverlayToDicomCopy(oseg.metadata['dcmfilelist'], output_dicom_dir, overlays, data['crinfo'], data['orig_shape'])
def __init__( self, datapath=None, working_voxelsize_mm=3, viewermax=None, viewermin=None, series_number=None, autocrop=True, autocrop_margin_mm=[10, 10, 10], manualroi=False, texture_analysis=None, segmentation_smoothing=False, smoothing_mm=4, volume_blowup=1.00, data3d=None, metadata=None, seeds=None, edit_data=False, segparams={}, segmodelparams=default_segmodelparams, roi=None, output_label=1, slab={}, output_datapath=None, input_datapath_start='', experiment_caption='', lisa_operator_identifier='', volume_unit='ml', save_filetype='pklz', # iparams=None, ): """ Segmentation of objects from CT data. datapath: path to directory with dicom files manualroi: manual set of ROI before data processing, there is a problem with correct coordinates data3d, metadata: it can be used for data loading not from directory. If both are setted, datapath is ignored output_label: label for output segmented volume slab: aditional label system for description segmented data {'none':0, 'liver':1, 'lesions':6} roi: region of interest. [[startx, stopx], [sty, spy], [stz, spz]] seeds: ndimage array with size same as data3d experiment_caption = this caption is used for naming of outputs lisa_operator_identifier: used for logging input_datapath_start: Path where user directory selection dialog starts. volume_blowup: Blow up volume is computed in smoothing so it is working only if smoothing is turned on. """ self.iparams = {} self.datapath = datapath self.output_datapath = output_datapath self.input_datapath_start = input_datapath_start self.crinfo = [[0, -1], [0, -1], [0, -1]] self.slab = slab self.output_label = output_label self.working_voxelsize_mm = None self.input_wvx_size = working_voxelsize_mm # print segparams # @TODO each axis independent alpha self.segparams = default_segparams self.segparams.update(segparams) self.segmodelparams = default_segmodelparams self.segmodelparams.update(segmodelparams) self.series_number = series_number self.autocrop = autocrop self.autocrop_margin_mm = np.array(autocrop_margin_mm) self.texture_analysis = texture_analysis self.segmentation_smoothing = segmentation_smoothing self.smoothing_mm = smoothing_mm self.volume_blowup = volume_blowup self.edit_data = edit_data self.roi = roi self.data3d = data3d self.seeds = seeds self.segmentation = None self.processing_time = None self.experiment_caption = experiment_caption self.lisa_operator_identifier = lisa_operator_identifier self.version = qmisc.getVersionString() self.viewermax = viewermax self.viewermin = viewermin self.volume_unit = volume_unit self.organ_interactivity_counter = 0 self.dcmfilelist = None self.save_filetype = save_filetype # oseg_input_params = locals() oseg_input_params = self.__clean_oseg_input_params(oseg_input_params) logger.debug("oseg_input_params") logger.debug(str(oseg_input_params)) self.oseg_input_params = oseg_input_params if data3d is None or metadata is None: # if 'datapath' in self.iparams: # datapath = self.iparams['datapath'] if datapath is not None: reader = datareader.DataReader() datap = reader.Get3DData(datapath, dataplus_format=True) # self.iparams['series_number'] = metadata['series_number'] # self.iparams['datapath'] = datapath self.import_dataplus(datap) else: # data will be selected from gui pass # logger.error('No input path or 3d data') else: # self.data3d = data3d # default values are updated in next line mindatap = {'series_number': -1, 'voxelsize_mm': 1, 'datapath': None, 'data3d': data3d } mindatap.update(metadata) self.import_dataplus(mindatap)
def __init__( self, datapath=None, working_voxelsize_mm=3, viewermax=None, viewermin=None, series_number=None, autocrop=True, autocrop_margin_mm=[10, 10, 10], manualroi=False, texture_analysis=None, segmentation_smoothing=False, smoothing_mm=4, volume_blowup=1.00, data3d=None, metadata=None, seeds=None, edit_data=False, segparams={}, segmodelparams=default_segmodelparams, roi=None, output_label=1, slab={}, output_datapath=None, input_datapath_start='', experiment_caption='', lisa_operator_identifier='', volume_unit='ml', save_filetype='pklz', debug_mode=False, seg_postproc_pars={}, cache_filename='cache.yml', seg_preproc_pars={}, # iparams=None, ): """ Segmentation of objects from CT data. :param datapath: path to directory with dicom files :param manualroi: manual set of ROI before data processing, there is a problem with correct coordinates :param data3d, metadata: it can be used for data loading not from directory. If both are setted, datapath is ignored :param output_label: label for output segmented volume :param slab: aditional label system for description segmented data {'none':0, 'liver':1, 'lesions':6} :param roi: region of interest. [[startx, stopx], [sty, spy], [stz, spz]] :param seeds: ndimage array with size same as data3d :param experiment_caption = this caption is used for naming of outputs :param lisa_operator_identifier: used for logging :param input_datapath_start: Path where user directory selection dialog starts. :param volume_blowup: Blow up volume is computed in smoothing so it is working only if smoothing is turned on. :param seg_postproc_pars: Can be used for setting postprocessing parameters. For example """ self.iparams = {} self.datapath = datapath self.output_datapath = output_datapath self.input_datapath_start = input_datapath_start self.crinfo = [[0, None], [0, None], [0, None]] self.slab = data_plus.default_slab() self.slab.update(slab) self.output_label = output_label self.working_voxelsize_mm = None self.input_wvx_size = working_voxelsize_mm # print segparams # @TODO each axis independent alpha self.segparams = default_segparams self.segparams.update(segparams) self.segmodelparams = default_segmodelparams self.segmodelparams.update(segmodelparams) self.series_number = series_number self.autocrop = autocrop self.autocrop_margin_mm = np.array(autocrop_margin_mm) self.texture_analysis = texture_analysis self.segmentation_smoothing = segmentation_smoothing self.smoothing_mm = smoothing_mm self.volume_blowup = volume_blowup self.edit_data = edit_data self.roi = roi self.data3d = data3d self.seeds = seeds self.segmentation = None self.processing_time = None self.experiment_caption = experiment_caption self.lisa_operator_identifier = lisa_operator_identifier self.version = qmisc.getVersionString() self.viewermax = viewermax self.viewermin = viewermin self.volume_unit = volume_unit self.organ_interactivity_counter = 0 self.dcmfilelist = None self.save_filetype = save_filetype self.vessel_tree = {} self.debug_mode = debug_mode # SegPostprocPars = namedtuple( # 'SegPostprocPars', [ # 'smoothing_mm', # 'segmentation_smoothing', # 'volume_blowup', # 'snakes', # 'snakes_method', # 'snakes_params'] # ) self.cache = cachef.CacheFile(cache_filename) self.seg_postproc_pars = { 'smoothing_mm': smoothing_mm, 'segmentation_smoothing': segmentation_smoothing, 'volume_blowup': volume_blowup, 'snakes': False, 'snakes_method': 'ACWE', 'snakes_params': {'smoothing': 1, 'lambda1': 100, 'lambda2': 1}, 'snakes_niter': 20, } self.seg_postproc_pars.update(seg_postproc_pars) self.seg_preproc_pars = { 'use_automatic_segmentation': True, } self.seg_preproc_pars.update(seg_preproc_pars) # seg_postproc_pars.update(seg_postproc_pars) # import ipdb; ipdb.set_trace() # noqa BREAKPOINT # self.seg_postproc_pars = SegPostprocPars(**seg_postproc_pars_default) # oseg_input_params = locals() oseg_input_params = self.__clean_oseg_input_params(oseg_input_params) logger.debug("oseg_input_params") logger.debug(str(oseg_input_params)) self.oseg_input_params = oseg_input_params if data3d is None or metadata is None: # if 'datapath' in self.iparams: # datapath = self.iparams['datapath'] if datapath is not None: reader = datareader.DataReader() datap = reader.Get3DData(datapath, dataplus_format=True) # self.iparams['series_number'] = metadata['series_number'] # self.iparams['datapath'] = datapath self.import_dataplus(datap) else: # self.data3d = data3d # default values are updated in next line mindatap = {'series_number': -1, 'voxelsize_mm': 1, 'datapath': None, 'data3d': data3d } mindatap.update(metadata) self.import_dataplus(mindatap)
def test_getVersionString(self): """ """ verstr = qmisc.getVersionString() self.assertTrue(type(verstr) == str)