Example #1
0
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
Example #2
0
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
Example #3
0
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
Example #4
0
    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))
Example #5
0
    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])
Example #6
0
    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])
Example #7
0
 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
Example #8
0
    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
Example #9
0
    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
Example #10
0
    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
Example #11
0
 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
Example #12
0
    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()
Example #13
0
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