Example #1
0
def lap_waterhsed_intensity(img,
                            holder,
                            DEBRISAREA=50,
                            BLUR=2,
                            MAXSIZE=5000,
                            OPENING=0,
                            THRES=0.01,
                            SEPARATE=3,
                            FILTERINGSIZE=20,
                            RATIO=1,
                            MIN_SIGMA=8,
                            MAX_SIGMA=12,
                            CIRC_THRES=0.8):
    '''
    Approximate sigma is given by sigma=radius/sqrt(2).
    MIN_SIGMA, MAX_SIGMA, SEPARATE are important to deal with oversegmentation...
    '''
    img = gaussian_filter(img, BLUR)
    foreground = extract_foreground_adaptive(img, RATIO, FILTERINGSIZE)
    sigma_list = range(int(MIN_SIGMA), int(MAX_SIGMA))
    local_maxima = lap_local_max(img, sigma_list, THRES)
    local_maxima[-foreground] = 0
    local_maxima = skilabel(peak_local_max_edge(local_maxima, SEPARATE))
    label = sitk_watershed_intensity(img, local_maxima)
    label = sizefilter_for_label(label, DEBRISAREA, MAXSIZE, OPENING)
    label = circularity_thresh(label, CIRC_THRES)
    label = skilabel(clear_border(label, buffer_size=2))
    return label
Example #2
0
def label_high_pass(img, slen=3, SIGMA=0.5, THRES=50, CLOSE=3):
    """For Salmonella"""
    cc = calc_high_pass(img, slen, SIGMA)
    cc[cc < 0] = 0
    la = skilabel(cc > THRES, conn=1)
    la = closing(la, disk(CLOSE))
    return la
Example #3
0
def logglobal(img,
              holder,
              DEBRISAREA=50,
              MAXSIZE=1000,
              OPENING=2,
              NUCRAD=10,
              magnitude=2,
              SHRINK=0,
              REGWSHED=10,
              HPASS=2.5,
              GLAP=3,
              CIRC_THRESH=0.8):
    logimg = np.log(img)
    highpassImg = highpassfilter(logimg, NUCRAD * HPASS)
    sharpLogimg = logimg + magnitude * highpassImg
    lapSharpLogimg = gaussian_laplace(sharpLogimg, NUCRAD / GLAP)
    lapSharpLogimg = lapSharpLogimg - lapSharpLogimg.min()
    lapSharpLogimg = lapSharpLogimg.max() - lapSharpLogimg
    img = lapSharpLogimg
    global_thresh = skifilter.threshold_otsu(img)
    bw = img > global_thresh
    bw = sizefilterandopen(bw, DEBRISAREA, MAXSIZE, OPENING)
    if SHRINK > 0:
        bw = binary_erosion(bw, np.ones((SHRINK, SHRINK)))
    label = devide_and_label_objects(bw, REGWSHED)
    label = sizefilter_for_label(label, DEBRISAREA, MAXSIZE, OPENING)
    label = circularity_thresh(label, CIRC_THRES)
    label = skilabel(clear_border(label, buffer_size=2))
    return label
Example #4
0
def lapgauss_constant(img,
                      holder,
                      SIGMA=2.5,
                      DEBRISAREA=50,
                      MAXSIZE=1000,
                      OPENING=2,
                      SHRINK=0,
                      REGWSHED=10,
                      THRES=0.3,
                      COPEN=1,
                      THINERODE=4,
                      CIRC_THRES=0.8):
    cimg = calc_lapgauss(img, SIGMA)
    bw = cimg > THRES
    bw = binary_fill_holes(bw)
    bw = skimorph.remove_small_objects(bw, DEBRISAREA, connectivity=4)
    bw = binary_opening(bw, np.ones((COPEN, COPEN)))
    bw = remove_thin_objects(bw, THINERODE)
    bw = sizefilterandopen(bw, DEBRISAREA, MAXSIZE, OPENING)
    if SHRINK > 0:
        bw = binary_erosion(bw, np.ones((SHRINK, SHRINK)))
    label = devide_and_label_objects(bw, REGWSHED)
    label = sizefilter_for_label(label, DEBRISAREA, MAXSIZE, OPENING)
    label = circularity_thresh(label, CIRC_THRES)
    label = skilabel(clear_border(label, buffer_size=2))
    return label
Example #5
0
def constant_lap_edge(img,
                      holder,
                      DEBRISAREA=50,
                      MAXSIZE=1000,
                      OPENING=2,
                      NUCRAD=6,
                      MAGNITUDE=2,
                      SHRINK=0,
                      REGWSHED=10,
                      FILTERSIZE=1,
                      THRES=4,
                      HPASS=8,
                      CIRC_THRES=0.8):
    img = gaussian_filter(img, FILTERSIZE)
    edge = enhance_edges(img, HPASS, NUCRAD)
    logimg = np.log(img) - edge * MAGNITUDE
    bw = logimg > THRES
    bw = binary_fill_holes(bw)
    if SHRINK > 0:
        bw = binary_erosion(bw, np.ones((SHRINK, SHRINK)))
    if OPENING != 0:  # added by KL
        bw = binary_opening(bw, np.ones((OPENING, OPENING)),
                            iterations=1)  #added by KL
    label = devide_and_label_objects(bw, REGWSHED)
    label = sizefilter_for_label(label, DEBRISAREA, MAXSIZE, OPENING)
    label = circularity_thresh(label, CIRC_THRES)
    label = skilabel(clear_border(label, buffer_size=2))
    return label
def logadaptivegauss(img,
                     holder,
                     DEBRISAREA=50,
                     MAXSIZE=1000,
                     OPENING=2,
                     magnitude=2,
                     NUCRAD=10,
                     FILTERINGSIZE=100,
                     T=10,
                     SHRINK=0,
                     REGWSHED=10,
                     GLAP=3,
                     HPASS=2.5):
    logimg = np.log(img)
    highpassImg = highpassfilter(logimg, NUCRAD * HPASS)
    sharpLogimg = logimg + magnitude * highpassImg
    lapSharpLogimg = gaussian_laplace(sharpLogimg, NUCRAD / GLAP)
    lapSharpLogimg = lapSharpLogimg - lapSharpLogimg.min()
    lapSharpLogimg = lapSharpLogimg.max() - lapSharpLogimg
    img = lapSharpLogimg

    fim = gaussian_filter(img, FILTERINGSIZE)
    bw = img > fim * (1. + T / 100.)
    bw = sizefilterandopen(bw, DEBRISAREA, MAXSIZE, OPENING)
    if SHRINK > 0:
        bw = binary_erosion(bw, np.ones((SHRINK, SHRINK)))
    label = devide_and_label_objects(bw, REGWSHED)
    label = sizefilter_for_label(label, DEBRISAREA, MAXSIZE, OPENING)
    label = skilabel(clear_border(label, buffer_size=2))
    return label
Example #7
0
def lapgauss_adaptive(img,
                      holder,
                      RATIO=3.0,
                      FILTERINGSIZE=50,
                      SIGMA=2.5,
                      DEBRISAREA=50,
                      MAXSIZE=1000,
                      OPENING=2,
                      SHRINK=0,
                      REGWSHED=10,
                      COPEN=1,
                      THINERODE=4,
                      CIRC_THRES=0.8):
    bw = extract_foreground_adaptive(img, RATIO, FILTERINGSIZE)
    cimg = calc_lapgauss(img, SIGMA)
    bw[cimg > 0] = 0
    bw = binary_fill_holes(bw)
    bw = skimorph.remove_small_objects(bw, DEBRISAREA, connectivity=4)
    bw = binary_opening(bw, np.ones((int(COPEN), int(COPEN))))
    bw = remove_thin_objects(bw, THINERODE)
    bw = sizefilterandopen(bw, DEBRISAREA, MAXSIZE, OPENING)
    if SHRINK > 0:
        bw = binary_erosion(bw, np.ones((SHRINK, SHRINK)))
    label = devide_and_label_objects(bw, REGWSHED)
    label = sizefilter_for_label(label, DEBRISAREA, MAXSIZE, OPENING)
    label = circularity_thresh(label, CIRC_THRES)
    label = skilabel(clear_border(label, buffer_size=2))
    return label
Example #8
0
def remove_thin_objects(bw, THINERODE):
    label = skilabel(bw)
    erod_label = grey_erosion(label, THINERODE)
    unq_label = np.unique(label)
    unq_erod_label = np.unique(erod_label)
    thinobj_id = [i for i in unq_label if i not in unq_erod_label]
    for i in thinobj_id:
        bw[label == i] = 0
    return bw
Example #9
0
def example_thres(img, holder, THRES=100):
    """take pixel above THRES as a foreground.

    Examples:
        >>> img = np.zeros((3, 3))
        >>> img[0, 0] = 10
        >>> img[2, 2] = 10
        >>> example_thres(img, None, THRES=5)
        array([[1, 0, 0],
               [0, 0, 0],
               [0, 0, 2]])
    """
    return skilabel(img > THRES)
Example #10
0
def lap_local_max(img, sigma_list, THRES):
    img = np.uint16(img)
    lapimages = []
    for sig in sigma_list:
        simg = sitk.GetImageFromArray(img)
        nimg = sitk.LaplacianRecursiveGaussian(image1=simg, sigma=sig)
        lapimages.append(-sitk.GetArrayFromImage(nimg))

    image_cube = np.dstack(lapimages)
    local_maxima = peak_local_max(image_cube, threshold_abs=THRES, footprint=np.ones((3, 3, 3)),threshold_rel=0.0,exclude_border=False, indices=False)

    local_maxima = local_maxima.sum(axis=2)
    local_maxima = skilabel(local_maxima)
    return local_maxima
Example #11
0
def lap_local_max(img, sigma_list, MIN_DIST, REL_THRES):
    img = np.uint16(img)
    lapimages = []
    for sig in sigma_list:
        simg = sitk.GetImageFromArray(img)
        nimg = sitk.LaplacianRecursiveGaussian(image1=simg, sigma=sig)
        lapimages.append(-sitk.GetArrayFromImage(nimg))

    image_cube = np.dstack(lapimages)
    local_maxima = peak_local_max(image_cube, min_distance=MIN_DIST, threshold_rel=REL_THRES,
                                  exclude_border=False, indices=False)

    local_maxima = local_maxima.sum(axis=2)
    local_maxima = skilabel(local_maxima)
    return local_maxima
Example #12
0
def adaptivethreshwithglobal_neckcut(img,
                                     holder,
                                     ADAPTIVEBLOCK=21,
                                     DEBRISAREA=50,
                                     MAXSIZE=1000,
                                     OPENING=2,
                                     FILTERSIZE=1,
                                     THRESHRELATIVE=1,
                                     SHRINK=0,
                                     REGWSHED=10,
                                     THRES_ANGLE=181,
                                     EDGELEN=5):
    img = gaussian_filter(img, FILTERSIZE)
    global_thresh = skifilter.threshold_otsu(img)
    bw = skifilter.threshold_adaptive(img, ADAPTIVEBLOCK, 'gaussian')
    bw = bw * img > global_thresh * THRESHRELATIVE
    bw = sizefilterandopen(bw, DEBRISAREA, MAXSIZE, OPENING)
    if SHRINK > 0:
        bw = binary_erosion(bw, np.ones((SHRINK, SHRINK)))
    label = devide_and_label_objects(bw, REGWSHED)

    cl_label = clear_border(label)
    outlines = labels2outlines(cl_label)
    rps = regionprops(outlines)
    good_coords = []
    for cell in rps:
        score, coords = calc_neck_score_thres(cell.coords,
                                              edgelen=EDGELEN,
                                              thres=THRES_ANGLE)

        if len(score) > 1:
            r0, c0 = coords[0, :]
            # Find candidates
            for cand in coords[1:, :]:
                cut_label = cut_neck(cl_label == cell.label, r0, c0, cand[0],
                                     cand[1])
                cand_label = skilabel(cut_label)
                cand_rps = regionprops(cand_label)
                cand_rps = [i for i in cand_rps if i.area > DEBRISAREA]
                if len(cand_rps) > 1:
                    good_coords.append([r0, c0, cand[0], cand[1]])
                    break
        # Reflect cut in the label
        for gc in good_coords:
            cut_neck(label, *gc)
    return label
Example #13
0
def watershed_distance(img, label, container, holder, ERODI=5,
                       DEBRISAREA=50, DISPLACEMENT=50, MASSTHRES=0.2):
    '''watershed existing label, meaning make a cut at the deflection.
    After the cuts, objects will be linked if they are within DISPLACEMENT and MASSTHRES.
    If two candidates are found, it will pick a closer one.

    Args:
    ERODI (int):        Erosion size element for generating watershed seeds.
                        Smaller ERODI will allow more cuts.
    DISPLACEMENT (int): The maximum distance (in pixel)
    MASSTHRES (float):  The maximum difference of total intensity changes.
                        0.2 means it allows for 20% total intensity changes.
    '''

    untr_prev, untr_curr = container.unlinked
    mask_untracked = container._label_untracked.astype(bool)
    wshed_label = watershed(mask_untracked, ERODI)
    wshed_label = skilabel(sizefilterandopen(wshed_label, DEBRISAREA, np.Inf, 0))
    newcells = CellListMaker(img, wshed_label, holder, holder.frame).make_list()
    distanceUntracked = _distance_diff(untr_prev, newcells)
    masschangeUntracked = _totalintensity_difference(untr_prev, newcells)

    withinarea = distanceUntracked < DISPLACEMENT
    withinmass = abs(masschangeUntracked) < MASSTHRES
    withinareaMass = withinarea * withinmass

    withinareaMass = pick_closer_binarycostmat(withinareaMass, distanceUntracked)
    good_curr_idx, good_prev_idx = find_one_to_one_assign(withinareaMass)

    # update the link
    for ci, pi in zip(good_curr_idx, good_prev_idx):
        untr_prev[pi].next = newcells[ci]
    # Get all linear coordinates from good newly segmented cells
    good_curr_coords = [newcells[n].prop.coords for n in good_curr_idx]
    lin_curr_coords = [convert_coords_to_linear(i, holder.img_shape) for i in flatlist(good_curr_coords)]
    # find cells in old mask (in current) that overlaps with good new cells
    old_cells_to_remove, lin_old_coords_remove = find_coords_overlap_coords(untr_curr, lin_curr_coords, holder.img_shape)
    # find cells in new mask which overlaps with the cells in old mask
    newcells_to_update = find_cells_overlap_linear_coords(newcells, lin_old_coords_remove, holder.img_shape)
    # remove old cells
    for old_cell in old_cells_to_remove:
        container.curr_cells.remove(old_cell)
    # add new cells
    container.curr_cells.extend(newcells_to_update)
    return container
def global_otsu(img,
                holder,
                FILTERSIZE=1,
                DEBRISAREA=50,
                MAXSIZE=1000,
                OPENING=2,
                SHRINK=0,
                REGWSHED=10):
    img = gaussian_filter(img, FILTERSIZE)
    global_thresh = skifilter.threshold_otsu(img)
    bw = img > global_thresh
    bw = sizefilterandopen(bw, DEBRISAREA, MAXSIZE, OPENING)
    if SHRINK > 0:
        bw = binary_erosion(bw, np.ones((SHRINK, SHRINK)))
    label = devide_and_label_objects(bw, REGWSHED)
    label = sizefilter_for_label(label, DEBRISAREA, MAXSIZE, OPENING)
    label = skilabel(clear_border(label, buffer_size=2))
    return label
Example #15
0
def repair_sal(img,
               pimg,
               comb,
               pcomb,
               label,
               nuc_prop,
               nuc_loc,
               THRESCHANGE=1000):
    # repair
    prev = regionprops(pcomb, pimg, cache=False)
    prev_label = [i.label for i in prev]
    curr = regionprops(comb, img, cache=False)
    curr_label = [i.label for i in curr]

    store = []
    for cell in curr:
        curr_sig = cell.mean_intensity * cell.area
        if cell.label in prev_label:
            p_cell = prev[prev_label.index(cell.label)]
            prev_sig = p_cell.mean_intensity * p_cell.area
        else:
            break
        if np.any(label == cell.label):
            store.append(curr_sig - prev_sig)
        if judge_bad(curr_sig, prev_sig, THRESCHANGE):  # or diff ratio?
            for rp in regionprops(skilabel(label == cell.label),
                                  img,
                                  cache=False):
                dist = pairwise_distance((rp.centroid, ), nuc_loc)[0]
                for num in range(1, 4):
                    neighbor_nuc = nuc_prop[np.argsort(dist)[num]]
                    neiid = neighbor_nuc.label
                    nei_curr = curr[curr_label.index(neiid)]
                    if neiid not in prev_label:
                        break
                    nei_prev = prev[prev_label.index(neiid)]
                    nei_curr_sig = nei_curr.mean_intensity * nei_curr.area
                    nei_prev_sig = nei_prev.mean_intensity * nei_prev.area
                    if judge_bad(nei_curr_sig, nei_prev_sig, THRESCHANGE):
                        label[rp.coords[:, 0], rp.coords[:, 1]] = neiid
                        break
                    else:
                        pass
    return label
def adaptivethresh2blocks(img,
                          holder,
                          ADAPTIVEBLOCK=21,
                          DEBRISAREA=50,
                          MAXSIZE=1000,
                          OPENING=2,
                          FILTERSIZE=1,
                          SHRINK=0,
                          REGWSHED=10):
    img = gaussian_filter(img, FILTERSIZE)
    bw = skifilter.threshold_adaptive(img, ADAPTIVEBLOCK, 'gaussian')
    bw2 = skifilter.threshold_adaptive(img, img.shape[0] / 4, 'gaussian')
    bw = bw * bw2
    bw = sizefilterandopen(bw, DEBRISAREA, MAXSIZE, OPENING)
    if SHRINK > 0:
        bw = binary_erosion(bw, np.ones((SHRINK, SHRINK)))
    label = devide_and_label_objects(bw, REGWSHED)
    label = sizefilter_for_label(label, DEBRISAREA, MAXSIZE, OPENING)
    label = skilabel(clear_border(label, buffer_size=2))
    return label
def adaptivethreshwithglobal(img,
                             holder,
                             ADAPTIVEBLOCK=21,
                             DEBRISAREA=50,
                             MAXSIZE=1000,
                             OPENING=2,
                             FILTERSIZE=1,
                             THRESHRELATIVE=1,
                             SHRINK=0,
                             REGWSHED=10):
    img = gaussian_filter(img, FILTERSIZE)
    global_thresh = skifilter.threshold_otsu(img)
    bw = skifilter.threshold_adaptive(img, ADAPTIVEBLOCK, 'gaussian')
    bw = bw * img > global_thresh * THRESHRELATIVE
    bw = sizefilterandopen(bw, DEBRISAREA, MAXSIZE, OPENING)
    if SHRINK > 0:
        bw = binary_erosion(bw, np.ones((SHRINK, SHRINK)))
    label = devide_and_label_objects(bw, REGWSHED)
    label = sizefilter_for_label(label, DEBRISAREA, MAXSIZE, OPENING)
    label = skilabel(clear_border(label, buffer_size=2))
    return label
Example #18
0
def devide_and_label_objects(bw, REGWSHED):
    label = skilabel(bw).astype(np.int64)
    if REGWSHED > 0:
        label = watershed(label, REGWSHED)
    return label
def track_neck_cut(img,
                   label,
                   container,
                   holder,
                   ERODI=5,
                   DEBRISAREA=50,
                   DISPLACEMENT=50,
                   MASSTHRES=0.2,
                   LIM=10,
                   EDGELEN=5,
                   THRES_ANGLE=180,
                   STEPLIM=10):
    """
        Adaptive segmentation by using tracking informaiton.
        Separate two objects by making a cut at the deflection. For each points on the outline,
        it will make a triangle separated by EDGELEN and calculates the angle facing inside of concave.

        EDGELEN (int):      A length of edges of triangle on the nuclear perimeter.
        THRES_ANGLE (int):  Define the neck points if a triangle has more than this angle.
        STEPLIM (int):      points of neck needs to be separated by at least STEPLIM in parimeters.
        """

    untr_prev, untr_curr = container.unlinked
    label_untracked = container._label_untracked
    unique_labels = np.unique(label_untracked)
    unique_labels = unique_labels[unique_labels > 0]
    newcells = []
    all_new_cells = []
    for label_id in unique_labels:
        mask = label_untracked == label_id
        cl_label = clear_border(mask)
        outlines = labels2outlines(cl_label).astype(np.uint16)
        rps = regionprops(outlines)
        rps = [i for i in rps if i.perimeter > STEPLIM]
        for cell in rps:
            score, coords = calc_neck_score_thres_filtered(cell.coords,
                                                           edgelen=EDGELEN,
                                                           thres=THRES_ANGLE,
                                                           steplim=STEPLIM)
            if len(score) > 1:
                r0, c0 = coords[0, :]
                if coords.shape[0] > LIM:
                    coords = coords[:LIM, :]
                for cand in coords[1:, :]:
                    untr_prev = container.unlinked[0]

                    cut_label = skilabel(cut_neck(cl_label, r0, c0, cand[0],
                                                  cand[1]),
                                         conn=1)
                    new_cells_temp = CellListMaker(img, cut_label, holder,
                                                   holder.frame).make_list()
                    if len(new_cells_temp) > 1:
                        distanceUntracked = _distance_diff(
                            untr_prev, new_cells_temp)
                        masschangeUntracked = _totalintensity_difference(
                            untr_prev, new_cells_temp)

                        withinarea = distanceUntracked < DISPLACEMENT
                        withinmass = abs(masschangeUntracked) < MASSTHRES
                        withinareaMass = withinarea * withinmass

                        withinareaMass = pick_closer_binarycostmat(
                            withinareaMass, distanceUntracked)
                        good_curr_idx, good_prev_idx = find_one_to_one_assign(
                            withinareaMass)
                        if len(good_curr_idx) > 0:
                            # update the link
                            all_new_cells.append(new_cells_temp)
                            for ci, pi in zip(good_curr_idx, good_prev_idx):
                                newcells.append(new_cells_temp[ci])
                                untr_prev[pi].next = new_cells_temp[ci]
                            break

    good_curr_coords = [n.prop.coords for n in newcells]
    lin_curr_coords = [
        convert_coords_to_linear(i, holder.img_shape)
        for i in flatlist(good_curr_coords)
    ]
    # find cells in old mask (in current) that overlaps with good new cells
    old_cells_to_remove, lin_old_coords_remove = find_coords_overlap_coords(
        untr_curr, lin_curr_coords, holder.img_shape)
    # find cells in new mask which overlaps with the cells in old mask
    all_new_cells = [i for j in all_new_cells for i in j]
    newcells_to_update = find_cells_overlap_linear_coords(
        all_new_cells, lin_old_coords_remove, holder.img_shape)
    # remove old cells
    for old_cell in old_cells_to_remove:
        container.curr_cells.remove(old_cell)
    # add new cells
    container.curr_cells.extend(newcells_to_update)
    return container