Esempio n. 1
0
def segmentation_smoothing(segmentation, sigma_mm, labels=1, background_label=0,
                   voxelsize_mm=None,
                   volume_blowup=1.,
                   slab=None,
                   volume_blowup_criterial_function=None,
                   ):
    """
    Shape of output segmentation is smoothed with gaussian filter.

    Sigma is computed in mm

    """
    # import scipy.ndimage
    if voxelsize_mm is None:
        voxelsize_mm = np.asarray([1., 1., 1.])

    if volume_blowup_criterial_function is None:
        volume_blowup_criterial_function = __volume_blowup_criterial_function
    sigma = float(sigma_mm) / np.array(voxelsize_mm)

    # print sigma
    # from PyQt4.QtCore import pyqtRemoveInputHook
    # pyqtRemoveInputHook()
    segmentation_selection = ima.select_labels(segmentation, labels=labels, slab=slab)
    vol1 = np.sum(segmentation_selection)
    wvol = vol1 * volume_blowup
    logger.debug('unique segm ' + str(np.unique(segmentation)))
    segsmooth = scipy.ndimage.filters.gaussian_filter(
        segmentation_selection.astype(np.float32), sigma)
    logger.debug('unique segsmooth ' + str(np.unique(segsmooth)))
    # import ipdb; ipdb.set_trace()
    # import pdb; pdb.set_trace()
    # pyed = sed3.sed3(self.orig_scale_segmentation)
    # pyed.show()
    logger.debug('wanted volume ' + str(wvol))
    logger.debug('sigma ' + str(sigma))

    critf = lambda x: volume_blowup_criterial_function(
        x, wvol, segsmooth)

    thr = scipy.optimize.fmin(critf, x0=0.5, disp=False)[0]
    logger.debug('optimal threshold ' + str(thr))
    logger.debug('segsmooth ' + str(np.nonzero(segsmooth)))

    segmentation_selection = (1.0 *
                              (segsmooth > thr)  # self.volume_blowup)
                              ).astype(np.int8)
    vol2 = np.sum(segmentation_selection)
    with np.errstate(divide="ignore", invalid="ignore"):
        logger.debug("volume ratio " + str(vol2 / float(vol1)))
    # import ipdb; ipdb.set_trace()
    segmentation_replacement(
        segmentation,
        label=labels,
        segmentation_new=segmentation_selection,
        background_label=background_label,
        slab=slab,
    )
Esempio n. 2
0
def segmentation_smoothing(segmentation, sigma_mm, labels=1, background_label=0,
                   voxelsize_mm=None,
                   volume_blowup=1.,
                   slab=None,
                   volume_blowup_criterial_function=None,
                   ):
    """
    Shape of output segmentation is smoothed with gaussian filter.

    Sigma is computed in mm

    """
    # import scipy.ndimage
    if voxelsize_mm is None:
        voxelsize_mm = np.asarray([1., 1., 1.])

    if volume_blowup_criterial_function is None:
        volume_blowup_criterial_function = __volume_blowup_criterial_function
    sigma = float(sigma_mm) / np.array(voxelsize_mm)

    # print sigma
    # from PyQt4.QtCore import pyqtRemoveInputHook
    # pyqtRemoveInputHook()
    segmentation_selection = ima.select_labels(segmentation, labels=labels, slab=slab)
    vol1 = np.sum(segmentation_selection)
    wvol = vol1 * volume_blowup
    logger.debug('unique segm ' + str(np.unique(segmentation)))
    segsmooth = scipy.ndimage.filters.gaussian_filter(
        segmentation_selection.astype(np.float32), sigma)
    logger.debug('unique segsmooth ' + str(np.unique(segsmooth)))
    # import ipdb; ipdb.set_trace()
    # import pdb; pdb.set_trace()
    # pyed = sed3.sed3(self.orig_scale_segmentation)
    # pyed.show()
    logger.debug('wanted volume ' + str(wvol))
    logger.debug('sigma ' + str(sigma))

    critf = lambda x: volume_blowup_criterial_function(
        x, wvol, segsmooth)

    thr = scipy.optimize.fmin(critf, x0=0.5, disp=False)[0]
    logger.debug('optimal threshold ' + str(thr))
    logger.debug('segsmooth ' + str(np.nonzero(segsmooth)))

    segmentation_selection = (1.0 *
                              (segsmooth > thr)  # self.volume_blowup)
                              ).astype(np.int8)
    vol2 = np.sum(segmentation_selection)
    with np.errstate(divide="ignore", invalid="ignore"):
        logger.debug("volume ratio " + str(vol2 / float(vol1)))
    # import ipdb; ipdb.set_trace()
    segmentation_replacement(
        segmentation,
        label=labels,
        segmentation_new=segmentation_selection,
        background_label=background_label,
        slab=slab,
    )
Esempio n. 3
0
def segmentation_replacement(segmentation,
                             segmentation_new,
                             label,
                             background_label=0,
                             slab=None,
                             label_new=1):
    """
    Remove label from segmentation and put there a new one.

    :param segmentation:
    :param segmentation_new:
    :param label:
    :param background_label:
    :param slab:
    :param label_new:
    :return:
    """
    segmentation_old = ima.select_labels(segmentation, labels=label, slab=slab)
    segmentation[segmentation_old] = ima.get_nlabels(slab, background_label)
    segmentation_new = ima.select_labels(segmentation_new, label_new)
    segmentation[segmentation_new] = ima.get_nlabels(slab, label)
    return segmentation
Esempio n. 4
0
    def test_branch_labels_with_gui_just_in_module(self):
        import lisa.organ_segmentation

        import io3d

        # datap = io3d.datasets.generate_abdominal()
        datap = io3d.datasets.generate_synthetic_liver(return_dataplus=True)
        oseg = lisa.organ_segmentation.OrganSegmentation()
        oseg.import_dataplus(datap)
        labeled_branches = lisa.virtual_resection.label_volumetric_vessel_tree(
            oseg, "porta")
        data3d = datap["data3d"]
        segmentation = datap["segmentation"]
        slab = datap["slab"]
        organ_label = "liver"

        seeds = np.zeros_like(data3d, dtype=np.int)
        seeds[40, 125, 166] = 1
        seeds[40, 143, 130] = 2
        seeds[40, 125, 115] = 3

        seglabel1 = labeled_branches[seeds == 1][0]
        seglabel2 = labeled_branches[seeds == 2][0]
        seglabel3 = labeled_branches[seeds == 3][0]
        import imma.measure

        import imma.image_manipulation

        import imma.image_manipulation as ima

        # import sed3
        # ed = sed3.sed3(labeled_branches)  # , contour=datap["segmentation"])
        # ed.show()
        organseg = ima.select_labels(segmentation, organ_label, slab)

        organ_split, connected = lisa.virtual_resection.split_tissue_on_labeled_tree(
            labeled_branches, seglabel1, [seglabel2, seglabel3], organseg)

        # import sed3
        # # ed = sed3.sed3(labeled_branches, contour=organ_split)
        # ed = sed3.sed3(organ_split)
        # ed.show()

        self.assertTrue(np.array_equal(np.unique(organ_split), [0, 1, 2]))

        self.assertGreater(np.sum(organ_split == 0), 1000,
                           "At least some background expected")
        self.assertGreater(np.sum(organ_split == 1), 1000,
                           "At least some object expected")
        self.assertGreater(np.sum(organ_split == 2), 1000,
                           "At least some object expected")
Esempio n. 5
0
def segmentation_replacement(
        segmentation,
        segmentation_new,
        label,
        background_label=0,
        slab=None,
        label_new=1
):
    """
    Remove label from segmentation and put there a new one.

    :param segmentation:
    :param segmentation_new:
    :param label:
    :param background_label:
    :param slab:
    :param label_new:
    :return:
    """
    segmentation_old = ima.select_labels(segmentation, labels=label, slab=slab)
    segmentation[segmentation_old] = ima.get_nlabels(slab, background_label)
    segmentation_new = ima.select_labels(segmentation_new, label_new)
    segmentation[segmentation_new] = ima.get_nlabels(slab, label)
    return segmentation
Esempio n. 6
0
def split_organ_by_two_vessels(datap,
                               seeds, organ_label=1,
                               seed_label1=1, seed_label2=2,
                               weight1=1, weight2=1):
    """

    Input of function is ndarray with 2 labeled vessels and data.
    Output is segmented organ by vessls using minimum distance criterium.

    :param datap: dictionary with 3d data, segmentation, and other information
           "data3d": 3d-ndarray with intensity data
           "voxelsize_mm",
           "segmentation": 3d ndarray with image segmentation
           "slab": segmentation labels
    :param seeds: ndarray with same size as data3d
            1: first part of portal vein (or defined in seed1_label)
            2: second part of portal vein (or defined in seed2_label)
    :param weight1: distance weight from seed_label1
    :param weight2: distance weight from seed_label2

    """
    weight1 = 1 if weight1 is None else weight1

    slab = datap["slab"]
    segmentation = datap["segmentation"]
    if type(seed_label1) != list:
        seed_label1 = [seed_label1]
    if type(seed_label2) != list:
        seed_label2 = [seed_label2]
    # dist se tady počítá od nul jenom v jedničkách
    dist1 = scipy.ndimage.distance_transform_edt(
        1 - ima.select_labels(seeds, seed_label1, slab),
        # seeds != seed_label1,
        sampling=datap['voxelsize_mm']
    )
    dist2 = scipy.ndimage.distance_transform_edt(
        1 - ima.select_labels(seeds, seed_label2, slab),
        # seeds != seed_label2,
        sampling=datap['voxelsize_mm']
    )
    # import skfmm
    # dist1 = skfmm.distance(
    #     labeled != l1,
    #     dx=datap['voxelsize_mm']
    # )
    # dist2 = skfmm.distance(
    #     labeled != l2,
    #     dx=datap['voxelsize_mm']
    # )
    # print 'skfmm'
    # from PyQt4.QtCore import pyqtRemoveInputHook; pyqtRemoveInputHook()
    # import ipdb; ipdb.set_trace()

    # from PyQt4.QtCore import pyqtRemoveInputHook
    # pyqtRemoveInputHook()
    # import ipdb; ipdb.set_trace() # BREAKPOINT

    # segm = (dist1 < dist2) * (data['segmentation'] != data['slab']['none'])
    target_organ_segmentation = ima.select_labels(segmentation, organ_label, slab)
    segm = ((target_organ_segmentation * ((dist1 / weight1) > (dist2 / weight2))).astype('int8') +
            target_organ_segmentation.astype('int8'))

    return segm, dist1, dist2
Esempio n. 7
0
def split_tissue_on_labeled_tree(labeled_branches,
                                 trunk_label, branch_labels,
                                 tissue_segmentation, neighbors_list=None,
                                 ignore_labels=None,
                                 ignore_trunk=True,
                                 on_missed_branch="split",

                                 ):
    """
    Based on pre-labeled vessel tree split surrounding tissue into two part.
    The connected sub tree is computed and used internally.

    :param labeled_branches: ndimage with labeled volumetric vessel tree.
    :param trunk_label: int
    :param branch_labels: list of ints
    :param tissue_segmentation: ndimage with bool type. Organ is True, the rest is False.
    :param ignore_trunk: True or False
    :param ignore_labels: list of labels which will be ignored
    :param on_missed_branch: str, ["split", "organ_label", exception]. Missed label is label directly connected
    to trunk but with no branch label inside.
    "split" will ignore mised label.
    "orig" will leave the original area label.
    "exception", will throw the exception.
    :return:
    """
    # bl = lisa.virtual_resection.branch_labels(oseg, "porta")

    import imma.measure
    import imma.image_manipulation
    import imma.image_manipulation as ima

    if ignore_labels is None:
        ignore_labels = []

    ignore_labels = list(ignore_labels)
    if ignore_trunk:
        ignore_labels.append(trunk_label)

    if neighbors_list is None:
        exclude = [0]
        exclude.extend(ignore_labels)
        neighbors_list = imma.measure.neighbors_list(
            labeled_branches,
            None,
            # [seglabel1, seglabel2, seglabel3],
            exclude=exclude)
    #exclude=[imma.image_manipulation.get_nlabels(slab, ["liver"]), 0])
    # ex
    # print(neighbors_list)
    # find whole branche
    # segmentations = [None] * len(branch_labels)
    segmentation = np.zeros_like(labeled_branches, dtype=int)
    new_branches = []
    connected = [None] * len(branch_labels)

    for i, branch_label in enumerate(branch_labels):
        import copy

        ignore_other_branches = copy.copy(branch_labels)
        ignore_other_branches.pop(i)
        ignore_labels_i = [0]
        ignore_labels_i.extend(ignore_other_branches)
        ignore_labels_i.extend(ignore_labels)
        connected_i = imma.measure.get_connected_labels(
            neighbors_list, branch_label, ignore_labels_i)
        # segmentations[i] = ima.select_labels(labeled_branches, connected_i).astype(np.int8)
        select = ima.select_labels(labeled_branches, connected_i).astype(np.int8)
        select = select > 0
        if np.max(segmentation[select]) > 0:
            logger.debug("Missing branch connected to branch and other branch or trunk.")
            union = (segmentation * select) > 0
            segmentation[select] = i + 1
            if on_missed_branch == "split":
                segmentation[union] = 0
            elif on_missed_branch == "orig":
                new_branche_label = len(branch_labels) + len(new_branches) + 1
                logger.debug("new branch label {}".format(new_branche_label))
                segmentation[union] = new_branche_label
                new_branches.append(new_branche_label)
            elif on_missed_branch == "exception":
                raise ValueError("Missing one vessel")
            else:
                raise ValueError("Unknown 'on_missed_label' parameter.")
        else:
            segmentation[select] = i + 1
        # error
        # else:
        #   segmentation[select] = i + 1
        connected[i] = connected_i
    seg = segmentation
    # if np.max(np.sum(segmentations, 0)) > 1:
    #     raise ValueError("Missing one vessel")
    #
    # for i, branch_label in enumerate(branch_labels):
    #     segmentations[i] = segmentations[i] * (i + 1)
    # seg = np.sum(segmentations, 0)

    # ignore_labels1 = [0, trunk_label, branch_label2]
    # ignore_labels1.extend(ignore_labels)
    # ignore_labels2 = [0, trunk_label, branch_label]
    # ignore_labels2.extend(ignore_labels)
    # connected2 = imma.measure.get_connected_labels(
    #     neighbors_list, branch_label, ignore_labels1)
    # connected3 = imma.measure.get_connected_labels(
    #     neighbors_list, branch_label2, ignore_labels2)
    #
    # # seg = ima.select_labels(segmentation, organ_label, slab).astype(np.int8)
    # seg1 = ima.select_labels(labeled_branches, connected2).astype(np.int8)
    # seg2 = ima.select_labels(labeled_branches, connected3).astype(np.int8)
    # seg = seg1 + seg2 * 2
    # if np.max(seg) > 2:
    #     ValueError("Missing one vessel")

    dseg = ima.distance_segmentation(seg)
    logger.debug("output unique labels {}".format(np.unique(dseg)))
    # organseg = ima.select_labels(segmentation, organ_label, slab).astype(np.int8)
    dseg[~tissue_segmentation.astype(np.bool)] = 0

    return dseg, connected
Esempio n. 8
0
def split_vessel(datap, seeds, vessel_volume_threshold=0.95, dilatation_iterations=1, input_label="porta",
                 output_label1 = 1, output_label2 = 2, input_seeds_cut_label=1,
                 input_seeds_separate_label=3,
                 input_seeds_label2=None,
                 method="reach volume",
                 ):
    """

    :param datap: data plus format with data3d, segmentation, slab ...
    :param seeds: 3d ndarray same size as data3d, label 1 is place where should be vessel cuted. Label 2 points to
    the vessel with output label 1 after the segmentation
    :param vessel_volume_threshold: this parameter defines the iteration stop rule if method "reach volume is selected
    :param dilatation_iterations:
    :param input_label: which vessel should be splited
    :param output_label1: output label for vessel part marked with right button (if it is used)
    :param output_label2: ouput label for not-marked vessel part
    :param method: "separate labels" or "reach volume". The first method needs 3 input seeds and it is more stable.
    :param input_seeds_separate_label: after the segmentation the object containing this label in seeds would be labeled with
    output_label1
    :param input_seeds_label2: This parameter is usedf the method is "separate labels". After the
    segmentation the object containing this label in seeds would be labeled with output_label1.
    :return:
    """
    split_obj0 = (seeds == input_seeds_cut_label).astype(np.int8)
    split_obj = split_obj0.copy()


    # numeric_label = imma.get_nlabel(datap["slab"], input_label)
    if method == "separate labels":
        input_label = np.max(datap["segmentation"][seeds == input_seeds_label2])

    vessels = ima.select_labels(datap["segmentation"], input_label, slab=datap["slab"])

    # if type(input_label) is str:
    #     numeric_label = datap['slab'][input_label]
    # else:
    #     numeric_label = input_label
    # vessels = datap['segmentation'] == numeric_label

    vesselstmp = vessels
    sumall = np.sum(vessels == 1)

    # split_obj = scipy.ndimage.binary_dilation(split_obj, iterations = 5 )
    # vesselstmp = vessels * (1 - split_obj)

    lab, n_obj = scipy.ndimage.label(vesselstmp)
    logger.debug("number of objects " + str(n_obj))

    # while n_obj < 2 :
# dokud neni z celkoveho objektu ustipnuto alespon 80 procent
    not_complete = True
    while not_complete:
        if method == "reach volume":
            not_complete = np.sum(lab == qmisc.max_area_index(lab, n_obj)) > (vessel_volume_threshold * sumall)
        elif method == "separate labels":
            # misc.
            # imma.get_nlabel(datap["slab"], )
            # imma.select_labels(seeds,input_seeds_separate_label)
            seglab1 = np.max(lab[seeds == input_seeds_separate_label])
            seglab2 = np.max(lab[seeds == input_seeds_label2])
            if (seglab1 > 0) and (seglab2 > 0) and (seglab1 != seglab2):
                not_complete = False
        else:
            IOError("Unknown method " + str(method))

        split_obj = scipy.ndimage.binary_dilation(split_obj, iterations=dilatation_iterations)
        vesselstmp = vessels * (1 - split_obj)

        lab, n_obj = scipy.ndimage.label(vesselstmp)

    if method == "reach volume":
        # všechny objekty, na které se to rozpadlo
        # pyed = sed3.sed3(lab)
        # pyed.show()
        obj1 = get_biggest_object(lab)

    # vymaz nejvetsiho
        lab[obj1 == 1] = 0
        obj2 = get_biggest_object(lab)

        pixel = 0
        pixels = obj1[seeds == input_seeds_separate_label]
        if len(pixels) > 0:
            pixel = pixels[0]

        # from PyQt4.QtCore import pyqtRemoveInputHook
        # pyqtRemoveInputHook()
        # import ipdb; ipdb.set_trace() # BREAKPOINT

        if pixel > 0:
            ol1 = output_label1
            ol2 = output_label2
        else:
            ol2 = output_label1
            ol1 = output_label2

        # first selected pixel with right button
        lab = ol1 * obj1 + ol2 * obj2
    elif method == "separate labels":
        lab = (lab == seglab1) * output_label1 + (lab == seglab2) * output_label2
    cut_by_user = split_obj0
    return lab, cut_by_user
Esempio n. 9
0
def split_organ_by_two_vessels(datap,
                               seeds,
                               organ_label=1,
                               seed_label1=1,
                               seed_label2=2,
                               weight1=1,
                               weight2=1):
    """

    Input of function is ndarray with 2 labeled vessels and data.
    Output is segmented organ by vessls using minimum distance criterium.

    :param datap: dictionary with 3d data, segmentation, and other information
           "data3d": 3d-ndarray with intensity data
           "voxelsize_mm",
           "segmentation": 3d ndarray with image segmentation
           "slab": segmentation labels
    :param seeds: ndarray with same size as data3d
            1: first part of portal vein (or defined in seed1_label)
            2: second part of portal vein (or defined in seed2_label)
    :param weight1: distance weight from seed_label1
    :param weight2: distance weight from seed_label2

    """
    weight1 = 1 if weight1 is None else weight1

    slab = datap["slab"]
    segmentation = datap["segmentation"]
    if type(seed_label1) != list:
        seed_label1 = [seed_label1]
    if type(seed_label2) != list:
        seed_label2 = [seed_label2]
    # dist se tady počítá od nul jenom v jedničkách
    dist1 = scipy.ndimage.distance_transform_edt(
        1 - ima.select_labels(seeds, seed_label1, slab),
        # seeds != seed_label1,
        sampling=datap['voxelsize_mm'])
    dist2 = scipy.ndimage.distance_transform_edt(
        1 - ima.select_labels(seeds, seed_label2, slab),
        # seeds != seed_label2,
        sampling=datap['voxelsize_mm'])
    # import skfmm
    # dist1 = skfmm.distance(
    #     labeled != l1,
    #     dx=datap['voxelsize_mm']
    # )
    # dist2 = skfmm.distance(
    #     labeled != l2,
    #     dx=datap['voxelsize_mm']
    # )
    # print 'skfmm'
    # from PyQt4.QtCore import pyqtRemoveInputHook; pyqtRemoveInputHook()
    # import ipdb; ipdb.set_trace()

    # from PyQt4.QtCore import pyqtRemoveInputHook
    # pyqtRemoveInputHook()
    # import ipdb; ipdb.set_trace() # BREAKPOINT

    # segm = (dist1 < dist2) * (data['segmentation'] != data['slab']['none'])
    target_organ_segmentation = ima.select_labels(segmentation, organ_label,
                                                  slab)
    segm = ((target_organ_segmentation * ((dist1 / weight1) >
                                          (dist2 / weight2))).astype('int8') +
            target_organ_segmentation.astype('int8'))

    return segm, dist1, dist2
Esempio n. 10
0
def split_tissue_on_bifurcation(
    labeled_branches,
    trunk_label,
    branch_labels,
    tissue_segmentation,
    neighbors_list=None,
    ignore_labels=None,
    ignore_trunk=True,
):
    """
    Based on pre-labeled vessel tree split surrounding tissue into two part.
    The connected sub tree is computed and used internally.

    :param labeled_branches: ndimage with labeled volumetric vessel tree.
    :param trunk_label: int
    :param branch_labels: list of ints
    :param tissue_segmentation: ndimage with bool type. Organ is True, the rest is False.
    :param ignore_trunk: True or False
    :param ignore_labels: list of labels which will be ignored
    :return:
    """
    # bl = lisa.virtual_resection.branch_labels(oseg, "porta")

    import imma.measure
    import imma.image_manipulation
    import imma.image_manipulation as ima

    if ignore_labels is None:
        ignore_labels = []

    ignore_labels = list(ignore_labels)
    if ignore_trunk:
        ignore_labels.append(trunk_label)

    if neighbors_list is None:
        exclude = [0]
        exclude.extend(ignore_labels)
        neighbors_list = imma.measure.neighbors_list(
            labeled_branches,
            None,
            # [seglabel1, seglabel2, seglabel3],
            exclude=exclude)
    #exclude=[imma.image_manipulation.get_nlabels(slab, ["liver"]), 0])
    # ex
    # print(neighbors_list)
    # find whole branche
    segmentations = [None] * len(branch_labels)
    connected = [None] * len(branch_labels)

    for i, branch_label in enumerate(branch_labels):
        import copy

        ignore_other_branches = copy.copy(branch_labels)
        ignore_other_branches.pop(i)
        ignore_labels_i = [0]
        ignore_labels_i.extend(ignore_other_branches)
        ignore_labels_i.extend(ignore_labels)
        connected_i = imma.measure.get_connected_labels(
            neighbors_list, branch_label, ignore_labels_i)
        segmentations[i] = ima.select_labels(labeled_branches,
                                             connected_i).astype(np.int8)
        connected[i] = connected_i

    if np.max(np.sum(segmentations, 0)) > 1:
        ValueError("Missing one vessel")

    for i, branch_label in enumerate(branch_labels):
        segmentations[i] = segmentations[i] * (i + 1)
    seg = np.sum(segmentations, 0)

    # ignore_labels1 = [0, trunk_label, branch_label2]
    # ignore_labels1.extend(ignore_labels)
    # ignore_labels2 = [0, trunk_label, branch_label]
    # ignore_labels2.extend(ignore_labels)
    # connected2 = imma.measure.get_connected_labels(
    #     neighbors_list, branch_label, ignore_labels1)
    # connected3 = imma.measure.get_connected_labels(
    #     neighbors_list, branch_label2, ignore_labels2)
    #
    # # seg = ima.select_labels(segmentation, organ_label, slab).astype(np.int8)
    # seg1 = ima.select_labels(labeled_branches, connected2).astype(np.int8)
    # seg2 = ima.select_labels(labeled_branches, connected3).astype(np.int8)
    # seg = seg1 + seg2 * 2
    # if np.max(seg) > 2:
    #     ValueError("Missing one vessel")

    dseg = ima.distance_segmentation(seg)
    # organseg = ima.select_labels(segmentation, organ_label, slab).astype(np.int8)
    dseg[~tissue_segmentation.astype(np.bool)] = 0

    return dseg, connected
Esempio n. 11
0
def split_vessel(
    datap,
    seeds,
    vessel_volume_threshold=0.95,
    dilatation_iterations=1,
    input_label="porta",
    output_label1=1,
    output_label2=2,
    input_seeds_cut_label=1,
    input_seeds_separate_label=3,
    input_seeds_label2=None,
    method="reach volume",
):
    """

    :param datap: data plus format with data3d, segmentation, slab ...
    :param seeds: 3d ndarray same size as data3d, label 1 is place where should be vessel cuted. Label 2 points to
    the vessel with output label 1 after the segmentation
    :param vessel_volume_threshold: this parameter defines the iteration stop rule if method "reach volume is selected
    :param dilatation_iterations:
    :param input_label: which vessel should be splited
    :param output_label1: output label for vessel part marked with right button (if it is used)
    :param output_label2: ouput label for not-marked vessel part
    :param method: "separate labels" or "reach volume". The first method needs 3 input seeds and it is more stable.
    :param input_seeds_separate_label: after the segmentation the object containing this label in seeds would be labeled with
    output_label1
    :param input_seeds_label2: This parameter is usedf the method is "separate labels". After the
    segmentation the object containing this label in seeds would be labeled with output_label1.
    :return:
    """
    split_obj0 = (seeds == input_seeds_cut_label).astype(np.int8)
    split_obj = split_obj0.copy()

    # numeric_label = imma.get_nlabel(datap["slab"], input_label)
    if method == "separate labels":
        input_label = np.max(
            datap["segmentation"][seeds == input_seeds_label2])

    vessels = ima.select_labels(datap["segmentation"],
                                input_label,
                                slab=datap["slab"])

    # if type(input_label) is str:
    #     numeric_label = datap['slab'][input_label]
    # else:
    #     numeric_label = input_label
    # vessels = datap['segmentation'] == numeric_label

    vesselstmp = vessels
    sumall = np.sum(vessels == 1)

    # split_obj = scipy.ndimage.binary_dilation(split_obj, iterations = 5 )
    # vesselstmp = vessels * (1 - split_obj)

    lab, n_obj = scipy.ndimage.label(vesselstmp)
    logger.debug("number of objects " + str(n_obj))

    # while n_obj < 2 :
    # dokud neni z celkoveho objektu ustipnuto alespon 80 procent
    not_complete = True
    while not_complete:
        if method == "reach volume":
            not_complete = np.sum(lab == qmisc.max_area_index(lab, n_obj)) > (
                vessel_volume_threshold * sumall)
        elif method == "separate labels":
            # misc.
            # imma.get_nlabel(datap["slab"], )
            # imma.select_labels(seeds,input_seeds_separate_label)
            seglab1 = np.max(lab[seeds == input_seeds_separate_label])
            seglab2 = np.max(lab[seeds == input_seeds_label2])
            if (seglab1 > 0) and (seglab2 > 0) and (seglab1 != seglab2):
                not_complete = False
        else:
            IOError("Unknown method " + str(method))

        split_obj = scipy.ndimage.binary_dilation(
            split_obj, iterations=dilatation_iterations)
        vesselstmp = vessels * (1 - split_obj)

        lab, n_obj = scipy.ndimage.label(vesselstmp)

    if method == "reach volume":
        # všechny objekty, na které se to rozpadlo
        # pyed = sed3.sed3(lab)
        # pyed.show()
        obj1 = get_biggest_object(lab)

        # vymaz nejvetsiho
        lab[obj1 == 1] = 0
        obj2 = get_biggest_object(lab)

        pixel = 0
        pixels = obj1[seeds == input_seeds_separate_label]
        if len(pixels) > 0:
            pixel = pixels[0]

        # from PyQt4.QtCore import pyqtRemoveInputHook
        # pyqtRemoveInputHook()
        # import ipdb; ipdb.set_trace() # BREAKPOINT

        if pixel > 0:
            ol1 = output_label1
            ol2 = output_label2
        else:
            ol2 = output_label1
            ol1 = output_label2

        # first selected pixel with right button
        lab = ol1 * obj1 + ol2 * obj2
    elif method == "separate labels":
        lab = (lab == seglab1) * output_label1 + (lab
                                                  == seglab2) * output_label2
    cut_by_user = split_obj0
    return lab, cut_by_user
Esempio n. 12
0
def split_tissue_on_labeled_tree(labeled_branches,
                                 trunk_label, branch_labels,
                                 tissue_segmentation, neighbors_list=None,
                                 ignore_labels=None,
                                 ignore_trunk=True,
                                 on_missed_branch="split",

                                 ):
    """
    Based on pre-labeled vessel tree split surrounding tissue into two part.
    The connected sub tree is computed and used internally.

    :param labeled_branches: ndimage with labeled volumetric vessel tree.
    :param trunk_label: int
    :param branch_labels: list of ints
    :param tissue_segmentation: ndimage with bool type. Organ is True, the rest is False.
    :param ignore_trunk: True or False
    :param ignore_labels: list of labels which will be ignored
    :param on_missed_branch: str, ["split", "organ_label", exception]. Missed label is label directly connected
    to trunk but with no branch label inside.
    "split" will ignore mised label.
    "orig" will leave the original area label.
    "exception", will throw the exception.
    :return:
    """
    # bl = lisa.virtual_resection.branch_labels(oseg, "porta")

    import imma.measure
    import imma.image_manipulation
    import imma.image_manipulation as ima

    if ignore_labels is None:
        ignore_labels = []

    ignore_labels = list(ignore_labels)
    if ignore_trunk:
        ignore_labels.append(trunk_label)

    if neighbors_list is None:
        exclude = [0]
        exclude.extend(ignore_labels)
        neighbors_list = imma.measure.neighbors_list(
            labeled_branches,
            None,
            # [seglabel1, seglabel2, seglabel3],
            exclude=exclude)
    #exclude=[imma.image_manipulation.get_nlabels(slab, ["liver"]), 0])
    # ex
    # print(neighbors_list)
    # find whole branche
    # segmentations = [None] * len(branch_labels)
    segmentation = np.zeros_like(labeled_branches, dtype=int)
    new_branches = []
    connected = [None] * len(branch_labels)

    for i, branch_label in enumerate(branch_labels):
        import copy

        ignore_other_branches = copy.copy(branch_labels)
        ignore_other_branches.pop(i)
        ignore_labels_i = [0]
        ignore_labels_i.extend(ignore_other_branches)
        ignore_labels_i.extend(ignore_labels)
        connected_i = imma.measure.get_connected_labels(
            neighbors_list, branch_label, ignore_labels_i)
        # segmentations[i] = ima.select_labels(labeled_branches, connected_i).astype(np.int8)
        select = ima.select_labels(labeled_branches, connected_i).astype(np.int8)
        select = select > 0
        if np.max(segmentation[select]) > 0:
            logger.debug("Missing branch connected to branch and other branch or trunk.")
            union = (segmentation * select) > 0
            segmentation[select] = i + 1
            if on_missed_branch == "split":
                segmentation[union] = 0
            elif on_missed_branch == "orig":
                new_branche_label = len(branch_labels) + len(new_branches) + 1
                logger.debug("new branch label {}".format(new_branche_label))
                segmentation[union] = new_branche_label
                new_branches.append(new_branche_label)
            elif on_missed_branch == "exception":
                raise ValueError("Missing one vessel")
            else:
                raise ValueError("Unknown 'on_missed_label' parameter.")
        else:
            segmentation[select] = i + 1
        # error
        # else:
        #   segmentation[select] = i + 1
        connected[i] = connected_i
    seg = segmentation
    # if np.max(np.sum(segmentations, 0)) > 1:
    #     raise ValueError("Missing one vessel")
    #
    # for i, branch_label in enumerate(branch_labels):
    #     segmentations[i] = segmentations[i] * (i + 1)
    # seg = np.sum(segmentations, 0)

    # ignore_labels1 = [0, trunk_label, branch_label2]
    # ignore_labels1.extend(ignore_labels)
    # ignore_labels2 = [0, trunk_label, branch_label]
    # ignore_labels2.extend(ignore_labels)
    # connected2 = imma.measure.get_connected_labels(
    #     neighbors_list, branch_label, ignore_labels1)
    # connected3 = imma.measure.get_connected_labels(
    #     neighbors_list, branch_label2, ignore_labels2)
    #
    # # seg = ima.select_labels(segmentation, organ_label, slab).astype(np.int8)
    # seg1 = ima.select_labels(labeled_branches, connected2).astype(np.int8)
    # seg2 = ima.select_labels(labeled_branches, connected3).astype(np.int8)
    # seg = seg1 + seg2 * 2
    # if np.max(seg) > 2:
    #     ValueError("Missing one vessel")

    dseg = ima.distance_segmentation(seg)
    logger.debug("output unique labels {}".format(np.unique(dseg)))
    # organseg = ima.select_labels(segmentation, organ_label, slab).astype(np.int8)
    dseg[~tissue_segmentation.astype(np.bool)] = 0

    return dseg, connected