Example #1
0
    f,ax = plt.subplots()
    ax.imshow(arr, cmap=cm.gray, interpolation='none')
    plt.show()
    
def make_img(num_obj=100, obj_rad=5, nr=1024, nc=1024):
    arr = np.zeros((nr,nc))
    kerLen = 2*obj_rad
    (X,Y) = np.mgrid[-1:1:1j*kerLen, -1:1:1j*kerLen]
    ker = (np.sqrt(X*X+Y*Y) <= 0.9)
    rand_pos = np.random.rand(num_obj, 2)
    for (x,y) in rand_pos:
        xstart = int(x*(nc-kerLen))
        ystart = int(y*(nr-kerLen))
        arr[xstart:xstart+kerLen, ystart:ystart+kerLen] += ker
    return arr

#Creating an Image.
image = make_img(num_obj=6, obj_rad=10, nr=128, nc=128)
my_imshow(image)

# To separate the circles. We generate markers at the maxima of the distance to the background:
from skimage.feature import peak_local_max
distance = ndi.distance_transform_edt(image)
local_maxi = peak_local_max(distance, labels=image,footprint=np.ones((3, 3)),indices=False)
markers = ndi.label(local_maxi)[0]

#Finally,run the watershed on the image and markers:
from skimage.segmentation import watershed
labels = watershed(-distance, markers, mask=image)
my_imshow(labels)
Example #2
0
def analyze_bubbles(img, scale=1, frame=0):
    """
    Process an image to detect the bubbles (bright on dark assumed)
    
    Parameters
    ----------
    img : np.array
        image to process
    scale : float, optional
        Scaling factor in px/mm. Default is 1 px/mm
    frame : int, optional
        Frame number of the image for inclusion in the dataframe. Default is 0
    Returns
    -------
    DataFrame {'Frame', Label', 'Area', 'Eccentricity', 'Bbox Area'}
        Frame (int): Frame number of the image
        Label (int): Identifier for each bubble
        Area (int): area of the detected bubble (mm2)
        Eccentricity (float): eccentricity of the region
        Bbox Area (int): area of the bounding box (mm2)
    """

    try:
        #Convert to grayscale
        img_gray = img_as_ubyte(rgb2gray(img))
        #Threshold the image (otsu) to get the bubbles
        img_bin = img_gray > threshold_minimum(img_gray)
        #Close holes in bubbles
        img_closed = closing(img_bin)
        #Compute distance to background
        dist = ndi.distance_transform_edt(img_closed)
        #Stretch contrast of the distance image
        dist_cont = exposure.rescale_intensity(dist, in_range='image')
        #Find local maximas in distance image and make them markers for the watershed
        local_maxi = peak_local_max(dist_cont,
                                    indices=False,
                                    footprint=np.ones((10, 10)))
        markers, num_max = ndi.label(local_maxi)
        #Run a watershed algorithm to separate the bubbles
        img_segmented = watershed(-dist_cont,
                                  markers,
                                  mask=img_closed,
                                  watershed_line=True)
        #Label the segmented image
        img_labeled, num_sec = ndi.label(img_segmented)
        #Get the properties of the labeled regions and construct a dataframe
        reg = regionprops(img_labeled, coordinates='rc')
        if len(reg) > 0:
            columns = ['Frame', 'Label', 'Area', 'Eccentricity', 'Bbox Area']
            df = pd.DataFrame(columns=columns, dtype=np.float64)
            df = df.append([{
                'Frame': frame,
                'Label': i.label,
                'Area': i.area / (scale**2),
                'Eccentricity': i.eccentricity,
                'Bbox Area': i.bbox_area / (scale**2)
            } for i in reg])
            return df
        else:
            return None
    except:
        return None
def getVoronoiStyle(seg_file, max_voro_area, voro_imfile, voro_imfile_2,
                    voro_outfile, voro_transfile):
    temp = np.asarray(np.load(seg_file, allow_pickle=True)).item()
    masks = temp['masks']

    im = np.zeros_like(np.array(masks))

    fro = pd.DataFrame(
        measure.regionprops_table(masks, properties=['label', 'centroid']))

    points_mask = np.array(fro[['centroid-0', 'centroid-1']].to_numpy())

    vor = Voronoi(points_mask)

    my_dpi = im.shape[1]

    plt.rcParams['figure.dpi'] = my_dpi
    plt.rcParams['figure.figsize'] = (im.shape[0] / my_dpi,
                                      im.shape[1] / my_dpi)
    fig = plt.figure()

    for simplex in vor.ridge_vertices:
        simplex = np.asarray(simplex)
        if np.all(simplex >= 0):
            plt.plot(vor.vertices[simplex, 0],
                     vor.vertices[simplex, 1],
                     'k-',
                     c='black',
                     linewidth=.2)

    center = points_mask.mean(axis=0)
    for pointidx, simplex in zip(vor.ridge_points, vor.ridge_vertices):
        simplex = np.asarray(simplex)
        if np.any(simplex < 0):
            i = simplex[simplex >= 0][0]  # finite end Voronoi vertex
            t = points_mask[pointidx[0]] - points_mask[pointidx[1]]  # tangent
            t = t / np.linalg.norm(t)
            n = np.array([-t[1], t[0]])  # normal
            midpoint = points_mask[pointidx].mean(axis=0)
            far_point = vor.vertices[i] + np.sign(np.dot(midpoint - center,
                                                         n)) * n * 100
            plt.plot([vor.vertices[i, 0], far_point[0]],
                     [vor.vertices[i, 1], far_point[1]],
                     'k-',
                     c='black',
                     linewidth=.2)

    plt.xlim([0, im.shape[0]])
    plt.ylim([0, im.shape[1]])
    plt.axis('off')
    fig.tight_layout(pad=0)
    plt.savefig(
        voro_imfile,
        dpi=my_dpi,  #bbox_inches='tight',#dpi=my_dpi,
        transparent=False,
        pad_inches=0,
        facecolor='white')
    plt.close()
    im2 = io.imread(voro_imfile)
    voro = (im2[:, :, 0])
    voro = voro[1:-1, 1:-1]
    voro = np.pad(voro, pad_width=1, mode='constant')
    distance = ndi.distance_transform_edt(voro)
    coords = peak_local_max(distance, footprint=np.ones((1, 1)), labels=voro)
    mask = np.zeros(distance.shape, dtype=bool)
    mask[tuple(coords.T)] = True
    markers, _ = ndi.label(mask)
    labels = segmentation.watershed(-distance, markers, mask=voro)
    labels = morphology.remove_small_objects(labels,
                                             min_size=40,
                                             connectivity=1,
                                             in_place=False)
    labels = morphology.dilation(labels, morphology.square(3))
    segmasks = masks
    segmasks = morphology.dilation(segmasks, morphology.square(3))

    sizeOfSegs = pd.DataFrame(
        measure.regionprops_table(labels, properties=['label', 'area']))
    bigMasks = np.array(
        sizeOfSegs[sizeOfSegs['area'] >= max_voro_area]['label'])
    newVorMask = np.copy(labels)[::-1, :]

    red = [
        getOverlap(row, segmasks=segmasks, fro=fro, dilation=11)
        for row in range(fro.shape[0])
    ]
    newVorMask = np.sum(red)
    np.save(voro_outfile, newVorMask.T, allow_pickle=True, fix_imports=True)
    io.imsave(voro_imfile_2, segmentation.find_boundaries(newVorMask).T)

    oldAssign = pd.DataFrame(
        measure.regionprops_table(masks, properties=['label', 'centroid']))
    newAssign = pd.DataFrame(
        measure.regionprops_table(newVorMask, properties=['label',
                                                          'centroid']))

    Clps2Voro = pd.DataFrame()

    for nlab in range(newAssign.shape[0]):
        tmpMtx = (newVorMask == newAssign['label'][nlab])
        for olab in range(oldAssign.shape[0]):
            if (tmpMtx[int(np.round(oldAssign['centroid-1'][olab])),
                       int(np.round(oldAssign['centroid-0'][olab]))]):
                Clps2Voro = Clps2Voro.append(
                    pd.DataFrame(
                        [newAssign['label'][nlab],
                         oldAssign['label'][olab]]).T)

    Clps2Voro = Clps2Voro.rename(columns={0: "voro_label", 1: "clps_label"})
    Clps2Voro = Clps2Voro.reset_index(drop=True)
    Clps2Voro.to_csv(voro_transfile)
from skimage.color import label2rgb
from skimage import data

coins = data.coins()

# Make segmentation using edge-detection and watershed.
edges = sobel(coins)

# Identify some background and foreground pixels from the intensity values.
# These pixels are used as seeds for watershed.
markers = np.zeros_like(coins)
foreground, background = 1, 2
markers[coins < 30.0] = background
markers[coins > 150.0] = foreground

ws = watershed(edges, markers)
seg1 = label(ws == foreground)

# Make segmentation using SLIC superpixels.
seg2 = slic(coins,
            n_segments=117,
            max_iter=160,
            sigma=1,
            compactness=0.75,
            multichannel=False,
            start_label=0)

# Combine the two.
segj = join_segmentations(seg1, seg2)

# Show the segmentations.
Example #5
0
def seg(img):
    # xg = img[:,:,1]

    xg = np.copy(img[:, :, 1])
    cv2.imshow('img', xg)
    cv2.waitKey()
    cv2.destroyAllWindows()

    mask = np.copy(xg)
    m1 = mask.mean()
    mask[mask > m1] = m1  # [xt > m1]

    m2 = mask.mean()
    mask[mask > m2] = m2  # [xt>m2]
    m3 = mask.mean()
    mask[mask < m3] = 0
    # tmp = np.copy(mask)
    # tmp[tmp >= m3] = 255
    mask[mask >= m3] = 1
    n = mask.sum()
    # cv2.imshow('img', tmp)
    # cv2.waitKey()
    # cv2.destroyAllWindows()

    xin = xg * mask
    xout = xin
    m1 = xout.sum() / n
    xout[xout > m1] = m1
    m2 = xout.sum() / n
    xout[xout > m2] = m2
    m3 = xout.sum() / n
    xout[xout > m3] = 0
    # tmp = np.copy(xout)
    # tmp[tmp > 0] = 255
    xout[xout > 0] = 2
    # # tmp = cv2.morphologyEx(tmp, cv2.MORPH_OPEN, kernel)
    # cv2.imshow('om', tmp)
    # cv2.waitKey()
    # cv2.destroyAllWindows()

    a, b = np.histogram(xg.flatten(), bins=20, range=[15, 255])
    idx = a.argmax()
    range_S = b[idx]
    range_B = b[-1]

    canny = cv2.Canny(xg, 20, 60) * mask
    # canny = cv2.dilate(canny, kernel, iterations=1)
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
    canny = cv2.morphologyEx(canny, cv2.MORPH_CLOSE, kernel, iterations=2)
    canny = cv2.erode(canny, kernel,
                      iterations=1)  # cv2.imshow('canny', canny )
    # cv2.waitKey()
    # cv2.destroyAllWindows()
    closed = np.zeros_like(canny)
    closed[mask == 0] = 1
    closed[(xg >= range_S) * (xg <= range_B)] = 1
    closed[(xg <= b[idx - 1 if idx >= 2 else 0])] = 1
    closed[canny > 0] = 2

    # tmp = np.copy(canny)
    # tmp[mask == 0] = 1
    # tmp[(xg >= range_S) *(xg <= range_B)] = 128
    # tmp[(xg <= b[idx-1 if idx >=2 else 0])] = 128
    # tmp[canny>0] = 255
    # cv2.imshow('closed', tmp)
    # cv2.waitKey()
    # cv2.destroyAllWindows()
    # xout

    fused = np.zeros_like(closed)
    fused[(closed == 2) * (xout == 2)] = 2
    fused[(closed == 2) * (xout == 0)] = 2
    fused[(closed == 1) * (xout == 0)] = 1
    fused[(closed == 1) * (xout == 2)] = 0
    # tmp = np.copy(fused)
    # tmp[fused ==2] = 255
    # tmp[fused ==1] = 128
    # tmp[fused ==0] = 0
    # cv2.imshow('closed', tmp)
    # cv2.waitKey()
    # cv2.destroyAllWindows()

    # image_segmented = watershed(xg, markers = closed)#, beta=1,beta=20, mode='bf'
    # image_segmented = random_walker(fused, closed)#, beta=1,beta=20, mode='bf'
    image_segmented = watershed(fused,
                                markers=closed)  #, beta=1,beta=20, mode='bf'
    image_segmented[image_segmented == 1] = 0
    image_segmented = image_segmented.astype(np.uint8)
    image_segmented[image_segmented > 1] = 255
    # closed = cv2.erode(image_segmented, None, iterations=2)
    cv2.imshow('img res', image_segmented)
    cv2.waitKey()

    cv2.destroyAllWindows()
    return image_segmented
Example #6
0
# min_distance: Número mínimo de pixels que separam os picos
# https://scikit-image.org/docs/stable/api/skimage.feature.html#skimage.feature.peak_local_max
print('-' * 50)
print('Número de Picos')
print(np.unique(max_local, return_counts=True))
print('-' * 50)

marcadores, n_marcadores = ndimage.label(max_local, structure=np.ones((3, 3)))
# Realiza marcação dos picos
# https://docs.scipy.org/doc/scipy/reference/generated/scipy.ndimage.label.html
# https://en.wikipedia.org/wiki/Connected-component_labeling
print('Análise de conectividade - Marcadores')
print(np.unique(marcadores, return_counts=True))
print('-' * 50)

img_ws = watershed(-img_dist, marcadores, mask=mascara)
# https://scikit-image.org/docs/dev/api/skimage.segmentation.html#skimage.segmentation.watershed
# https://en.wikipedia.org/wiki/Watershed_(image_processing)
# https://scikit-image.org/docs/dev/auto_examples/segmentation/plot_watershed.html

print('Imagem Segmentada - Watershed')
print(np.unique(img_ws, return_counts=True))
print("Número de Batatas: ", len(np.unique(img_ws)) - 1)
print('-' * 50)

img_final = np.copy(img_rgb)
img_final[img_ws != 3] = [0, 0, 0]  # Acessando a batata 3
########################################################################################################################
plt.figure('Watershed')
plt.subplot(2, 3, 1)
plt.imshow(img_rgb)
def S3NucleiSegmentationWatershed(nucleiPM, nucleiImage, logSigma, TMAmask,
                                  nucleiFilter, nucleiRegion):
    nucleiContours = nucleiPM[:, :, 1]
    nucleiCenters = nucleiPM[:, :, 0]

    mask = resize(TMAmask, (nucleiImage.shape[0], nucleiImage.shape[1]),
                  order=0) > 0

    if nucleiRegion == 'localThreshold':
        Imax = peak_local_max(extrema.h_maxima(255 - nucleiContours,
                                               logSigma[0]),
                              indices=False)
        Imax = label(Imax).astype(np.int32)
        foregroundMask = watershed(nucleiContours, Imax, watershed_line=True)
        P = regionprops(
            foregroundMask,
            np.amax(nucleiCenters) - nucleiCenters - nucleiContours)
        prop_keys = ['mean_intensity', 'label', 'area']

        def props_of_keys(prop, keys):
            return [prop[k] for k in keys]

        mean_ints, labels, areas = np.array(
            Parallel(n_jobs=6)(delayed(props_of_keys)(prop, prop_keys)
                               for prop in P)).T
        del P
        maxArea = (logSigma[1]**2) * 3 / 4
        minArea = (logSigma[0]**2) * 3 / 4
        passed = np.logical_and.reduce(
            (np.logical_and(areas > minArea,
                            areas < maxArea), np.less(mean_ints, 50)))

        foregroundMask *= np.isin(foregroundMask, labels[passed])
        np.greater(foregroundMask, 0, out=foregroundMask)
        foregroundMask = label(foregroundMask, connectivity=1).astype(np.int32)
    elif nucleiRegion == 'bypass':
        foregroundMask = nucleiPM[:, :, 0]
        P = regionprops(foregroundMask, nucleiImage)
        prop_keys = ['mean_intensity', 'label', 'area']

        def props_of_keys(prop, keys):
            return [prop[k] for k in keys]

        mean_ints, labels, areas = np.array(
            Parallel(n_jobs=6)(delayed(props_of_keys)(prop, prop_keys)
                               for prop in P)).T
        del P
        maxArea = (logSigma[1]**2) * 3 / 4
        minArea = (logSigma[0]**2) * 3 / 4
        passed = np.logical_and(areas > minArea, areas < maxArea)

        foregroundMask *= np.isin(foregroundMask, labels[passed])
        np.greater(foregroundMask, 0, out=foregroundMask)
        foregroundMask = label(foregroundMask, connectivity=1).astype(np.int32)
    else:

        if len(logSigma) == 1:
            nucleiDiameter = [logSigma * 0.5, logSigma * 1.5]
        else:
            nucleiDiameter = logSigma
        logMask = nucleiCenters > 150

        win_view_setting = WindowView(nucleiContours.shape, 2000, 500)

        nucleiContours = win_view_setting.window_view_list(nucleiContours)
        padding_mask = win_view_setting.padding_mask()
        mask = win_view_setting.window_view_list(mask)

        maxArea = (logSigma[1]**2) * 3 / 4
        minArea = (logSigma[0]**2) * 3 / 4

        foregroundMask = np.array(
            Parallel(n_jobs=6)(
                delayed(contour_pm_watershed)(img,
                                              sigma=logSigma[1] / 30,
                                              h=logSigma[1] / 30,
                                              tissue_mask=tm,
                                              padding_mask=m,
                                              min_area=minArea,
                                              max_area=maxArea)
                for img, tm, m in zip(nucleiContours, mask, padding_mask)))

        del nucleiContours, mask

        foregroundMask = win_view_setting.reconstruct(foregroundMask)
        foregroundMask = label(foregroundMask, connectivity=1).astype(np.int32)

        if nucleiFilter == 'IntPM':
            int_img = nucleiCenters
        elif nucleiFilter == 'Int':
            int_img = nucleiImage

        print('    ', datetime.datetime.now(), 'regionprops')
        P = regionprops(foregroundMask, int_img)

        def props_of_keys(prop, keys):
            return [prop[k] for k in keys]

        prop_keys = ['mean_intensity', 'area', 'solidity', 'label']
        mean_ints, areas, solidities, labels = np.array(
            Parallel(n_jobs=6)(delayed(props_of_keys)(prop, prop_keys)
                               for prop in P)).T
        del P

        MITh = threshold_otsu(mean_ints)

        minSolidity = 0.8

        passed = np.logical_and.reduce(
            (np.greater(mean_ints,
                        MITh), np.logical_and(areas > minArea,
                                              areas < maxArea),
             np.greater(solidities, minSolidity)))

        # set failed mask label to zero
        foregroundMask *= np.isin(foregroundMask, labels[passed])

        np.greater(foregroundMask, 0, out=foregroundMask)
        foregroundMask = label(foregroundMask, connectivity=1).astype(np.int32)

    return foregroundMask
image = img_as_ubyte(data.camera())

# denoise image
denoised = rank.median(image, disk(2))

# find continuous region (low gradient -
# where less than 10 for this image) --> markers
# disk(5) is used here to get a more smooth image
markers = rank.gradient(denoised, disk(5)) < 10
markers = ndi.label(markers)[0]

# local gradient (disk(2) is used to keep edges thin)
gradient = rank.gradient(denoised, disk(2))

# process the watershed
labels = watershed(gradient, markers)

# display results
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(8, 8),
                         sharex=True, sharey=True)
ax = axes.ravel()

ax[0].imshow(image, cmap=plt.cm.gray)
ax[0].set_title("Original")

ax[1].imshow(gradient, cmap=plt.cm.nipy_spectral)
ax[1].set_title("Local Gradient")

ax[2].imshow(markers, cmap=plt.cm.nipy_spectral)
ax[2].set_title("Markers")
Example #9
0
def separate_watershed(
    vdf_temp,
    min_distance=1,
    min_size=1,
    max_size=np.inf,
    max_number_of_grains=np.inf,
    marker_radius=1,
    threshold=False,
    exclude_border=False,
    plot_on=False,
):
    """Separate segments from one VDF image using edge-detection by the
    sobel transform and the watershed segmentation implemented in
    scikit-image. See [1,2] for examples from scikit-image.

    Parameters
    ----------
    vdf_temp : np.array
        One VDF image.
    min_distance: int
        Minimum distance (in pixels) between markers for them to be
        considered separate markers for the watershed segmentation.
    min_size : float
        Grains with size (i.e. total number of pixels) below min_size
        are discarded.
    max_size : float
        Grains with size (i.e. total number of pixels) above max_size
        are discarded.
    max_number_of_grains : int
        Maximum number of grains included in the returned separated
        grains. If it is exceeded, those with highest peak intensities
        will be returned.
    marker_radius : float
        If 1 or larger, each marker for watershed is expanded to a disk
        of radius marker_radius. marker_radius should not exceed
        2*min_distance.
    threshold : bool
        If True, a mask is calculated by thresholding the VDF image by
        the Li threshold method in scikit-image. If False (default), the
        mask is the boolean VDF image.
    exclude_border : int or True, optional
        If non-zero integer, peaks within a distance of exclude_border
        from the boarder will be discarded. If True, peaks at or closer
        than min_distance of the boarder, will be discarded.
    plot_on : bool
        If True, the VDF, the mask, the distance transform
        and the separated grains will be plotted in one figure window.

    Returns
    -------
    sep : np.array
        Array containing segments from VDF images (i.e. separated
        grains). Shape: (image size x, image size y, number of grains)

    References
    ----------
    [1] http://scikit-image.org/docs/dev/auto_examples/segmentation/
        plot_watershed.html
    [2] http://scikit-image.org/docs/dev/auto_examples/xx_applications/
        plot_coins_segmentation.html#sphx-glr-auto-examples-xx-
        applications-plot-coins-segmentation-py
    """

    # Create a mask from the input VDF image.
    if threshold:
        th = threshold_li(vdf_temp)
        mask = np.zeros_like(vdf_temp)
        mask[vdf_temp > th] = True
    else:
        mask = vdf_temp.astype("bool")

    # Calculate the Eucledian distance from each point in the mask to the
    # nearest background point of value 0.
    distance = distance_transform_edt(mask)

    # If exclude_boarder is given, the edge of the distance is removed
    # by erosion. The distance image is used to find markers, and so the
    # erosion is done to avoid that markers are located at the edge
    # of the mask.
    if exclude_border > 0:
        distance_mask = binary_erosion(distance,
                                       structure=disk(exclude_border))
        distance = distance * distance_mask.astype("bool")

    # Find the coordinates of the local maxima of the distance transform.
    local_maxi = peak_local_max(
        distance,
        indices=False,
        min_distance=1,
        num_peaks=max_number_of_grains,
        exclude_border=exclude_border,
        threshold_rel=None,
    )
    maxi_coord1 = np.where(local_maxi)

    # Discard maxima that are found at pixels that are connected to a
    # smaller number of pixels than min_size. Used as markers, these would lead
    # to segments smaller than min_size and should therefore not be
    # considered when deciding which maxima to use as markers.
    if min_size > 1:
        labels_check = label(mask)[0]
        delete_indices = []
        for i in np.arange(np.shape(maxi_coord1)[1]):
            index = np.transpose(maxi_coord1)[i]
            label_value = labels_check[index[0], index[1]]
            if len(labels_check[labels_check == label_value]) < min_size:
                delete_indices.append(i)
                local_maxi[index[0], index[1]] = False
        maxi_coord1 = np.delete(maxi_coord1, delete_indices, axis=1)

    # Cluster the maxima by DBSCAN based on min_distance. For each
    # cluster, only the maximum closest to the average maxima position is
    # used as a marker.
    if min_distance > 1 and np.shape(maxi_coord1)[1] > 1:
        clusters = DBSCAN(
            eps=min_distance,
            metric="euclidean",
            min_samples=1,
        ).fit(np.transpose(maxi_coord1))
        local_maxi = np.zeros_like(local_maxi)
        for n in np.arange(clusters.labels_.max() + 1):
            maxi_coord1_n = np.transpose(maxi_coord1)[clusters.labels_ == n]
            com = np.average(maxi_coord1_n, axis=0).astype("int")
            index = distance_matrix([com], maxi_coord1_n).argmin()
            index = maxi_coord1_n[index]
            local_maxi[index[0], index[1]] = True

    # Use the resulting maxima as markers. Each marker should have a
    # unique label value. For each maximum, generate markers with the same
    # label value in a radius given by marker_radius centered at the
    # maximum position. This is done to make the segmentation more robust
    # to local changes in pixel values around the marker.
    markers = label(local_maxi)[0]
    if marker_radius >= 1:
        disk_mask = disk(marker_radius)
        for mm in np.arange(1, np.max(markers) + 1):
            im = np.zeros_like(markers)
            im[np.where(markers == mm)] = markers[np.where(markers == mm)]
            markers_temp = convolve2d(im,
                                      disk_mask,
                                      boundary="fill",
                                      mode="same",
                                      fillvalue=0)
            markers[np.where(markers_temp)] = mm
    markers = markers * mask

    # Find the edges of the VDF image using the Sobel transform.
    elevation = sobel(vdf_temp)

    # 'Flood' the elevation (i.e. edge) image from basins at the marker
    # positions. Find the locations where different basins meet, i.e.
    # the watershed lines (segment boundaries). Only search for segments
    # (labels) in the area defined by mask.
    labels = watershed(elevation, markers=markers, mask=mask)

    sep = np.zeros(
        (np.shape(vdf_temp)[0], np.shape(vdf_temp)[1], (np.max(labels))),
        dtype="int32")
    n, i = 1, 0
    while (np.max(labels)) > n - 1:
        sep_temp = labels * (labels == n) / n
        sep_temp = np.nan_to_num(sep_temp)
        # Discard a segment if it is too small or too large, or else add
        # it to the list of separated segments.
        if (np.sum(sep_temp, axis=(0, 1)) < min_size) or np.sum(
                sep_temp, axis=(0, 1)) > max_size:
            sep = np.delete(sep, ((n - i) - 1), axis=2)
            i = i + 1
        else:
            sep[:, :, (n - i) - 1] = sep_temp
        n = n + 1
    # Put the intensity from the input VDF image into each segmented area.
    vdf_sep = np.broadcast_to(vdf_temp.T, np.shape(sep.T)) * (sep.T == 1)

    if plot_on:  # pragma: no cover
        # If segments have been discarded, make new labels that do not
        # include the discarded segments.
        if np.max(labels) != (np.shape(sep)[2]) and (np.shape(sep)[2] != 0):
            labels = sep[:, :, 0]
            for i in range(1, np.shape(sep)[2]):
                labels = labels + sep[..., i] * (i + 1)
        # If no separated particles were found, set all elements in
        # labels to 0.
        elif np.shape(sep)[2] == 0:
            labels = np.zeros(np.shape(labels))

        seps_img_sum = np.zeros_like(vdf_temp).astype("float64")
        for lbl, vdf in zip(np.arange(1, np.max(labels) + 1), vdf_sep):
            mask_l = np.zeros_like(labels).astype("bool")
            _idx = np.where(labels == lbl)
            mask_l[_idx] = 1
            seps_img_sum += vdf_temp * mask_l / np.max(vdf_temp[_idx])
            seps_img_sum[_idx] += lbl

        maxi_coord = np.where(local_maxi)

        fig, axes = plt.subplots(2, 3, sharex=True, sharey=True)
        ax = axes.ravel()

        ax[0].imshow(vdf_temp, cmap=plt.cm.magma_r)
        ax[0].axis("off")
        ax[0].set_title("VDF")

        ax[1].imshow(mask, cmap=plt.cm.gray_r)
        ax[1].axis("off")
        ax[1].set_title("Mask")

        ax[2].imshow(distance, cmap=plt.cm.gray_r)
        ax[2].axis("off")
        ax[2].set_title("Distance and markers")
        ax[2].imshow(masked_where(markers == 0, markers),
                     cmap=plt.cm.gist_rainbow)
        ax[2].plot(maxi_coord1[1], maxi_coord1[0], "k+")
        ax[2].plot(maxi_coord[1], maxi_coord[0], "gx")

        ax[3].imshow(elevation, cmap=plt.cm.magma_r)
        ax[3].axis("off")
        ax[3].set_title("Elevation")

        ax[4].imshow(labels, cmap=plt.cm.gnuplot2_r)
        ax[4].axis("off")
        ax[4].set_title("Labels")

        ax[5].imshow(seps_img_sum, cmap=plt.cm.magma_r)
        ax[5].axis("off")
        ax[5].set_title("Segments")

    return vdf_sep
Example #10
0
def bacteria_watershed_old(
        segs,
        maxsize=1000,  #uint16((5*2)/(pix2mic**2))  ### max area
        minsize=200,  #uint16((0.5*0.1)/(pix2mic**2))    ### min area
        absolwidth=1,
        thr_strength=2.,
        phase_contrast=None,
        fix_thr=None):
    min_av_width = 1
    segs2 = {}  # here images after watershed
    thresh_array = []
    #    for ch_n, img0 in segs.items():
    #        thresh_array.append(skfilt.threshold_minimum(img0.flatten()))
    #    med, mad = get_med_and_mad(thresh_array)
    #    threshold_int = med+3*mad

    for ch_n, img0 in segs.items():
        factor = 1.
        if phase_contrast is None:
            img = -image2gray(segs[0])
        if phase_contrast is True:
            img = image2gray(segs[0])
        med, mad = get_med_and_mad(img)
        if fix_thr is None:
            th3 = cv.adaptiveThreshold(
                img,
                255,
                cv.ADAPTIVE_THRESH_GAUSSIAN_C,
                cv.THRESH_BINARY,
                101,  # block size of the adaptive thr
                thr_strength * mad)  # constant value subtracted
        else:
            th3 = deepcopy(img)
            th3[img > fix_thr] = 1
            th3[img <= fix_thr] = 0

        #threshold_int = skfilt.threshold_minimum(img0.flatten())
        #if skfilt.threshold_minimum(img0.flatten())> threshold_int:
        #bw0 = img0 > threshold_int+10*factor
        bw0 = (th3 == 0)
        #else:
        #    bw0 = img0 > threshold_int;

        bw1 = ndi.morphology.binary_erosion(bw0,
                                            structure=ones((5, 5)),
                                            iterations=1)
        bw2 = ndi.morphology.binary_dilation(bw0)
        bw3 = bw2 ^ bw1
        ### only the borders
        # perform distance transform on filtered image (distance from the nearest 0)
        dist = ndi.distance_transform_edt(bw1)
        markers = np.zeros(img0.shape, dtype=bool)
        markers[dist >= absolwidth] = True
        markers = ndi.label(markers)[0]
        markers = markers + 1
        #    bw3 = bw2 ^ (dist >= absolwidth); ### only the borders
        markers[bw3] = 0

        # Perform watershed
        # edit by Nicola
        if phase_contrast is None:
            segmentation = watershed(-img0, markers)
        if phase_contrast is True:
            segmentation = watershed(img0, markers)
    #    segmentation = watershed(img0, markers)
        segmentation = ndi.binary_fill_holes(segmentation != 1)

        # label image
        labeled_bacteria, nbac = ndi.label(segmentation)

        ### now filter bacteria for size and width
        dist = ndi.distance_transform_edt(labeled_bacteria > 0)

        newbac = np.zeros(labeled_bacteria.shape, dtype=labeled_bacteria.dtype)

        stats = dict(
            num_rejected_av_width=0,
            num_rejected_area=0,
        )

        label = 0
        for region in regionprops(labeled_bacteria):
            masked_bac = labeled_bacteria == region.label
            skel = skeletonize(masked_bac)
            av_width_skel = np.mean(dist[skel])
            if av_width_skel < min_av_width:
                stats["num_rejected_av_width"] += 1
                continue
            if maxsize > region.area > minsize:
                label += 1
                newbac[labeled_bacteria == region.label] = label
            if region.area > maxsize:
                stats["num_rejected_area"] += 1


#        if stats["num_rejected_area"]>0:
        segs2[ch_n] = newbac
    return segs2, thresh_array
Example #11
0
def bacteria_watershed(
        segs,
        maxsize=1000,  #uint16((5*2)/(pix2mic**2))  ### max area
        minsize=200,  #uint16((0.5*0.1)/(pix2mic**2))    ### min area
        absolwidth=1,
        thr_strength=2.,
        phase_contrast=None,
        fix_thr=None):
    min_av_width = 1
    segs2 = {}  # here images after watershed
    thresh_array = []
    #    for ch_n, img0 in segs.items():
    #        thresh_array.append(skfilt.threshold_minimum(img0.flatten()))
    #    med, mad = get_med_and_mad(thresh_array)
    #    threshold_int = med+3*mad

    for ch_n, img0 in segs.items():
        if fix_thr is None:
            thresh = skfilt.threshold_li(
                np.concatenate([s.flatten() for s in segs.values()]))

        else:
            thresh_thr = fix_thr

        bw0 = img0 > thresh
        bw1 = ndi.morphology.binary_erosion(bw0)
        bw2 = ndi.morphology.binary_dilation(bw0)
        bw3 = bw2 ^ bw1

        # perform distance transform on filtered image
        dist = ndi.distance_transform_edt(bw2)

        # create markers for watershed
        markers = np.zeros(img0.shape, dtype=bool)

        markers[dist >= absolwidth] = True
        markers = ndi.label(markers)[0]
        #markers[markers>=1]= markers[markers>=1]+1
        #markers[bw3] = 0

        # Perform watershed
        labeled_bacteria = skseg.watershed(-dist, markers, mask=bw2)
        #labeled_bacteria = ndi.binary_fill_holes(segmentation)# != 1)

        ### now filter bacteria for size and width
        dist = ndi.distance_transform_edt(labeled_bacteria > 0)

        newbac = np.zeros(labeled_bacteria.shape, dtype=labeled_bacteria.dtype)

        stats = dict(
            num_rejected_av_width=0,
            num_rejected_area=0,
        )

        label = 0
        for region in regionprops(labeled_bacteria):
            masked_bac = labeled_bacteria == region.label
            skel = skeletonize(masked_bac)
            av_width_skel = np.mean(dist[skel])
            if av_width_skel < min_av_width:
                stats["num_rejected_av_width"] += 1
                continue
            if maxsize > region.area > minsize:
                label += 1
                newbac[labeled_bacteria == region.label] = label
            if region.area > maxsize:
                stats["num_rejected_area"] += 1


#        if stats["num_rejected_area"]>0:
        segs2[ch_n] = newbac
    return segs2, thresh_array
def split_bacteria_in_well(
    bacteria_label_image,
    intensity_image,
    min_skel_length=50,
    threshold_stat=None,
    debug=None,
):
    """
    Split bacteria in a single well image based on
    statistical thresholding of width and intensity along
    the skeleton

    Parameters
    ------
    bacteria_label_image : ndarray (2D)
        Labelled image of detected bacteria
    intensity_image : ndarray (2d)
        Intensity image of current well
    min_skel_length : float (optional)
        Minimum skeleton length for a region to be considered for splitting
    returns
    ------
    split_bac : Dictionary
        The key is the well coordinates and the value is a labelled image of detected bacteria
    """

    max_label = 0
    stats = []
    dist = ndi.distance_transform_edt(bacteria_label_image > 0)
    output_labels = bacteria_label_image.copy()
    for prop in regionprops(bacteria_label_image):
        region_mask = bacteria_label_image == prop.label
        #skel, dist = skmorph.medial_axis(region_mask, return_distance=True)
        skel = skmorph.skeletonize(region_mask)
        if skel.sum() < min_skel_length:
            max_label += 1
            output_labels[region_mask] = max_label
            continue

        skelprop = regionprops(skel.astype(int))[0]
        posy, posx = skelprop.coords.T

        skel_intensity = intensity_image[skel]
        skel_dist = dist[skel]

        threshold_int = threshold_mad(skel_intensity, 1)
        threshold_dist = threshold_mad(skel_dist, 1)

        breaks = skel_intensity < threshold_int  #Nicola: 9.5.20 (debug["med_int"] - debug["mad_int"])

        breaks_dist = skel_dist < threshold_dist  # Nicola 9.5.20 debug["med_dist"]

        breaks[~breaks_dist] = False

        skel_breaks = skel.copy()
        skel_breaks[skel] = breaks

        break_labels, n_breaks = ndi.label(skel_breaks)

        sizes = ndi.sum(skel_breaks,
                        break_labels,
                        index=np.arange(1, n_breaks + 1))
        for label, break_size in enumerate(sizes, start=1):
            # if break_size < min_break_size:
            if break_size < 0:
                skel_breaks[break_labels == label] = False
        bacteria_markers, n_bacteria_markers = ndi.label(skel ^ skel_breaks,
                                                         structure=np.ones(
                                                             (3, 3),
                                                             dtype=bool))

        num_removed = 0
        for label in range(1, n_bacteria_markers + 1):
            bwnow = bacteria_markers == label
            if bwnow.sum() >= min_skel_length:
                continue
            bacteria_markers[bwnow] = 0
            num_removed += 1

        if num_removed == n_bacteria_markers:
            max_label += 1
            output_labels[region_mask] = max_label
            continue

        bacteria_markers, num_final = ndi.label(bacteria_markers > 0,
                                                structure=np.ones((3, 3),
                                                                  dtype=bool))

        bacterianow = watershed(-dist, bacteria_markers, mask=region_mask)
        bacterianow[bacterianow > 0] += max_label
        output_labels[region_mask] = bacterianow[region_mask]
        max_label += num_final

    return output_labels
def split_bacteria_in_well_strong(
    bacteria_label_image,
    intensity_image,
    min_skel_length=50,
):
    """
    Split bacteria in a single well image based on
    peaks intensity along the skeleton

    Parameters
    ------
    bacteria_label_image : ndarray (2D)
        Labelled image of detected bacteria
    intensity_image : ndarray (2d)
        Intensity image of current well
    min_skel_length : float (optional)
        Minimum skeleton length for a region to be considered for splitting
    returns
    ------
    split_bac : Dictionary
        The key is the well coordinates and the value is a labelled image of detected bacteria
    """

    max_label = 0
    stats = []
    dist = ndi.distance_transform_edt(bacteria_label_image > 0)
    output_labels = bacteria_label_image.copy()
    for prop in regionprops(bacteria_label_image):
        region_mask = bacteria_label_image == prop.label
        #skel, dist = skmorph.medial_axis(region_mask, return_distance=True)
        skel = skmorph.skeletonize(region_mask)
        if skel.sum() < min_skel_length:
            max_label += 1
            output_labels[region_mask] = max_label
            continue

        skelprop = regionprops(skel.astype(int))[0]
        posy, posx = skelprop.coords.T

        skel_x = uint8(posx.mean())
        # find intensity profile along bacteria axis
        image_skel = intensity_image[posy[0]:posy[-1] + 1,
                                     skel_x - 2:skel_x + 2]
        #temp_image[~thinned]= nan
        skel_intensity = nanmean(image_skel, axis=1)

        # find distance profile along bacteria axis
        dist = ndi.distance_transform_edt(bacteria_label_image > 0)
        image_skel_dist = dist[posy[0]:posy[-1], skel_x - 2:skel_x + 2]
        skel_dist = nanmean(image_skel_dist, axis=1)

        skel_intensity_gf = gaussian_filter(skel_intensity, 2)
        skel_dist_gf = gaussian_filter(skel_dist, 2)

        xs_int, ph = find_peaks(-skel_intensity_gf,
                                prominence=0.10,
                                distance=min_skel_length)
        xs_dist, ph = find_peaks(-skel_dist_gf,
                                 prominence=0.10,
                                 distance=min_skel_length)

        joined_conditions = abs(xs_dist - xs_int[:, newaxis]) < 3  ##
        breaks_point = repeat(xs_dist[np.newaxis, :], len(xs_int),
                              axis=0)[joined_conditions]
        breaks = zeros_like(skel_intensity)
        breaks[breaks_point] = 1

        skel_breaks = skel.copy()
        #remove the point in the skel
        skel_breaks[skel] = breaks  # this is the sure background

        break_labels, n_breaks = ndi.label(skel_breaks)

        sizes = ndi.sum(skel_breaks,
                        break_labels,
                        index=np.arange(1, n_breaks + 1))
        for label, break_size in enumerate(sizes, start=1):
            # if break_size < min_break_size:
            if break_size < 0:
                skel_breaks[break_labels == label] = False

        bacteria_markers, n_bacteria_markers = ndi.label(skel ^ skel_breaks,
                                                         structure=np.ones(
                                                             (3, 3),
                                                             dtype=bool))

        num_removed = 0
        for label in range(1, n_bacteria_markers + 1):
            bwnow = bacteria_markers == label
            if bwnow.sum() >= min_skel_length:
                continue
            bacteria_markers[bwnow] = 0
            num_removed += 1

        if num_removed == n_bacteria_markers:
            max_label += 1
            output_labels[region_mask] = max_label
            continue

        bacteria_markers, num_final = ndi.label(bacteria_markers > 0,
                                                structure=np.ones((3, 3),
                                                                  dtype=bool))

        bacterianow = watershed(-dist, bacteria_markers, mask=region_mask)
        bacterianow[bacterianow > 0] += max_label
        output_labels[region_mask] = bacterianow[region_mask]
        max_label += num_final

    return output_labels
Example #14
0
def segmentation(img, local_maxi, labels, meta, directory, plot=True, save=False):

    only_clusters = np.zeros(img.shape, dtype=np.int)
    for pos, new in zip(local_maxi, labels):
        if new > 0:
            only_clusters[int(pos[0]), int(pos[1])] = new
        elif new == 0:
            only_clusters[int(pos[0]), int(pos[1])] = max(labels) + 1
    only_clusters = dilation(only_clusters, disk(10))

    binary = _binarize(img)

    dist_water = ndi.distance_transform_edt(binary)
    segmentation_ws = watershed(-img, only_clusters, mask = binary)

    ganglion_prop = regionprops(segmentation_ws)
    
    if plot == True:
        if segmentation_ws.size > 250000000:
            x,y=img.shape #Array splitting
            img_1 = img[0:x, 0:int(y/2)]
            img_2 = img[0:x, int(y/2)+1:y]
            seg_ws1 = segmentation_ws[0:x, 0:int(y/2)]
            seg_ws2 = segmentation_ws[0:x, int(y/2)+1:y]
            seg_ws = [seg_ws1, seg_ws2]
            img_list = [img_1, img_2]
            
            for i in range(2):
                image_label_overlay = label2rgb(seg_ws[i], image=img_list[i].astype('uint16'), 
                                                bg_label=0)
        
                fig,ax = plt.subplots(1,1, figsize=(16,16))
                ax.imshow(image_label_overlay, interpolation='nearest')
                ax.axis('off')

                for prop in regionprops(seg_ws[i]):
                    ax.annotate(prop.label,
                                (prop.centroid[1]-5, prop.centroid[0]), color='green',
                                fontsize=8,weight = "bold")

                if save:
                    try:
                        filename = meta['Name']+str(i+1)+'.pdf'
                        plt.savefig(directory+'/'+filename, transparent=True)
                    except IOError:
                        plt.savefig(filename, transparent=True)
                        
        else:
            image_label_overlay = label2rgb(segmentation_ws, image=img.astype('uint16'), 
                                                bg_label=0)
        
            fig,ax = plt.subplots(1,1, figsize=(16,16))
            ax.imshow(image_label_overlay, interpolation='nearest')
            ax.axis('off')

            for prop in ganglion_prop:
                ax.annotate(prop.label,
                                (prop.centroid[1]-5, prop.centroid[0]), color='green',
                                fontsize=8,weight = "bold")

            if save:
                    try:
                        filename = meta['Name']+'.pdf'
                        plt.savefig(directory+'/'+filename, transparent=True)
                    except IOError:
                        plt.savefig(filename, transparent=True)

    return(ganglion_prop)
Example #15
0
def extract_binary_masks_blob(
        A,
        neuron_radius: float,
        dims: Tuple[int, ...],
        num_std_threshold: int = 1,
        minCircularity: float = 0.5,
        minInertiaRatio: float = 0.2,
        minConvexity: float = .8) -> Tuple[np.array, np.array, np.array]:
    """
    Function to extract masks from data. It will also perform a preliminary selectino of good masks based on criteria like shape and size

    Args:
        A: scipy.sparse matrix
            contains the components as outputed from the CNMF algorithm

        neuron_radius: float
            neuronal radius employed in the CNMF settings (gSiz)

        num_std_threshold: int
            number of times above iqr/1.349 (std estimator) the median to be considered as threshold for the component

        minCircularity: float
            parameter from cv2.SimpleBlobDetector

        minInertiaRatio: float
            parameter from cv2.SimpleBlobDetector

        minConvexity: float
            parameter from cv2.SimpleBlobDetector

    Returns:
        masks: np.array

        pos_examples:

        neg_examples:

    """
    params = cv2.SimpleBlobDetector_Params()
    params.minCircularity = minCircularity
    params.minInertiaRatio = minInertiaRatio
    params.minConvexity = minConvexity

    # Change thresholds
    params.blobColor = 255

    params.minThreshold = 0
    params.maxThreshold = 255
    params.thresholdStep = 3

    params.minArea = np.pi * ((neuron_radius * .75)**2)

    params.filterByColor = True
    params.filterByArea = True
    params.filterByCircularity = True
    params.filterByConvexity = True
    params.filterByInertia = True

    detector = cv2.SimpleBlobDetector_create(params)

    masks_ws = []
    pos_examples = []
    neg_examples = []

    for count, comp in enumerate(A.tocsc()[:].T):
        logging.debug(count)
        comp_d = np.array(comp.todense())
        gray_image = np.reshape(comp_d, dims, order='F')
        gray_image = (gray_image - np.min(gray_image)) / \
            (np.max(gray_image) - np.min(gray_image)) * 255
        gray_image = gray_image.astype(np.uint8)

        # segment using watershed
        markers = np.zeros_like(gray_image)
        elevation_map = sobel(gray_image)
        thr_1 = np.percentile(gray_image[gray_image > 0], 50)
        iqr = np.diff(np.percentile(gray_image[gray_image > 0], (25, 75)))
        thr_2 = thr_1 + num_std_threshold * iqr / 1.35
        markers[gray_image < thr_1] = 1
        markers[gray_image > thr_2] = 2
        edges = watershed(elevation_map, markers) - 1
        # only keep largest object
        label_objects, _ = scipy.ndimage.label(edges)
        sizes = np.bincount(label_objects.ravel())

        if len(sizes) > 1:
            idx_largest = np.argmax(sizes[1:])
            edges = (label_objects == (1 + idx_largest))
            edges = scipy.ndimage.binary_fill_holes(edges)
        else:
            logging.warning('empty component')
            edges = np.zeros_like(edges)

        masks_ws.append(edges)
        keypoints = detector.detect((edges * 200.).astype(np.uint8))

        if len(keypoints) > 0:
            pos_examples.append(count)
        else:
            neg_examples.append(count)

    return np.array(masks_ws), np.array(pos_examples), np.array(neg_examples)
#############
# LABEL DETECTION
#############

# Make segmentation using edge-detection and watershed.
elevation = sobel(stars_gray)
plt.figure()
plt.imshow(elevation, cmap=plt.cm.gray)

# Identify some background and foreground pixels from the intensity values.
# Unsure region is labeled 0
markers = np.zeros_like(stars_gray)
markers[stars_gray < 30.0] = 1  #background
markers[stars_gray > 150.0] = 2  #foreground

stars_segmented = watershed(mask, markers)
#seg1 = label(ws == foreground)
#regions_seg = regionprops(seg1)

#fig_label, ax_label = plt.subplots(1,1)
#color1 = label2rgb(seg1, image=stars_gray, bg_label=0)
#ax_label.imshow(edges,cmap=plt.cm.nipy_spectral)
#ax_label.set_title('Sobel+Watershed')
plt.figure()
plt.imshow(stars_segmented, cmap=plt.cm.gray)
stars_segmented = ndi.binary_fill_holes(stars_segmented - 1)
labeled_stars_segmented, _ = ndi.label(stars_segmented)
image_label_overlay = label2rgb(labeled_stars_segmented,
                                image=stars_gray,
                                bg_label=0)
Example #17
0
def main(bq, prob_map_dir, outdir, testing_data_dir, min_distance,
         label_threshold, black_threshold):
    table_service = bq.service('table')
    try:
        import tables
    except ImportError:
        logging.warn("pytables services not available")
    #some hyperparameters
    minimum = 50

    directory = prob_map_dir
    blk_threshold = 0.05
    min_dis = min_distance
    label_thresh = label_threshold
    files = os.listdir(directory)
    original_input = testing_data_dir + os.listdir(testing_data_dir)[0]
    output_files = []
    with tifffile.TiffFile(original_input) as tiff:
        imMeta = tiff.is_imagej
    for file in files:
        print file
        #slice_ind = seeds_slice_id # input('Please input the slice number for seeds:')
        blk_threshold = black_threshold  #input('Please input the threhold for black voxels')
        #slice_ind = slice_ind-1
        path = os.path.join(directory, file)
        img = sitk.ReadImage(path)
        img = sitk.GetArrayFromImage(img)
        img = img.astype('float32')
        seg_new = img / np.amax(img)
        slice_ind = slice_det(seg_new)
        seg_new[seg_new < blk_threshold] = 0
        mid_slice = seg_new[slice_ind]
        mask_mid = peak_local_max(-mid_slice,
                                  min_distance=min_dis,
                                  indices=False,
                                  exclude_border=1)
        #plt.imshow(mid_slice,cmap='gray')
        #plt.show()
        mask_mid = mask_mid * 1
        mask_mid = binary_opening(1 - mask_mid)
        mask_mid = binary_closing(mask_mid)
        distance = ndi.distance_transform_edt(1 - mask_mid)
        #mask_mid = peak_local_max(distance,min_distance=30,indices=False,threshold_rel=0.2)
        mask_mid_bin = np.zeros_like(distance)
        mask_mid_bin[distance > label_thresh] = 1
        masks = label(mask_mid_bin)
        #masks_img = sitk.GetImageFromArray((masks*255).astype('uint8'))
        #sitk.WriteImage(masks_img,'/home/tom/result/'+filename+'det.png')
        uni, counts = np.unique(masks, return_counts=True)
        for i in uni:
            if counts[i] < minimum:
                masks[masks == i] = 0
        uni, counts = np.unique(masks, return_counts=True)
        mask_temp = masks
        masks = mask_temp
        #plt.imshow(masks)
        #plt.show()
        #mask = watershed(seg_new[slice_ind],masks)
        #one_cell = np.zeros_like(seg_new)
        #one_cell[slice_ind] = mask
        #masks = propagate(seg_new,one_cell,slice_ind)
        mask_3d = np.zeros_like(seg_new)
        mask_3d[slice_ind] = masks
        #last = np.zeros((512,512))
        #first = np.zeros((512,512))
        #last[400:402,259:262]=30
        #first[375:380,245:250]=1
        #mask_3d[5]=last
        #mask_3d[18*5]=last
        #mask_3d[0]=first
        #masks_img = sitk.GetImageFromArray((masks*255).astype('uint8'))
        #sitk.WriteImage(masks_img,'/home/tom/result/'+'seeds.png')
        #masks = random_walker(seg_new,mask_3d,beta=10,mode='bf')
        masks = watershed(seg_new, mask_3d, watershed_line=True)
        #CRF
        #distance_one_cell = ndi.distance_transform_edt(one_cell)
        #distance_one_cell[distance_one_cell>15] = np.amax(distance_one_cell)
        #distance_one_cell = distance_one_cell/np.amax(distance_one_cell)
        #prob_map = np.multiply(1-prob_map,one_cell)
        #pro = CRFProcessor.CRF3DProcessor()
        #seg_new = np.transpose(prob_map,(1,2,0))
        #labels = np.zeros((512,512,12,2))
        #seg_new[seg_new>0.01] = 1
        #labels[:,:,:,0] = seg_new
        #labels[:,:,:,1] = 1-seg_new
        #distance_one_cell = np.transpose(distance_one_cell,(1,2,0))
        #result = pro.set_data_and_run(seg_new,labels)
        #result = np.transpose(result,(2,0,1))
        #print np.unique(result)
        #plt.imshow(mask_mid_bin)
        #plt.show()
        #masks = resize(masks,(masks.shape[0]/5,masks.shape[1],masks.shape[2]),mode='constant')
        #masks_img = sitk.GetImageFromArray((masks).astype('uint8'))
        #file_name = os.path.splitext(file)[0]
        #outfile = os.path.join(outdir,file_name+'-seg.tif')
        #sitk.WriteImage(masks_img,outfile)
        with tifffile.TiffWriter('source/result/' + file + 'seg.tif') as tif:
            for i in range(masks.shape[0]):
                tif.save(masks[i], extratags=[(270, 's', 1, imMeta)])
        labeled_image = label_segmentation('source/result/' + file + 'seg.tif')
        num_cells = len(np.unique(masks)) - 1
        coordinates = seg_img_coord(masks)
        #for label in np.unique(seg):
        adj_table = compute_cell_adjacent_table(masks)
        adj_table_done = tuple([(k, v) for k, v in adj_table.items()])
        #df = pd.DataFrame(adj_table)
        #df.to_csv("result/adj_table.csv")
        center = cell_center(masks)
        points = compute_conjunction_points(masks, adj_table)
        points_done = tuple([(k, [x for xs in v for x in xs])
                             for k, v in points.items()])
        #np.savetxt("result/points.csv", points, delimiter=",")

        cell_vol = cell_volumn(masks)
        cell_vol_done = tuple([(k, v) for k, v in cell_vol.items()])
        #df1 = pd.DataFrame(cell_volumn(masks))
        #df1.to_csv("result/cell_volumn.csv")
        output_files.append('source/result/' + file + 'seg.tif')
        tfu = adj_table.values()
        b = np.full([len(tfu), len(max(tfu, key=lambda x: len(x)))],
                    fill_value=np.nan)
        for i, j in enumerate(tfu):
            b[i][0:len(j)] = j

        with h5py.File('source/hdf/PlantCellSegmentation.h5', 'w') as hf:
            grp0 = hf.create_group("Cell Labels")
            grp1 = hf.create_group("Surface Coordinates")
            grp2 = hf.create_group("Cell Center")
            grp3 = hf.create_group("Cell Volume")
            grp4 = hf.create_group("Adjacency Table")
            grp5 = hf.create_group("Segmented Image")
            grp2.create_dataset("Cell Center",
                                data=(np.array((center.values()))))
            grp3.create_dataset("Cell Volume",
                                data=(np.array((cell_vol.values()))))
            grp4.create_dataset("Adjacency Table", data=b)
            grp0.create_dataset("Cell Labels", data=np.array((center.keys())))
            grp5.create_dataset("Segmented Image",
                                data=masks,
                                compression='gzip',
                                compression_opts=9)
            for ix in range(num_cells):
                grp1.create_dataset("Cell Label: {}".format(ix),
                                    compression='gzip',
                                    compression_opts=9,
                                    data=(np.array(
                                        (coordinates.values())))[ix])

        #outtable_xml_adj_table = table_service.store_array(adj_table_done, name='adj_table')
        #outtable_xml_points = table_service.store_array(points_done, name='points')
        #outtable_xml_cell_vol = table_service.store_array(cell_vol_done, name='cell_vol')
    #print(output_files)
    return output_files, adj_table, points, cell_vol, coordinates, center
Example #18
0
def generate_labels(data, labels_dir, masks_dir):
    tile_id, polygons = data
    out_mask_path = os.path.join(masks_dir, tile_id + ".png")
    # if os.path.exists(out_mask_path):
    #     return
    try:
        labels = np.zeros((3072, 3072), np.int16)
        label = 1

        for feat in polygons:
            if feat == "LINESTRING EMPTY" or feat == "POLYGON EMPTY":
                continue
            feat = feat.replace("POLYGON ((", "").replace(
                "POLYGON Z ((",
                "").replace("), (",
                            "|").replace("),(",
                                         "|").replace("(",
                                                      "").replace(")", "")
            feat_polygons = feat.split("|")
            for i, polygon in enumerate(feat_polygons):
                polygon_coords = []
                for xy in polygon.split(","):
                    xy = xy.strip()
                    x, y, *_ = xy.split(" ")
                    x = float(x)
                    y = float(y)
                    polygon_coords.append([x, y])

                coords = np.round(np.array(polygon_coords) * 3).astype(
                    np.int32)
                fillPoly(labels, [coords], label if i == 0 else 0)
                label += 1
        labels, _, _ = relabel_sequential(labels)
        small_labels = np.zeros_like(labels)
        eroded_labels = np.zeros_like(labels)
        big_labels = np.zeros_like(labels)
        very_big_labels = np.zeros_like(labels)
        for prop in measure.regionprops(labels):
            y1, x1, y2, x2 = prop.bbox
            if prop.minor_axis_length > 8:
                very_big_labels[y1:y2, x1:x2][prop.image > 0] = 1
            elif prop.minor_axis_length > 4:
                big_labels[y1:y2, x1:x2][prop.image > 0] = 1
            else:
                small_labels[y1:y2, x1:x2][prop.image > 0] = 1

            eroded_lbl = binary_erosion(prop.image, iterations=1)

            eroded_labels[y1:y2, x1:x2][eroded_lbl > 0] = prop.label
        cv2.imwrite(os.path.join(labels_dir, tile_id + ".tif"),
                    labels.astype(np.uint16))
        binary_image = binary_dilation((labels > 0),
                                       iterations=2).astype(np.uint8)
        tmp = watershed(binary_image,
                        mask=binary_image,
                        markers=eroded_labels,
                        watershed_line=True)
        ws_line = (binary_image ^ (tmp > 0)) * (1 - small_labels)
        fat_ws_line = (binary_dilation(ws_line, iterations=1) >
                       0) * (1 - big_labels) * (1 - small_labels)
        labels[ws_line > 0] = 0
        labels[fat_ws_line > 0] = 0
        labels, _, _ = relabel_sequential(labels)
        out = create_mask(labels).astype(np.uint8)
        out = Image.fromarray(out)

        out.save(out_mask_path, optimize=True)
    except Exception as e:
        traceback.print_exc()
        print(tile_id)
Example #19
0
def generate_trimap(model,
                    image_path,
                    kernel_size=10,
                    device='cuda',
                    dispart_mode=None):
    model = model.to(device).eval()
    #img = Image.open(image_path)
    img = image_path

    trf = T.Compose([
        T.ToTensor(),
        T.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
    ])

    inp = trf(img).unsqueeze(0).to(device)

    if device == 'cuda':
        torch.cuda.empty_cache()

    with torch.no_grad():
        om = model(inp)['out'][0]
        om = torch.softmax(om.squeeze(), 0)
    om = om.detach().cpu().numpy()

    del inp
    if device == 'cuda':
        torch.cuda.empty_cache()

    label_colors = np.array([
        (0, 0, 0),  # 0=background
        # 1=aeroplane, 2=bicycle, 3=bird, 4=boat, 5=bottle
        (128, 0, 0),
        (0, 128, 0),
        (128, 128, 0),
        (0, 0, 128),
        (128, 0, 128),
        # 6=bus, 7=car, 8=cat, 9=chair, 10=cow
        (0, 128, 128),
        (128, 128, 128),
        (64, 0, 0),
        (192, 0, 0),
        (64, 128, 0),
        # 11=dining table, 12=dog, 13=horse, 14=motorbike, 15=person
        (192, 128, 0),
        (64, 0, 128),
        (192, 0, 128),
        (64, 128, 128),
        (192, 128, 128),
        # 16=potted plant, 17=sheep, 18=sofa, 19=train, 20=tv/monitor
        (0, 64, 0),
        (128, 64, 0),
        (0, 192, 0),
        (128, 192, 0),
        (0, 64, 128)
    ])

    r = np.zeros_like(om[0, :, :]).astype(np.uint8)
    r_ = np.zeros_like(om[0, :, :]).astype(np.uint8)
    g = np.zeros_like(om[0, :, :]).astype(np.uint8)
    g_ = np.zeros_like(om[0, :, :]).astype(np.uint8)
    b = np.zeros_like(om[0, :, :]).astype(np.uint8)
    b_ = np.zeros_like(om[0, :, :]).astype(np.uint8)

    for l in range(0, 21):
        idx = om[l, :, :] > 0.05
        idx_ = om[l, :, :] > 0.95
        r[idx] = label_colors[l, 0]
        g[idx] = label_colors[l, 1]
        b[idx] = label_colors[l, 2]
        r_[idx_] = label_colors[l, 0]
        g_[idx_] = label_colors[l, 1]
        b_[idx_] = label_colors[l, 2]

    rgb = np.stack([r, g, b], axis=2)
    rgb_ = np.stack([r_, g_, b_], axis=2)

    rgb_gray = cv2.cvtColor(rgb, cv2.COLOR_BGR2GRAY)
    _, rgb_bw = cv2.threshold(rgb_gray, 10, 255, cv2.THRESH_BINARY)

    rgb_fg_gray = cv2.cvtColor(rgb_, cv2.COLOR_BGR2GRAY)
    _, rgb_fg_bw = cv2.threshold(rgb_fg_gray, 10, 255, cv2.THRESH_BINARY)

    #img = np.array(Image.open(image_path))
    img = np.array(image_path)

    #img_fz = felzenszwalb(img, scale=100, sigma=0.5, min_size=50)
    #img_fz = felzenszwalb(img, scale=100, sigma=0.5, min_size=50)
    #img_slic = slic(img, n_segments=250, compactness=10, sigma=1)
    img_quick = quickshift(img, kernel_size=1, max_dist=6, ratio=0.5, sigma=0)
    gradient = sobel(rgb2gray(img))
    img_watershed = watershed(gradient, markers=250, compactness=0.001)

    if dispart_mode == 'fg':
        temp = rgb_fg_bw / 255
        seg_ = dispart(temp.astype('int16'), img_quick)
        seg_ = seg_ * 255

        pixels = 2 * kernel_size + 1
        kernel = np.ones((pixels, pixels), np.uint8)

        dilation = cv2.dilate(rgb_bw, kernel, iterations=1)

        trimap = np.zeros_like(rgb_bw)  # bg
        trimap[dilation == 255] = 127  # confusion
        trimap[seg_ == 255] = 255  #fg

        return trimap

    if dispart_mode == 'bg':
        temp = rgb_bw / 255
        seg_ = dispart(temp.astype('int16'), img_quick)
        seg_ = seg_ * 255

        pixels = 2 * kernel_size + 1
        kernel = np.ones((pixels, pixels), np.uint8)

        dilation = cv2.dilate(seg_, kernel, iterations=1)

        trimap = np.zeros_like(seg_)  # bg
        trimap[dilation == 255] = 127  # confusion
        trimap[rgb_fg_bw == 255] = 255  #fg

        return trimap

    if dispart_mode == 'fg_bg':
        temp = rgb_fg_bw / 255
        seg_fg = dispart(temp.astype('int16'), img_quick)
        seg_fg = seg_fg * 255

        temp = rgb_bw / 255
        seg_bg = dispart(temp.astype('int16'), img_quick)
        seg_bg = seg_bg * 255

        pixels = 2 * kernel_size + 1
        kernel = np.ones((pixels, pixels), np.uint8)

        dilation = cv2.dilate(seg_bg, kernel, iterations=1)

        trimap = np.zeros_like(seg_bg)  # bg
        trimap[dilation == 255] = 127  # confusion
        trimap[seg_fg == 255] = 255  #fg

        return trimap

    else:
        pixels = 2 * 10 + 1
        kernel = np.ones((pixels, pixels), np.uint8)

        dilation = cv2.dilate(rgb_bw, kernel, iterations=1)

        remake = np.zeros_like(rgb_bw)
        remake[dilation == 255] = 127
        remake[rgb_fg_bw == 255] = 255

        return remake
                           myGrid=np.linspace(
                               xmin, xmax, num=xx[condition_label].shape[0]))
        xsnap = list(map(snap_fun, data[:, 0]))
        snap_fun = partial(p_utils.snapInd,
                           myGrid=np.linspace(
                               ymin, ymax, num=yy[condition_label].shape[1]))
        ysnap = list(map(snap_fun, data[:, 1]))
        points[condition_label] = np.ravel_multi_index(
            [xsnap, ysnap], xx[condition_label].shape)
        #points[condition_label] = geo.MultiPoint(np.array([xsnap,ysnap]).T)

        F[condition_label], kFactor = getFed(data,
                                             xx=xx[condition_label],
                                             yy=yy[condition_label])

        wtr[condition_label] = watershed(1 - F[condition_label],
                                         mask=F[condition_label] > 0.000001)
        uwtr = np.unique(wtr[condition_label])

        entropy = np.full(len(uwtr) + 1, 1, dtype='float')

        esig[condition_label] = sig / (len(uwtr) * len(types_ce))
        vsig[condition_label] = sig / (1 * len(types_cv))

        entropy_outs[condition_label] = np.full(len(CV), 1, dtype='float')
        cluster_outs[condition_label] = np.full(len(CV), 0, dtype='int')
        significant_outs[condition_label] = np.full(len(CV), False)

        e_routs = pd.DataFrame(columns=types_ce, dtype=float)
        e_ImgOuts[condition_label] = np.zeros(wtr[condition_label].shape)

        p_routs[condition_label] = {}
Example #21
0
def fill_segments(mask, objects, stem_objects=None, label="default"):
    """Fills masked segments from contours.

    Inputs:
    mask         = Binary image, single channel, object = 1 and background = 0
    objects      = List of contours

    Returns:
    filled_img   = Filled mask

    :param mask: numpy.ndarray
    :param objects: list
    :param stem_objects: numpy.ndarray
    :param label: str
    :return filled_img: numpy.ndarray
    """

    h, w = mask.shape
    markers = np.zeros((h, w))

    objects_unique = objects.copy()
    if stem_objects is not None:
        objects_unique.append(np.vstack(stem_objects))

    labels = np.arange(len(objects_unique)) + 1
    for i, l in enumerate(labels):
        cv2.drawContours(markers, objects_unique, i, int(l), 5)

    # Fill as a watershed segmentation from contours as markers
    filled_mask = watershed(mask == 0,
                            markers=markers,
                            mask=mask != 0,
                            compactness=0)

    # Count area in pixels of each segment
    ids, counts = np.unique(filled_mask, return_counts=True)

    if stem_objects is None:
        outputs.add_observation(
            sample=label,
            variable='segment_area',
            trait='segment area',
            method='plantcv.plantcv.morphology.fill_segments',
            scale='pixels',
            datatype=list,
            value=counts[1:].tolist(),
            label=(ids[1:] - 1).tolist())
    else:
        outputs.add_observation(
            sample=label,
            variable='leaf_area',
            trait='segment area',
            method='plantcv.plantcv.morphology.fill_segments',
            scale='pixels',
            datatype=list,
            value=counts[1:].tolist(),
            label=(ids[1:] - 1).tolist())
        outputs.add_observation(
            sample=label,
            variable='stem_area',
            trait='segment area',
            method='plantcv.plantcv.morphology.fill_segments',
            scale='pixels',
            datatype=list,
            value=counts[1:].tolist(),
            label=(ids[1:] - 1).tolist())

    rgb_vals = color_palette(num=len(labels), saved=False)
    filled_img = np.zeros((h, w, 3), dtype=np.uint8)
    for l in labels:
        for ch in range(3):
            filled_img[:, :, ch][filled_mask == l] = rgb_vals[l - 1][ch]

    _debug(visual=filled_img,
           filename=os.path.join(params.debug_outdir,
                                 str(params.device) + "_filled_img.png"))

    return filled_img
def label_cell(nuclei_pred, cell_pred):
    """Label the cells and the nuclei.

    Keyword arguments:
    nuclei_pred -- a 3D numpy array of a prediction from a nuclei image.
    cell_pred -- a 3D numpy array of a prediction from a cell image.

    Returns:
    A tuple containing:
    nuclei-label -- A nuclei mask data array.
    cell-label  -- A cell mask data array.

    0's in the data arrays indicate background while a continous
    strech of a specific number indicates the area for a specific
    cell.
    The same value in cell mask and nuclei mask refers to the identical cell.

    NOTE: The nuclei labeling from this function will be sligthly
    different from the values in :func:`label_nuclei` as this version
    will use information from the cell-predictions to make better
    estimates.
    """
    def __wsh(
        mask_img,
        threshold,
        border_img,
        seeds,
        threshold_adjustment=0.35,
        small_object_size_cutoff=10,
    ):
        img_copy = np.copy(mask_img)
        m = seeds * border_img  # * dt
        img_copy[m <= threshold + threshold_adjustment] = 0
        img_copy[m > threshold + threshold_adjustment] = 1
        img_copy = img_copy.astype(np.bool)
        img_copy = remove_small_objects(
            img_copy, small_object_size_cutoff).astype(np.uint8)

        mask_img[mask_img <= threshold] = 0
        mask_img[mask_img > threshold] = 1
        mask_img = mask_img.astype(np.bool)
        mask_img = remove_small_holes(mask_img, 1000)
        mask_img = remove_small_objects(mask_img, 8).astype(np.uint8)
        markers = ndi.label(img_copy, output=np.uint32)[0]
        labeled_array = segmentation.watershed(mask_img,
                                               markers,
                                               mask=mask_img,
                                               watershed_line=True)
        return labeled_array

    nuclei_label = __wsh(
        nuclei_pred[..., 2] / 255.0,
        0.4,
        1 - (nuclei_pred[..., 1] + cell_pred[..., 1]) / 255.0 > 0.05,
        nuclei_pred[..., 2] / 255,
        threshold_adjustment=-0.25,
        small_object_size_cutoff=500,
    )

    # for hpa_image, to remove the small pseduo nuclei
    nuclei_label = remove_small_objects(nuclei_label, 2500)
    nuclei_label = measure.label(nuclei_label)
    # this is to remove the cell borders' signal from cell mask.
    # could use np.logical_and with some revision, to replace this func.
    # Tuned for segmentation hpa images
    threshold_value = max(
        0.22,
        filters.threshold_otsu(cell_pred[..., 2] / 255) * 0.5)
    # exclude the green area first
    cell_region = np.multiply(
        cell_pred[..., 2] / 255 > threshold_value,
        np.invert(np.asarray(cell_pred[..., 1] / 255 > 0.05, dtype=np.int8)),
    )
    sk = np.asarray(cell_region, dtype=np.int8)
    distance = np.clip(cell_pred[..., 2], 255 * threshold_value, cell_pred[...,
                                                                           2])
    cell_label = segmentation.watershed(-distance, nuclei_label, mask=sk)
    cell_label = remove_small_objects(cell_label, 5500).astype(np.uint8)
    selem = disk(6)
    cell_label = closing(cell_label, selem)
    cell_label = __fill_holes(cell_label)
    # this part is to use green channel, and extend cell label to green channel
    # benefit is to exclude cells clear on border but without nucleus
    sk = np.asarray(
        np.add(
            np.asarray(cell_label > 0, dtype=np.int8),
            np.asarray(cell_pred[..., 1] / 255 > 0.05, dtype=np.int8),
        ) > 0,
        dtype=np.int8,
    )
    cell_label = segmentation.watershed(-distance, cell_label, mask=sk)
    cell_label = __fill_holes(cell_label)
    cell_label = np.asarray(cell_label > 0, dtype=np.uint8)
    cell_label = measure.label(cell_label)
    cell_label = remove_small_objects(cell_label, 5500)
    cell_label = measure.label(cell_label)
    cell_label = np.asarray(cell_label, dtype=np.uint16)
    nuclei_label = np.multiply(cell_label > 0, nuclei_label) > 0
    nuclei_label = measure.label(nuclei_label)
    nuclei_label = remove_small_objects(nuclei_label, 2500)
    nuclei_label = np.multiply(cell_label, nuclei_label > 0)

    return nuclei_label, cell_label
Example #23
0
import matplotlib.pyplot as plt
import numpy as np

from skimage.data import astronaut
from skimage.color import rgb2gray
from skimage.filters import sobel
from skimage.segmentation import felzenszwalb, slic, quickshift, watershed
from skimage.segmentation import mark_boundaries
from skimage.util import img_as_float

img = img_as_float(astronaut()[::2, ::2])
segments_fz = felzenszwalb(img, scale=100, sigma=0.5, min_size=50)
segments_slic = slic(img, n_segments=250, compactness=10, sigma=1)
segments_quick = quickshift(img, kernel_size=3, max_dist=6, ratio=0.5)
gradient = sobel(rgb2gray(img))
segments_watershed = watershed(gradient, markers=250, compactness=0.001)

print("Felzenszwalb's number of segments: %d" % len(np.unique(segments_fz)))
print('SLIC number of segments: %d' % len(np.unique(segments_slic)))
print('Quickshift number of segments: %d' % len(np.unique(segments_quick)))

fig, ax = plt.subplots(2, 2, sharex=True, sharey=True,
                       subplot_kw={'adjustable': 'box-forced'})
fig.set_size_inches(8, 3, forward=True)
fig.tight_layout()

ax[0, 0].imshow(mark_boundaries(img, segments_fz))
ax[0, 0].set_title("Felzenszwalbs's method")
ax[0, 1].imshow(mark_boundaries(img, segments_slic))
ax[0, 1].set_title('SLIC')
ax[1, 0].imshow(mark_boundaries(img, segments_quick))
Example #24
0
###################### Q5.3 filtre dynamique ######################
# img_rec = reconstruction(255 - img_ui,255 - img_ui + 20, selem=diamond(1))
# ui_min_reg = (img_rec != 255 - img_ui + 20)

##################### Q5.4 filtre conbine ############################
imgradient = dilation(img_ui, disk(2)) - erosion(img_ui, disk(2))
im_rec = reconstruction(dilation(imgradient, disk(2)),
                        imgradient,
                        method='erosion')
img_rec = reconstruction(255 - im_rec, 255 - im_rec + 20,
                         selem=diamond(1))  ## ici h = 20
ui_min_reg = (img_rec != 255 - im_rec + 20)

seeds = label(ui_min_reg, neighbors=8)  # Etiquetage des minima
ui_ws = watershed(img_ui,
                  seeds)  # LPE par defaut : Marqueur = Minima Regionaux
ws_display = color.label2rgb(ui_ws, img_ui)

# Affichage avec matplotlib
plt.subplot(131)
plt.imshow(img_ui, cmap='gray', vmin=0.0, vmax=255.0)
plt.title('Originale')
plt.subplot(132)
plt.imshow(ui_min_reg, cmap='gray', vmin=0.0, vmax=1.0)
plt.title('Minima regionaux')
plt.subplot(133)
plt.imshow(ws_display)
plt.title('Ligne de Partage des Eaux')
plt.show()

############################ Q6 ##################
Example #25
0
 def _skimage_ws(self, NEED_WL):
     return segmentation.watershed(
         self.skimage_dist,
         self.markers,
         connectivity=ndimage.generate_binary_structure(3, 3),
         watershed_line=NEED_WL)
Example #26
0
def wscat(catdir, catname, path, tile, savedir=False):
    # load full catalog
    allobjs = np.loadtxt(catdir + '/cosmos_full_cat.dat',
                         skiprows=1)  #cosmos_full_cat
    objra = allobjs[:, 2]
    objdec = allobjs[:, 3]

    # load sfg catalogs
    table = ascii.read(catdir + catname)  #cosmos_sfgcat_extended_update
    try:
        catalogs = np.array([
            table['z'], table['id'], table['x'], table['y'], table['ra'],
            table['dec']
        ]).T
    except KeyError:
        catalogs = np.array([
            table['zphot'], table['id'], table['x'], table['y'], table['ra'],
            table['dec']
        ]).T
    _ids = list(
        catalogs[:, 1]
    )  #np.loadtxt('{}.dat'.format(catname), skiprows=1, usecols=[0])
    # _ids = list(_ids)

    idsdec = [
        os.path.basename(_dir).split('-')[1].split('_')[0]
        for _dir in glob.glob('./{}/a{}/_id-*'.format(path, tile))
    ]
    idx = [_ids.index(float(_iddec)) for _iddec in idsdec]
    catalogs = catalogs[idx]
    catra = catalogs[:, 4]
    catdec = catalogs[:, 5]
    _ids = list(catalogs[:, 1])

    # load tile image
    hdu = fits.open('../images/{}/{}-ultravista_Ks.fits'.format(tile, tile))
    imgks = hdu[0].data
    header = hdu[0].header
    hdu.close()
    wcs = pywcs.WCS(header)

    # check extend of tile image
    tmparray = np.arange(31, 4096 - 31)
    ra, dec = wcs.all_pix2world(tmparray, tmparray, 1, ra_dec_order=True)
    minra = min(ra)
    maxra = max(ra)
    mindec = min(dec)
    maxdec = max(dec)

    # return idx of sfgs within tile image
    ra_idx = np.where((catra > minra) & (catra < maxra))[0]
    dec_idx = np.where((catdec > mindec) & (catdec < maxdec))[0]
    dec_idx = set(dec_idx)
    idx = list(set(ra_idx).intersection(set(dec_idx)))

    # change ra and dec to pixel coordinate of tile image
    catx, caty = wcs.all_world2pix(catra[idx],
                                   catdec[idx],
                                   1,
                                   ra_dec_order=True)
    catalogs = catalogs[idx, :]
    catalogs[:, 2] = catx
    catalogs[:, 3] = caty

    catalogs = catalogs[:]
    for i, (_id, x,
            y) in enumerate(zip(catalogs[:, 1], catalogs[:, 2], catalogs[:,
                                                                         3])):
        print(tile, i, _id)

        size = 26
        scale = 3
        tmpobjs = np.array(
            return_objcoord(wcs, [int(y), int(x)],
                            size, [objra, objdec],
                            scale=scale))
        localpeaks = peaks(tmpobjs, (2 * size * scale, 2 * size * scale))
        markers = ndi.label(localpeaks)[0]

        matchimg = imgks[int(y) - size:int(y) + size,
                         int(x) - size:int(x) + size]
        matchimg = rescale(
            matchimg, 156. / 52., mode='reflect',
            multichannel=False) * (52. / 156.)**2
        #     tmpdir = glob.glob('./selectedgal/resolved_sfgs/a{}/_id-{}*'.format(tile, int(_id)))[0]
        #     matchimg = fits.open('{}/subaru-zp_lambd-000100.0/g_1.fits'.format(tmpdir))[0].data
        #     matchimg = rescale(matchimg, 156./52., mode='reflect', multichannel=False)*(52./156.)**2

        tmpsig = 3.
        while True:
            masked = matchimg.copy()
            filtered = sigma_clip(matchimg, sigma=tmpsig, masked=True)
            distance = filtered.data
            filtered = filtered.mask
            masked[filtered == False] = np.nan

            idx = np.argmin((tmpobjs[:, 1] - 78)**2 + (tmpobjs[:, 0] - 78)**2)
            if not np.isnan(masked[int(tmpobjs[idx, 0]),
                                   int(tmpobjs[idx,
                                               1])]):  # idx 0 is y, 1 is x
                labels = watershed(-distance / np.sum(distance),
                                   markers,
                                   compactness=0.1,
                                   mask=filtered)  #-masked/np.sum(masked)

                segmap = labels.copy()
                segmap[abs(segmap - segmap[int(tmpobjs[idx, 0]),
                                           int(tmpobjs[idx, 1])]) > 0] = 0.
                segmap = ndi.binary_fill_holes(segmap).astype(float)

                # plt.imshow(matchimg*segmap)
                # plt.scatter(tmpobjs[:,1],tmpobjs[:,0], marker='x', color='r')
                # plt.show()

                edges = roberts(segmap)
                edges[edges > 0] = 1

                ex = np.where(edges == 1)[1]
                ey = np.where(edges == 1)[0]
                fit = fitEllipse(ex, ey, segmap)
                tmpx, tmpy, a, b, phi = fit.getparams()
                if not np.any(np.isnan([a, b, phi])):
                    break
                elif tmpsig < 2:
                    break
            tmpsig -= 0.5

        ell = fit.plotEllipse(a, b, phi)

        # print (_id, a, b, phi)
        # nrow = 1
        # ncol = 4
        # imscale = 2.5
        # fig = plt.figure(figsize=((ncol+1)*imscale, (nrow+1)*imscale))
        # gs = gridspec.GridSpec(nrow, ncol, wspace=0.0, hspace=0.0, top=1.-0.5/(nrow+1),\
        #                    bottom=0.5/(nrow+1), left=0.5/(ncol+1), right=1-0.5/(ncol+1))
        #
        # ax = plt.subplot(gs[0])
        # ax.imshow(matchimg, origin='lower')
        #
        # ax = plt.subplot(gs[1])
        # ax.imshow(masked, origin='lower')
        # ax.scatter(tmpobjs[:,1],tmpobjs[:,0], marker='x', color='r')
        #
        # ax = plt.subplot(gs[2])
        # ax.imshow(segmap, cmap=plt.cm.nipy_spectral, origin='lower')
        # ax.scatter(tmpobjs[:,1],tmpobjs[:,0], marker='x', color='r')
        #
        # ax = plt.subplot(gs[3])
        # ax.imshow(edges, origin='lower')
        # ax.scatter(tmpx+ell[0,:], tmpy+ell[1,:], color='g', s=2)
        # plt.show()

        if not os.path.isdir('./{}/a{}/watershed_segmaps'.format(path, tile)):
            os.makedirs('./{}/a{}/watershed_segmaps'.format(path, tile))

        if savedir and not np.any(np.isnan([a, b, phi])):
            hdr = fits.Header()
            hdr['XC'] = tmpx
            hdr['YC'] = tmpy
            hdr['SEMIMAJ'] = a
            hdr['SEMIMIN'] = b
            hdr['AXISUNIT'] = 'arcsecond'
            hdr['PA'] = phi
            hdr['PAUNIT'] = 'rad'
            hdr['SEGMAP'] = 'Based on Ks'
            hdu = fits.PrimaryHDU(segmap, hdr)
            hdu.writeto('./{}/a{}/watershed_segmaps/_id-{}.fits'.format(
                path, tile, int(_id)),
                        overwrite=True)
        elif np.any(np.isnan([a, b, phi])):
            filename = glob.glob('./{}/a{}/_id-{}*'.format(
                path, tile, int(_id)))[0]
            shutil.move(
                filename,
                filename.replace(os.path.basename(filename),
                                 'badphot/' + os.path.basename(filename)))
def Segmentation(img = io.imread(fullpath),
                 Levels = 2,
                Level1 = "QuickShift",
                Level2 = "RAG_Merging",
                useBounday = False,
                Debug = False):
    # Level1
    if Level1 == "QuickShift":    
        labels1 = segmentation.quickshift(img, kernel_size=3, max_dist=10, ratio=0.7)#.slic(img, compactness=30, n_segments=400)
    elif Level1 == "SLIC":
        labels1 = segmentation.slic(img, compactness=30, n_segments=400)
    elif Level1 == "felzenszwalb":
        labels1 = segmentation.felzenszwalb(img, scale=100, sigma=0.5, min_size=50)
    elif Level1 == "Watershed":
        gradient = sobel(rgb2gray(img))
        labels1 = segmentation.watershed(gradient, markers=250, compactness=0.001)
        
    out1 = color.label2rgb(labels1, img, kind='avg')

    if Levels == 1:
        if Debug:
            io.imshow(out1)
            print(labels1)
        return out1,labels1

    # Level2
    if Level2 == "NormalizedCut":        
        g = graph.rag_mean_color(img, labels1, mode='similarity')
        labels2 = graph.cut_normalized(labels1, g)
    elif Level2 == "RAG_Thresholding":
        g = graph.rag_mean_color(img, labels1)
        labels2 = graph.cut_threshold(labels1, g, 29)
    elif Level2 == "RAG_Merging":
        g = graph.rag_mean_color(img, labels1)      
        labels2 = graph.merge_hierarchical(labels1, g, thresh=35, rag_copy=False,
                                           in_place_merge=True,
                                           merge_func=merge_mean_color,
                                           weight_func=_weight_mean_color)       
        
    out2 = color.label2rgb(labels2, img, kind='avg')
    
    if useBounday:
        out1 = segmentation.mark_boundaries(out1, labels1, (1, 0, 0))
        out2 = segmentation.mark_boundaries(out2, labels2, (1, 1, 0))

    if Debug:
        print(labels1)
        print(labels2)       
        fig, ax = plt.subplots(nrows=3, sharex=True, sharey=True, figsize=(10, 12))
        print('level1 segments: {}'.format(len(np.unique(labels1))))
        print('level2 segments: {}'.format(len(np.unique(labels2))))
        
        ax[0].imshow(img)
        ax[1].imshow(out1)
        ax[2].imshow(out2)
        
        for a in ax:
            a.axis('off')
        
        plt.tight_layout()
    
    return out1,out2
Example #28
0
    def _process_frame(self, frame):
        # load volume
        #d2_data = ND2Reader(self.nd2_file)
        with ND2Reader(self.nd2_file) as nd2_data:
            v = get_nd2_vol(nd2_data, self.conf['object_channel'], frame)
            self.inspect_steps[0] = dict(name='original_volume', data=v)
            v = array_to_int8(v)

            # denoise images
            vi = vol_to_images(v)
            vi_dn = list(map(denoise, vi))
            v_dn = images_to_vol(vi_dn)
            v_dn = array_to_int8(v_dn)
            self.inspect_steps[1] = dict(name='denoised_volume', data=v_dn)
            #th, v_th = voting_threshold(v, adjust=8)

            # difference of gaussian
            v_dni = vol_to_images(v_dn)
            dog = create_dog_func(self.conf['dog_sigma1'],
                                  self.conf['dog_sigma2'])
            v_dg = images_to_vol(list(map(dog, v_dni)))
            self.inspect_steps[2] = dict(name='dog_volume', data=v_dg)

            # threshold
            v_dg_th = v_dg > self.conf['threshold']
            v_dg = array_to_int8(v_dg)
            self.inspect_steps[3] = dict(name='threshold_volume', data=v_dg_th)

            # watershed and create labels
            local_maxi = peak_local_max(
                v_dg,
                indices=False,
                min_distance=self.conf['peak_min_dist'],
                labels=v_dg_th)
            markers, num_objects = ndi.label(local_maxi,
                                             structure=np.ones((3, 3, 3)))
            #v_labels = watershed(-v_dg, markers, mask=v_dg_th)
            v_labels = watershed(-v_dg, markers, mask=v_dg_th, compactness=1)
            self.inspect_steps[4] = dict(name='labels_volume', data=v_labels)
            #   add to labels dask array to list
            self.labels[frame] = da.array(v_labels)

            # extract info from labels
            labels_idx = np.arange(1, v_labels.max())
            label_pos = ndi.measurements.center_of_mass(
                v_dg_th, v_labels, labels_idx)
            df = pd.DataFrame(label_pos)

            #collect data for inspection
            if self.conf['process_type'] == 'single_thread':
                self.inspect_steps[0] = dict(name='original_volume', data=v)
                self.inspect_steps[1] = dict(name='denoised_volume', data=v_dn)
                self.inspect_steps[2] = dict(name='dog_volume', data=v_dg)
                self.inspect_steps[3] = dict(name='threshold_volume',
                                             data=v_dg_th)
                self.inspect_steps[4] = dict(name='labels_volume',
                                             data=v_labels)

            #makes a dataframe with all coordinates
            df.columns = ['x', 'y', 'z']

            # adjust xs, ys to centrer roi
            if self.conf['center_roi']:
                adjust_x = self.conf['nd2info']['roi_x']
                adjust_y = self.conf['nd2info']['roi_y']
            else:
                adjust_x = 0
                adjust_y = 0

            df['xs'] = df['x'] * self.conf['nd2info']['px_microns'] - adjust_x
            df['ys'] = df['y'] * self.conf['nd2info']['px_microns'] - adjust_y
            df['zs'] = df['z'] * self.conf['z_dist']

            if self.conf['rotate']:
                #theta = np.radians(self.conf['rotate_angle'])
                #df['xxs'] = df['xs']*np.cos(theta) + df['ys']*np.sin(theta)
                #df['yys'] = df['ys']*np.cos(theta) - df['xs']*np.sin(theta)

                rot = Rot.from_euler('z',
                                     -self.conf['rotate_angle'],
                                     degrees=True)
                xyz = df[['xs', 'ys', 'zs']].to_numpy()
                xyz_rot = rot.apply(xyz)
                df['xs'], df['ys'] = xyz_rot[:, 0], xyz_rot[:, 1]

            df.insert(0, 'frame', frame)
            df.insert(1, 'time', frame / self.conf['nd2info']['frame_rate'])
            df.insert(0, 'path', self.nd2_file)

            df['size'] = ndi.measurements.sum(v_dg_th, v_labels, labels_idx)
            df['int_mean'] = ndi.measurements.mean(v, v_labels, labels_idx)
            df['int_max'] = ndi.measurements.maximum(v, v_labels, labels_idx)

            #df['c']=c

            intensity_channels = self.conf['intensity_channels']

            for c in intensity_channels:
                v_int = get_nd2_vol(nd2_data, c, frame)
                #v_int=ndimage.zoom(imf.get_vol(t=t, c=c2), (1,1,4),order=0)

                df['c' + str(c) + '_mean'] = ndi.measurements.mean(
                    v_int, v_labels, labels_idx)
                df['c' + str(c) + '_max'] = ndi.measurements.maximum(
                    v_int, v_labels, labels_idx)

        return df
Example #29
0
#imsave(amb_cc_save_fp, amb_cc)

print(f"amb cc max: {np.max(amb_cc)}")
print(f"amb cc n: {len(np.unique(amb_cc))}")

##################
### WATERSHED
##################

from skimage.measure import label
from skimage.morphology import remove_small_objects
from skimage.segmentation import watershed

print('doing watershed')
ws_w_small = watershed(image=boundary,
                       markers=amb_cc,
                       mask=area_bin.astype(np.uint16))

print('removing small')

ws_removed = remove_small_objects(ws_w_small, min_size=1500)
ws_removed = ws_removed.astype(np.uint16)

print('watershed done, saving')
ws_save_fp = ws_save_name + ".tiff"
imsave(ws_save_fp, ws_removed, check_contrast=False, compress=True)

print('finished')

########################
###  CONVERT TO H5
def compute_cell_bmap(cell_probs):
    output = cell_probs
    #output=output/np.max(output)
    #np.save('/Users/bharath/research/temp.npy',output)
    output2 = output[::2, ::2]
    local_maxi = peak_local_max(output2, indices=False, min_distance=5)
    markers = ndi.label(local_maxi, structure=np.ones((3, 3)))[0]

    maxscores = {}

    #markers[output2<0.01] = -1
    #segments = random_walker(output2, markers, tol=0.01)
    segments = watershed(-output2, markers, mask=output2 > 0.01)
    segments = resize(segments, output.shape, order=0, preserve_range=True)
    for l in np.unique(segments):
        maxscores[l] = np.max(output[segments == l])

    gx = convolve2d(segments, np.array([[1, 0, -1]]), mode='same')
    gx[0, :] = 0
    gx[-1, :] = 0
    gx[:, 0] = 0
    gx[:, -1] = 0
    gy = convolve2d(segments, np.array([[1, 0, -1]]).T, mode='same')
    gy[0, :] = 0
    gy[-1, :] = 0
    gy[:, 0] = 0
    gy[:, -1] = 0

    gmag = np.sqrt(gx**2 + gy**2)
    gmag = gmag > 0
    D = {}
    P = {}
    y, x = np.where(gmag)
    for i in range(y.size):
        nearby_labels = np.unique(segments[y[i] - 1:y[i] + 2,
                                           x[i] - 1:x[i] + 2])
        t = tuple(nearby_labels)

        if t in D.keys():
            D[t].append([y[i], x[i]])
            P[t].append(cell_probs[y[i], x[i]])
        else:
            D[t] = [[y[i], x[i]]]
            P[t] = [cell_probs[y[i], x[i]]]
    bmap = np.zeros(cell_probs.shape)
    for t in D.keys():

        min_peak = np.min([maxscores[k] for k in t if k != 0])
        coords = np.array(D[t])

        #if 2-way boundary:
        if len(t) < 3:
            score = np.mean(np.array(P[t]))
        else:
            perms = permutations(t, 2)
            perms = [np.mean(P[t]) for t in perms if t in P.keys()]
            score = np.min(perms)

        if 0 in t:
            bmap[coords[:, 0], coords[:, 1]] = 1
        else:
            bmap[coords[:, 0], coords[:, 1]] = min_peak - score
    bmap[0, :] = 1
    bmap[-1, :] = 1
    bmap[:, 0] = 1
    bmap[:, -1] = 1
    return bmap
import numpy as np

from skimage.data import astronaut
from skimage.color import rgb2gray
from skimage.filters import sobel
from skimage.segmentation import felzenszwalb, slic, quickshift, watershed
from skimage.segmentation import mark_boundaries
from skimage.util import img_as_float

img = img_as_float(astronaut()[::2, ::2])

segments_fz = felzenszwalb(img, scale=100, sigma=0.5, min_size=50)
segments_slic = slic(img, n_segments=250, compactness=10, sigma=1)
segments_quick = quickshift(img, kernel_size=3, max_dist=6, ratio=0.5)
gradient = sobel(rgb2gray(img))
segments_watershed = watershed(gradient, markers=250, compactness=0.001)

print("Felzenszwalb number of segments: {}".format(len(np.unique(segments_fz))))
print('SLIC number of segments: {}'.format(len(np.unique(segments_slic))))
print('Quickshift number of segments: {}'.format(len(np.unique(segments_quick))))

fig, ax = plt.subplots(2, 2, figsize=(10, 10), sharex=True, sharey=True)

ax[0, 0].imshow(mark_boundaries(img, segments_fz))
ax[0, 0].set_title("Felzenszwalbs's method")
ax[0, 1].imshow(mark_boundaries(img, segments_slic))
ax[0, 1].set_title('SLIC')
ax[1, 0].imshow(mark_boundaries(img, segments_quick))
ax[1, 0].set_title('Quickshift')
ax[1, 1].imshow(mark_boundaries(img, segments_watershed))
ax[1, 1].set_title('Compact watershed')
Example #32
0
def model_predict(img_path):
    #print(img_path)
    image = cv2.imread(img_path)
    #print(image.size)
    R = image[:, :, 0]
    G = image[:, :, 1]
    B = image[:, :, 2]
    temp = ((len(R) - 2) * (len(R[0]) - 2))
    avg = [None] * temp
    cov = [None] * temp
    avg1 = [None] * temp
    cov1 = [None] * temp
    avg2 = [None] * temp
    cov2 = [None] * temp

    #Kanal Red

    z = 0
    w = 0
    for x in range(1, len(R) - 1):
        for y in range(1, len(R[0]) - 1):
            avg[z] = (float(R[x - 1][y + 1]) + float(R[x][y + 1]) +
                      float(R[x + 1][y + 1]) + float(R[x + 1][y]) +
                      float(R[x + 1][y - 1]) + float(R[x][y - 1]) +
                      float(R[x - 1][y - 1]) + float(R[x - 1][y])) / 8
            z = z + 1

    for x in range(1, len(R) - 1):
        for y in range(1, len(R[0]) - 1):
            cov[w] = numpy.sqrt(((avg[w] - float(R[x - 1][y + 1]))**2 +
                                 (avg[w] - float(R[x][y + 1]))**2 +
                                 (avg[w] - float(R[x + 1][y + 1]))**2 +
                                 (avg[w] - float(R[x + 1][y]))**2 +
                                 (avg[w] - float(R[x + 1][y - 1]))**2 +
                                 (avg[w] - float(R[x][y - 1]))**2 +
                                 (avg[w] - float(R[x - 1][y - 1]))**2 +
                                 (avg[w] - float(R[x - 1][y]))**2) / 8)
            w = w + 1

    #Kanal Green
    z = 0
    w = 0

    for x in range(1, len(G) - 1):
        for y in range(1, len(G[0]) - 1):
            avg1[z] = (float(G[x - 1][y + 1]) + float(G[x][y + 1]) +
                       float(G[x + 1][y + 1]) + float(G[x + 1][y]) +
                       float(G[x + 1][y - 1]) + float(G[x][y - 1]) +
                       float(G[x - 1][y - 1]) + float(G[x - 1][y])) / 8
            z = z + 1

    for x in range(1, len(G) - 1):
        for y in range(1, len(G[0]) - 1):
            cov1[w] = numpy.sqrt(((avg1[w] - float(G[x - 1][y + 1]))**2 +
                                  (avg1[w] - float(G[x][y + 1]))**2 +
                                  (avg1[w] - float(G[x + 1][y + 1]))**2 +
                                  (avg1[w] - float(G[x + 1][y]))**2 +
                                  (avg1[w] - float(G[x + 1][y - 1]))**2 +
                                  (avg1[w] - float(G[x][y - 1]))**2 +
                                  (avg1[w] - float(G[x - 1][y - 1]))**2 +
                                  (avg1[w] - float(G[x - 1][y]))**2) / 8)
            w = w + 1

    #Kanal Blue
    z = 0
    w = 0

    for x in range(1, len(B) - 1):
        for y in range(1, len(B[0]) - 1):
            avg2[z] = (float(B[x - 1][y + 1]) + float(B[x][y + 1]) +
                       float(B[x + 1][y + 1]) + float(B[x + 1][y]) +
                       float(B[x + 1][y - 1]) + float(B[x][y - 1]) +
                       float(B[x - 1][y - 1]) + float(B[x - 1][y])) / 8
            z = z + 1

    for x in range(1, len(B) - 1):
        for y in range(1, len(B[0]) - 1):
            cov2[w] = numpy.sqrt(((avg2[w] - float(B[x - 1][y + 1]))**2 +
                                  (avg2[w] - float(B[x][y + 1]))**2 +
                                  (avg2[w] - float(B[x + 1][y + 1]))**2 +
                                  (avg2[w] - float(B[x + 1][y]))**2 +
                                  (avg2[w] - float(B[x + 1][y - 1]))**2 +
                                  (avg2[w] - float(B[x][y - 1]))**2 +
                                  (avg2[w] - float(B[x - 1][y - 1]))**2 +
                                  (avg2[w] - float(B[x - 1][y]))**2) / 8)
            w = w + 1

    matrix2 = numpy.empty([1, temp, 6])

    for y in range(0, temp):
        matrix2[0][y] = [
            avg[y] / 2, cov[y], avg1[y] / 2, cov1[y], avg2[y] / 2, cov2[y]
        ]

    X = matrix2[0]
    #print(X)

    pkl_filename = "models/kmeans_model.pkl"
    with open(pkl_filename, 'rb') as file:
        pickle_model = pickle.load(file)
    y_kmeans = pickle_model.predict(X)

    #kmeans = KMeans(n_clusters=5, random_state=0).fit(model)
    #y_kmeans = kmeans.predict(X)

    #Redrawing the matrix
    matrix3 = numpy.empty([len(R) - 2, len(R[0]) - 2])
    t = 0
    for x in range(0, len(matrix3)):
        for y in range(0, len(matrix3[0])):
            matrix3[x][y] = y_kmeans[t]
            t = t + 1

    #Redrawing Targeted Color
    matrix4 = numpy.empty([len(R) - 2, len(R[0]) - 2])
    t = 0
    for x in range(0, len(matrix4)):
        for y in range(0, len(matrix4[0])):
            if (y_kmeans[t] == 2):
                matrix4[x][y] = 1
            else:
                matrix4[x][y] = 0
            t = t + 1

    kernel = numpy.ones((3, 3), numpy.uint8)
    erosi = cv2.erode(matrix4, kernel, iterations=1)

    D = ndimage.distance_transform_edt(erosi)
    localMax = peak_local_max(D, indices=False, min_distance=10, labels=erosi)

    # perform a connected component analysis on the local peaks,
    # using 8-connectivity, then appy the Watershed algorithm
    markers = ndimage.label(localMax, structure=numpy.ones((3, 3)))[0]
    labels = watershed(-D, markers, mask=erosi)
    print("[INFO] {} unique segments found".format(
        len(numpy.unique(labels)) - 1))
    total_label = format(len(numpy.unique(labels)) - 1)

    plt.imsave('static/img_conv/testbc2.png', erosi, cmap='gray')
    #return render_template('index.html', name = 'new_plot', filename ='testbc2.png')
    return total_label