def distance_matrics(vol1, vol2, voxelsize_mm): # crop data to reduce comutation time crinfo = qmisc.crinfo_from_specific_data(vol1, CROP_MARGIN) logger.debug(str(crinfo) + ' m1 ' + str(np.max(vol1)) + ' m2 ' + str(np.min(vol2))) logger.debug("crinfo " + str(crinfo)) vol1 = qmisc.crop(vol1, crinfo) vol2 = qmisc.crop(vol2, crinfo) border1 = get_border(vol1) border2 = get_border(vol2) #pyed = py3DSeedEditor.py3DSeedEditor(vol1, contour=vol1) #pyed.show() b1dst = scipy.ndimage.morphology.distance_transform_edt( 1 - border1, sampling=voxelsize_mm ) dst_b1_to_b2 = border2 * b1dst #import ipdb; ipdb.set_trace() # BREAKPOINT #pyed = py3DSeedEditor.py3DSeedEditor(dst_b1_to_b2, contour=vol1) #pyed.show() #print np.nonzero(border1) # avgd = np.average(dst_b1_to_b2[np.nonzero(border2)]) avgd = np.average(dst_b1_to_b2[border2]) rmsd = np.average(dst_b1_to_b2[border2] ** 2) maxd = np.max(dst_b1_to_b2) return avgd, rmsd, maxd
def distance_matrics(vol1, vol2, voxelsize_mm): # crop data to reduce comutation time crinfo = qmisc.crinfo_from_specific_data(vol1 + vol2, CROP_MARGIN) logger.debug(str(crinfo) + ' m1 ' + str(np.max(vol1)) + ' m2 ' + str(np.min(vol2))) logger.debug("crinfo " + str(crinfo)) vol1 = qmisc.crop(vol1, crinfo) vol2 = qmisc.crop(vol2, crinfo) border1 = get_border(vol1) border2 = get_border(vol2) # pyed = sed3.sed3(vol1, contour=vol1) # pyed.show() b1dst = scipy.ndimage.morphology.distance_transform_edt( 1 - border1, sampling=voxelsize_mm ) b2dst = scipy.ndimage.morphology.distance_transform_edt( 1 - border2, sampling=voxelsize_mm ) dst_b1_to_b2 = border2 * b1dst dst_b2_to_b1 = border1 * b2dst dst_12 = dst_b1_to_b2[border2] dst_21 = dst_b2_to_b1[border1] dst_both = np.append(dst_12, dst_21) # sum_d12 = np.sum(dst_12) # sum_d21 = np.sum(dst_21) # len_d12 = len(dst_12) # len_d21 = len(dst_21) # import ipdb; ipdb.set_trace() # BREAKPOINT # pyed = sed3.sed3(dst_b1_to_b2, contour=vol1) # pyed.show() # print np.nonzero(border1) # avgd = np.average(dst_b1_to_b2[np.nonzero(border2)]) # import ipdb; ipdb.set_trace() # noqa BREAKPOINT # avgd = (sum_d21 + sum_d12)/float(len_d21 + len_d12) # rmsd = ((np.sum(dst_12**2) + dst_21**2)/float(len_d21 + len_d12))**0.5 avgd = np.average(dst_both) # there is not clear what is correct # rmsd = np.average(dst_both ** 2)**0.5 # rmsd = (np.average(dst_12) + np.average(dst_21))**0.5 rmsd = np.average(dst_both ** 2) # rmsd = np.average(dst_b1_to_b2[border2] ** 2) maxd = max(np.max(dst_b1_to_b2), np.max(dst_b2_to_b1)) # old # avgd = np.average(dst_b1_to_b2[border2]) # rmsd = np.average(dst_b1_to_b2[border2] ** 2) # maxd = np.max(dst_b1_to_b2) return avgd, rmsd, maxd
def distance_matrics(vol1, vol2, voxelsize_mm): # crop data to reduce comutation time crinfo = qmisc.crinfo_from_specific_data(vol1 + vol2, CROP_MARGIN) logger.debug(str(crinfo) + ' m1 ' + str(np.max(vol1)) + ' m2 ' + str(np.min(vol2))) logger.debug("crinfo " + str(crinfo)) vol1 = qmisc.crop(vol1, crinfo) vol2 = qmisc.crop(vol2, crinfo) border1 = _get_border(vol1) border2 = _get_border(vol2) # pyed = sed3.sed3(vol1, contour=vol1) # pyed.show() b1dst = scipy.ndimage.morphology.distance_transform_edt( 1 - border1, sampling=voxelsize_mm ) b2dst = scipy.ndimage.morphology.distance_transform_edt( 1 - border2, sampling=voxelsize_mm ) dst_b1_to_b2 = border2 * b1dst dst_b2_to_b1 = border1 * b2dst dst_12 = dst_b1_to_b2[border2] dst_21 = dst_b2_to_b1[border1] dst_both = np.append(dst_12, dst_21) # sum_d12 = np.sum(dst_12) # sum_d21 = np.sum(dst_21) # len_d12 = len(dst_12) # len_d21 = len(dst_21) # import ipdb; ipdb.set_trace() # BREAKPOINT # pyed = sed3.sed3(dst_b1_to_b2, contour=vol1) # pyed.show() # print np.nonzero(border1) # avgd = np.average(dst_b1_to_b2[np.nonzero(border2)]) # import ipdb; ipdb.set_trace() # noqa BREAKPOINT # avgd = (sum_d21 + sum_d12)/float(len_d21 + len_d12) # rmsd = ((np.sum(dst_12**2) + dst_21**2)/float(len_d21 + len_d12))**0.5 avgd = np.average(dst_both) # there is not clear what is correct # rmsd = np.average(dst_both ** 2)**0.5 # rmsd = (np.average(dst_12) + np.average(dst_21))**0.5 rmsd = np.average(dst_both ** 2) # rmsd = np.average(dst_b1_to_b2[border2] ** 2) maxd = max(np.max(dst_b1_to_b2), np.max(dst_b2_to_b1)) # old # avgd = np.average(dst_b1_to_b2[border2]) # rmsd = np.average(dst_b1_to_b2[border2] ** 2) # maxd = np.max(dst_b1_to_b2) return avgd, rmsd, maxd
def crop(self, tmpcrinfo): """ Function makes crop of 3d data and seeds and stores it in crinfo. tmpcrinfo: temporary crop information """ # print ('sedds ', str(self.seeds.shape), ' se ', # str(self.segmentation.shape), ' d3d ', str(self.data3d.shape)) self.data3d = qmisc.crop(self.data3d, tmpcrinfo) # No, size of seeds should be same as data3d if self.seeds is not None: self.seeds = qmisc.crop(self.seeds, tmpcrinfo) if self.segmentation is not None: self.segmentation = qmisc.crop(self.segmentation, tmpcrinfo) self.crinfo = qmisc.combinecrinfo(self.crinfo, tmpcrinfo) logger.debug("crinfo " + str(self.crinfo))
def test_multiple_crop_and_uncrop(self): """ test combination of multiple crop """ shape = [10, 10, 5] img_in = np.random.random(shape) crinfo1 = [[2, 8], [3, 9], [2, 5]] crinfo2 = [[2, 5], [1, 4], [1, 2]] img_cropped = qmisc.crop(img_in, crinfo1) img_cropped = qmisc.crop(img_cropped, crinfo2) crinfo_combined = qmisc.combinecrinfo(crinfo1, crinfo2) img_uncropped = qmisc.uncrop(img_cropped, crinfo_combined, shape) self.assertTrue(img_uncropped[4, 4, 3] == img_in[4, 4, 3])
def test_crop_and_uncrop(self): shape = [10, 10, 5] img_in = np.random.random(shape) crinfo = [[2, 8], [3, 9], [2, 5]] img_cropped = qmisc.crop(img_in, crinfo) img_uncropped = qmisc.uncrop(img_cropped, crinfo, shape) self.assertTrue(img_uncropped[4, 4, 3] == img_in[4, 4, 3])
def import_segmentation_from_file(self, filepath): """ Loads data from file. Expected are uncropped data. """ # logger.debug("import segmentation from file") # logger.debug(str(self.crinfo)) reader = datareader.DataReader() datap = reader.Get3DData(filepath, dataplus_format=True) segmentation = datap['data3d'] segmentation = qmisc.crop(segmentation, self.crinfo) logger.debug(str(segmentation.shape)) self.segmentation = segmentation
def sliver_compare_with_other_volume(self, segmentation_datap): """ Compares actual Lisa data with other which are given by segmentation_datap. That means segmentation_datap = { 'segmentation': 3d np.array, 'crinfo': information about crop (optional) } """ # if there is no segmentation, data can be stored in data3d. It is the # way how are data stored in sliver. if 'segmentation' in segmentation_datap.keys(): segm_key = 'segmentation' else: segm_key = 'data3d' if 'crinfo' in segmentation_datap.keys(): data3d_segmentation = qmisc.uncrop( segmentation_datap[segm_key], segmentation_datap['crinfo'], self.orig_shape) else: data3d_segmentation = segmentation_datap[segm_key] pass # now we can uncrop actual Lisa data data3d_segmentation_actual = qmisc.uncrop( self.segmentation, self.crinfo, self.orig_shape) evaluation = volumetry_evaluation.compare_volumes( data3d_segmentation_actual, data3d_segmentation, self.voxelsize_mm ) score = volumetry_evaluation.sliver_score_one_couple(evaluation) segdiff = qmisc.crop( ((data3d_segmentation) - data3d_segmentation_actual), self.crinfo) return evaluation, score, segdiff
def train_one(self, data,voxelSize_mm): """ Trenovani shape modelu data se vezmou a oriznou (jen jatra) na oriznuta data je aplikovo binarni otevreni - rychlejsi nez morphsnakes co vznikne je uhlazena cast ktera se odecte od puvodniho obrazu cimz vzniknou spicky orezany obraz se nasledne rozparceluje podle velikosti (shape) modelu pokud pocet voxelu v danem useku prekroci danou mez, je modelu prirazena nejaka hodnota. Meze jsou nasledujici: 0%-50% => 1 50%-75% => 2 75%-100% => 3 """ crinfo = qmisc.crinfo_from_specific_data(data, margin=self.model_margin) datacr = qmisc.crop(data, crinfo=crinfo) dataShape = self.model.shape datacrres = self.trainThresholdMap(datacr, voxelSize_mm, dataShape) self.model += datacrres self.data_number += 1
def _crop(self, data, crinfo): """ Crop data with crinfo.""" data = qmisc.crop(data, crinfo) #data[crinfo[0][0]:crinfo[0][1], # crinfo[1][0]:crinfo[1][1], crinfo[2][0]:crinfo[2][1]] return data
def __init__( self, datapath=None, working_voxelsize_mm=3, series_number=None, autocrop=True, autocrop_margin_mm=[10, 10, 10], manualroi=False, texture_analysis=None, segmentation_smoothing=False, smoothing_mm=4, data3d=None, metadata=None, seeds=None, edit_data=False, segparams={}, roi=None, # iparams=None, output_label=1, slab={}, qt_app=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} """ self.iparams = {} self.datapath = datapath self.crinfo = [[0, -1], [0, -1], [0, -1]] self.slab = slab self.output_label = output_label self.qt_app = qt_app # TODO uninteractive Serie selection if data3d is None or metadata is None: #if self.iparams.has_key('datapath'): if 'datapath' in self.iparams: datapath = self.iparams['datapath'] #self.data3d, self.metadata = dcmr.dcm_read_from_dir(datapath) if datapath is None: self.process_qt_app() datapath = dcmr.get_dcmdir_qt(self.qt_app) # @TODO dialog v qt #reader = dcmr.DicomReader(datapath) # , qt_app=qt_app) #self.data3d = reader.get_3Ddata() #self.metadata = reader.get_metaData() reader = datareader.DataReader() self.data3d, self.metadata = reader.Get3DData(datapath) self.iparams['series_number'] = self.metadata['series_number'] self.iparams['datapath'] = datapath else: self.data3d = data3d # default values are updated in next line self.metadata = {'series_number': -1, 'voxelsize_mm': 1, 'datapath': None} self.metadata.update(metadata) self.iparams['series_number'] = self.metadata['series_number'] self.iparams['datapath'] = self.metadata['datapath'] self.orig_shape = self.data3d.shape # voxelsize processing if working_voxelsize_mm == 'orig': working_voxelsize_mm = self.metadata['voxelsize_mm'] elif working_voxelsize_mm == 'orig*2': working_voxelsize_mm = np.array(self.metadata['voxelsize_mm']) * 2 elif working_voxelsize_mm == 'orig*4': working_voxelsize_mm = np.array(self.metadata['voxelsize_mm']) * 4 if np.isscalar(working_voxelsize_mm): self.working_voxelsize_mm = ([working_voxelsize_mm] * 3) else: self.working_voxelsize_mm = working_voxelsize_mm self.working_voxelsize_mm = np.array( self.working_voxelsize_mm).astype(float) # if np.isscalar(self.working_voxelsize_mm): # self.working_voxelsize_mm = (np.ones([3]) * #self.working_voxelsize_mm).astype(float) self.iparams['working_voxelsize_mm'] = self.working_voxelsize_mm #self.parameters = {} #self.segparams = {'pairwiseAlpha':2, 'use_boundary_penalties':True, #'boundary_penalties_sigma':50} # for each mm on boundary there will be sum of penalty equal 10 self.segparams = {'pairwise_alpha_per_mm2': 10, 'use_boundary_penalties': False, 'boundary_penalties_sigma': 50} self.segparams = {'pairwise_alpha_per_mm2': 40, 'use_boundary_penalties': False, 'boundary_penalties_sigma': 50} #print segparams # @TODO each axis independent alpha self.segparams.update(segparams) self.segparams['pairwise_alpha'] = \ self.segparams['pairwise_alpha_per_mm2'] / \ np.mean(self.iparams['working_voxelsize_mm']) #self.segparams['pairwise_alpha']=25 # parameters with same effect as interactivity #if iparams is None: # self.iparams= {} #else: # self.set_iparams(iparams) # manualcrop if manualroi is True: # is not None: # @todo opravit souřadný systém v součinnosti s autocrop self.process_qt_app() self.data3d, self.crinfo = qmisc.manualcrop(self.data3d) self.iparams['roi'] = self.crinfo self.iparams['manualroi'] = True #print self.crinfo elif roi is not None: self.data3d = qmisc.crop(self.data3d, roi) self.crinfo = roi self.iparams['roi'] = roi self.iparams['manualroi'] = None if seeds is None: self.iparams['seeds'] = np.zeros(self.data3d.shape, dtype=np.int8) else: if qmisc.isSparseMatrix(seeds): seeds = seeds.todense() self.iparams['seeds'] = seeds self.voxelsize_mm = np.array(self.metadata['voxelsize_mm']) self.autocrop = autocrop self.autocrop_margin_mm = np.array(autocrop_margin_mm) self.autocrop_margin = self.autocrop_margin_mm / self.voxelsize_mm self.texture_analysis = texture_analysis self.segmentation_smoothing = segmentation_smoothing self.smoothing_mm = smoothing_mm self.edit_data = edit_data self.zoom = self.voxelsize_mm / (1.0 * self.working_voxelsize_mm) # def set_iparams(self, iparams): # """ # Set interactivity variables. Make numpy array from scipy sparse # matrix. # """ # # # seeds may be stored in sparse matrix # try: # if qmisc.SparseMatrix.issparse(iparams['seeds']): # iparams['seeds'] = iparams['seeds'].todense() # #import pdb; pdb.set_trace() # except: # # patrne neni SparseMatrix # pass # # self.iparams = iparams # @TODO use logger print 'dir ', self.iparams['datapath'], ", series_number",\ self.iparams['series_number'], 'voxelsize_mm',\ self.voxelsize_mm self.time_start = time.time()
def resection_portal_vein_new(data, interactivity=False, seeds=None, label=10, vein=6, **kwargs): """ New function for portal vein segmentation :param data: :param interactivity: :param seeds: :param kwargs: :return: """ # ed = sed3.sed3(a) # ed.show() # from PyQt4 import QtGui # from PyQt4.QtGui import QApplication, QMainWindow, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, QFrame, \ # QFont, QPixmap, QFileDialog # # window = QtGui.QWidget() # mainLayout = QVBoxLayout() # window.setLayout(mainLayout) # mainLayout.addWidget(sed3.sed3qtWidget(data['data3d'], contour=data['segmentation'])) # zachovani puvodnich dat segmentation = data["segmentation"] data3d = data["data3d"] # data pouze se segmentacemi segm = ((data["segmentation"] == label) * label + (data["segmentation"] == vein) * vein) # ufiknutí segmentace crinfo = qmisc.crinfo_from_specific_data(segm, [0]) data["segmentation"] = qmisc.crop(segm, crinfo) data["data3d"] = qmisc.crop(data3d, crinfo) # @TODO zde nahradit střeve čímkoliv smysluplnějším if interactivity: print("Select cut") # seeds = cut_editor_old(data) seeds = cut_editor_old(data) elif seeds is None: logger.error('seeds is None and interactivity is False') return None lab, cut = split_vessel(data, seeds) segm, dist1, dist2 = split_organ_by_two_vessels(data, lab) # jatra rozdeleny na 3 kusy a = morphology.label(segm, background=0) ### podmínka nefunguje if 3 in a: # zda se v segmentaci objevuje 3. cast print "slape :) :) :P" a_index = velikosti(segm) print a_index i = nejnizsi(a_index[0], a_index[1], a_index[2]) segm = ((a == i) * (segm == 1).astype('int8') + (a != i) * (segm == 2).astype('int8') + (segm != 0).astype('int8')) # TODO split this function from visualization data = virtual_resection_visualization(data, segm, dist1, dist2, cut, interactivity=interactivity) # vrácení původních dat a spojení s upravenými daty data["data3d"] = data3d data["segmentation"] = qmisc.uncrop( data["segmentation"], crinfo, (len(segmentation), len(segmentation[0]), len(segmentation[0]))) #segmentation = segmentation == vein data["segmentation"] = ( data["segmentation"] + (segmentation != label) * segmentation) - (segmentation == vein) * vein return data