Example #1
0
def test_float_input():
    "[watershed]: Compare floating point input with integer input"
    f = np.random.random((128,64))
    f = mh.gaussian_filter(f, 8.)
    f = mh.gaussian_filter(f, 8.)
    markers,_ = mh.label(mh.regmin(f))
    f = np.round(f * 2**30)
    wf = mh.cwatershed(f / 2**30., markers)
    w32 = mh.cwatershed(f.astype(np.int32), markers)
    assert (wf == w32).mean() > .999
def test_run_distance(image, module, image_set, workspace):
    module.operation.value = "Distance"

    module.x_name.value = "binary"

    module.y_name.value = "watershed"

    module.connectivity.value = 3

    data = image.pixel_data

    if image.multichannel:
        data = skimage.color.rgb2gray(data)

    threshold = skimage.filters.threshold_otsu(data)

    binary = data > threshold

    image_set.add(
        "binary",
        cellprofiler.image.Image(
            image=binary,
            convert=False,
            dimensions=image.dimensions
        )
    )

    module.run(workspace)

    original_shape = binary.shape

    distance = scipy.ndimage.distance_transform_edt(binary)

    distance = mahotas.stretch(distance)

    surface = distance.max() - distance

    if image.volumetric:
        footprint = numpy.ones((3, 3, 3))
    else:
        footprint = numpy.ones((3, 3))

    peaks = mahotas.regmax(distance, footprint)

    if image.volumetric:
        markers, _ = mahotas.label(peaks, numpy.ones((16, 16, 16)))
    else:
        markers, _ = mahotas.label(peaks, numpy.ones((16, 16)))

    expected = mahotas.cwatershed(surface, markers)

    expected = expected * binary

    expected = skimage.measure.label(expected)

    actual = workspace.get_objects("watershed")

    actual = actual.segmented

    numpy.testing.assert_array_equal(expected, actual)
def test_watershed2():
    S = np.zeros((100,10), np.uint8)
    markers = np.zeros_like(S)
    markers[20,2] = 1
    markers[80,2] = 2
    W = mahotas.cwatershed(S, markers)
    assert np.all( (W == 1) | (W == 2) )
Example #4
0
def roysam_watershed(dna,thresh=None,blur_factor=3):
    '''
    Run watershed on mixed gradient & intensity image as suggested by Lin et al.

    -Input
    dna:            DNA image
    thresh:         Gray value threshold (default: computed using Murphy's RC)
    blur_factor:    Blur factor (default: 3)
    
    
    REFERENCE
    Gang Lin, Umesh Adiga, Kathy Olson, John F. Guzowski, Carol A. Barnes, and Badrinath Roysam
    "A Hybrid 3-D Watershed Algorithm Incorporating Gradient Cues & Object Models for Automatic
        Segmentation of Nuclei in Confocal Image Stacks"
     Vol. 56A, No. 1, pp. 23-36 Cytometry Part A, November 2003.
    '''
    if thresh is None:
        thresh = 'murphy_rc'
    M = (ndimage.gaussian_filter(dna,4) > thresholding.threshold(dna,thresh))
    G = pymorph.gradm(dna)
    D = ndimage.distance_transform_edt(M)
    D *= np.exp(1-G/float(G.max()))
    T = ndimage.gaussian_filter(D.max() - D,blur_factor)
    if T.max() < 256:
        T = pymorph.to_uint8(T)
    else:
        T = pymorph.to_uint8(T*(256.0/T.max()))
    T *= M
    R = pymorph.regmin(T)
    R *= M
    R,N = ndimage.label(R)
    R[(R==0)&(M==0)] = N+1
    W,WL = mahotas.cwatershed(T,R,return_lines=True)
    W *= M
    return W,WL
Example #5
0
def test_watershed_labeled():
    import mahotas as mh

    S = np.array([[0, 0, 0, 0], [0, 1, 2, 1], [1, 1, 1, 1], [0, 0, 1, 0], [1, 1, 1, 1], [1, 2, 2, 1], [1, 1, 2, 2]])
    M = np.array([[0, 0, 0, 0], [0, 0, 1, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 2, 0, 0], [0, 0, 0, 0]])
    labeled = mh.cwatershed(S, M)
    sizes = mh.labeled.labeled_sum(S, labeled)
    assert len(sizes) == labeled.max() + 1
def _segment(histone):
    markers = np.zeros_like(histone)
    markers[16::32, 16::32] = 1
    markers, _ = mh.label(markers)
    regions = mh.cwatershed(histone.max() - mh.gaussian_filter(histone, 1.2).astype(int), markers)
    sizes = mh.labeled.labeled_size(regions.astype(np.intc))
    invalid, = np.where(sizes < 512)
    return mh.labeled.relabel(mh.labeled.remove_regions(regions.astype(np.intc), invalid))
Example #7
0
def watershed(probs, radius):
    if probs.ndim == 3:
        shed = np.zeros(probs.shape)

        for n in xrange(probs.shape[0]):
            sel = disk(radius)
            minima = mh.regmin(probs[n], Bc=sel)
            markers, nr_markers = mh.label(minima)
            shed[n] = mh.cwatershed(probs[n], markers)

    else:
        sel = disk(radius)
        minima = mh.regmin(probs, Bc=sel)
        markers, nr_markers = mh.label(minima)
        shed = mh.cwatershed(probs, markers)

    return shed
def test_mix_types():
    f = np.zeros((64,64), np.uint16)
    f += (np.indices(f.shape)[1]**2).astype(np.uint16)
    f += ((np.indices(f.shape)[0]-23)**2).astype(np.uint16)
    markers = np.zeros((64,64), np.int64)
    markers[32,32] = 1
# Below used to force a crash (at least in debug mode)
    a,b = mahotas.cwatershed(f, markers, return_lines=1)
Example #9
0
def segment(img, T):
    binimg = (img > T)
    binimg = ndimage.median_filter(binimg, size=5)
    dist = mahotas.distance(binimg)
    dist = dist.astype(np.int32)
    maxima = pymorph.regmax(dist)
    maxima,_ = ndimage.label(maxima)
    return mahotas.cwatershed(dist.max() - dist, maxima)
Example #10
0
 def segmentCones(self):
     """Function to take regional maxima and segment the cones from them"""
     dist = mh.distance(self.orgImage > self.params['threshold'])
     dist = dist.max() - dist
     dist = dist = dist - dist.min()
     dist = dist/float(dist.ptp()) * 255
     dist = dist.astype(np.uint8)
     self.params['cones'] = mh.cwatershed(dist, self.ConeCounts.Seeds)
def WatershedFillDoubleSizedOutlineArray(arr):
    '''Take an image array similar to the "Outlines"
       (but with lines=0, cells=1 instead)
       and turn it into a (double-sized) fully segmented image'''
    arrEdit = ndimage.measurements.label(arr)[0]
    arrDouble = shape_multiply(arrEdit,[2,2]).astype(np.uint16)
    arrInvDouble = (1-shape_multiply(arr,[2,2])).astype(np.uint16)
    waterArr = mahotas.cwatershed(arrInvDouble,arrDouble)
    return waterArr
Example #12
0
def test_mix_types():
    "[watershed regression]: Mixing types of surface and marker arrays used to cause crash"
    f = np.zeros((64,64), np.uint16)
    f += (np.indices(f.shape)[1]**2).astype(np.uint16)
    f += ((np.indices(f.shape)[0]-23)**2).astype(np.uint16)
    markers = np.zeros((64,64), np.int64)
    markers[32,32] = 1
# Below used to force a crash (at least in debug mode)
    a,b = mahotas.cwatershed(f, markers, return_lines=1)
Example #13
0
 def cast_test(M, S, dtype):
     M = M.astype(dtype)
     S = S.astype(dtype)
     W = mahotas.cwatershed(2 - S, M)
     assert sys.getrefcount(W) == 2
     assert np.all(
         W
         == np.array(
             [[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1], [2, 2, 1, 1], [2, 2, 2, 2], [2, 2, 2, 2], [2, 2, 2, 2]]
         )
     )
Example #14
0
def sobel_segment(img):
    vsobel = np.array([
        [1,2,1],
        [0,0,0],
        [-1,-2,-1]])
    sobel = ndimage.convolve(img.astype(float),vsobel)**2
    hsobel = vsobel.T
    sobel += ndimage.convolve(img.astype(float), hsobel)**2
    imgf = ndimage.gaussian_filter(img,2)
    maxima,nmaxima = ndimage.label(pymorph.regmax(imgf))
    overseg = mahotas.cwatershed(sobel.astype(np.uint32), maxima)
    return overseg
Example #15
0
def compute_vertex_areas(input_map, adj_list):
    '''Computes the image map containing pixel-vertex relation'''
    surface = numpy.ones(input_map.shape, dtype=numpy.uint32)
    markers = numpy.zeros(input_map.shape, dtype=numpy.uint32)

    vertex_list = []

    for index, (x, y) in enumerate(adj_list.iterkeys()):
        markers[x, y] = index + 1
        vertex_list.append((x, y))

    return mahotas.cwatershed(surface, markers), vertex_list
Example #16
0
 def cast_test(dtype):
     St = S.astype(dtype)
     Mt = M.astype(int)
     W = mahotas.cwatershed(2-St,Mt)
     assert sys.getrefcount(W) == 2
     assert np.all(W == np.array([[1, 1, 1, 1],
            [1, 1, 1, 1],
            [1, 1, 1, 1],
            [2, 2, 1, 1],
            [2, 2, 2, 2],
            [2, 2, 2, 2],
            [2, 2, 2, 2]]))
def watershedSegment(image, diskSize=20):
    gradmag = gradientMagnitudue(image)

    ## compute foreground markers

    # open image to create flat regions at cell centers
    se_disk = pymorph.sedisk(diskSize) 
    image_opened = mahotas.open(image, se_disk);

    # define foreground markers as regional maxes of cells
    # this step is slow!
    foreground_markers = mahotas.regmax(image_opened)

    ## compute background markers

    # Threshold the image, cast it to the right datatype, and then calculate the distance image
    image_black_white = image_opened > mahotas.otsu(image_opened)
    image_black_white = image_black_white.astype('uint16')

    # note the inversion here- a key difference from the matlab algorithm
    # matlab distance is to nearest non-zero pixel
    # python distance is to nearest 0 pixel
    image_distance = pymorph.to_uint16(nd.distance_transform_edt(np.logical_not(image_black_white)))
    eight_conn = pymorph.sebox()

    distance_markers = mahotas.label(mahotas.regmin(image_distance, eight_conn))[0]
    image_dist_wshed, image_dist_wshed_lines =mahotas.cwatershed(image_distance, distance_markers, eight_conn, return_lines=True)
    background_markers = image_distance_watershed_lines - image_black_white

    all_markers = np.logical_or(foreground_markers, background_markers)

    # impose a min on the gradient image.  assumes int64
    gradmag2 = imimposemin(gradmag.astype(int), all_markers, eight_conn)

    # call watershed
    segmented_cells, segmented_cell_lines = mahotas.cwatershed(gradmag2, mahotas.label(all_markers)[0], eight_conn, return_lines=True)

    # seperate watershed regions
    segmented_cells[gradientMagnitudue(segmented_cells) > 0] = 0
    return segmented_cells > 0, segmented_cells
Example #18
0
def nuclei_regions(comp_map):
    """
    NUCLEI_REGIONS: extract "support regions" for nuclei. This function
    expects as input a "tissue components map" (as returned, for example,
    by segm.tissue_components) where values of 1 indicate pixels having
    a color corresponding to nuclei.
    It returns a set of compact support regions corresponding to the
    nuclei.


    :param comp_map: numpy.ndarray
       A mask identifying different tissue components, as obtained
       by classification in RGB space. The value 0

       See segm.tissue.tissue_components()

    :return:
    """
    # Deprecated:...
    # img_hem, _ = rgb2he(img0, normalize=True)

    # img_hem = denoise_tv_bregman(img_hem, HE_OPTS['bregm'])

    # Get a mask of nuclei regions by unsupervised clustering:
    # Vector Quantization: background, mid-intensity Hem and high intensity Hem
    # -train the quantizer for 3 levels
    # vq = KMeans(n_clusters=3)
    # vq.fit(img_hem.reshape((-1,1)))
    # -the level of interest is the brightest:
    # k = np.argsort(vq.cluster_centers_.squeeze())[2]
    # mask_hem = (vq.labels_ == k).reshape(img_hem.shape)
    # ...end deprecated

    # Final mask:
    mask = (comp_map == 1)   # use the components classified by color

    # mask = morph.closing(mask, selem=HE_OPTS['strel1'])
    # mask = morph.opening(mask, selem=HE_OPTS['strel1'])
    # morph.remove_small_objects(mask, in_place=True)
    # mask = (mask > 0)

    mask = mahotas.close_holes(mask)
    morph.remove_small_objects(mask, in_place=True)

    dst  = mahotas.stretch(mahotas.distance(mask))
    Bc=np.ones((9,9))
    lmax = mahotas.regmax(dst, Bc=Bc)
    spots, _ = mahotas.label(lmax, Bc=Bc)
    regions = mahotas.cwatershed(lmax.max() - lmax, spots) * mask

    return regions
# end NUCLEI_REGIONS
def GradBasedSegmentation(im):
    blur = nd.gaussian_filter(im, 16)
    rmax = pymorph.regmax(blur)
    T = mahotas.thresholding.otsu(blur)
    bImg0 = im > T
    # bImg01=nd.binary_closing(bImg0,iterations=2)
    bImg01 = pymorph.close(bImg0, pymorph.sedisk(3))
    bImg = pymorph.open(bImg01, pymorph.sedisk(4))
    # bImg=nd.binary_opening(bImg01,iterations=3)
    b = pymorph.edgeoff(bImg)
    d = distanceTranform(b)
    seeds, nr_nuclei = nd.label(rmax)
    lab = mahotas.cwatershed(d, seeds)
    return lab
def ConvertOutlinesToWatershed(origArr,outlines,useDilate=False,structure=[[0,1,0],[1,1,1],[0,1,0]]):
    if useDilate:
        outlines=ndimage.morphology.binary_dilation(origArr,structure=structure)
    labels = ndimage.label(1-outlines)[0]
    wh=np.where(labels==0)
    labels[wh]=-1
    labels+=1
    labels = labels.astype(np.uint16)
    labels[0]=1
    labels[-1]=1
    labels[:,0]=1
    labels[:,-1]=1
    
    water = mahotas.cwatershed(origArr,labels)
    return water
Example #21
0
def watershed_segment(img, mode='direct', thresholding=None, min_obj_size=None, **kwargs):
    '''
    segment_watershed(img, mode='direct', thresholding=None, min_obj_size=None, **kwargs)

    Segment using traditional watershed

    Parameters
    ----------

        * img: a pyslic.Image. The algorithm operates on the dna channel.
        * mode: 'direct' or 'gradient': whether to use the image or the gradient of the image
        * thresholding: how to threshold the smoothed image (default: None, no thresholding)
        * min_obj_size: minimum object size. This is slightly different than post-filtering for minimum 
            object size as it fill those holes with a second watershed pass as opposed to having
            an image with holes
        * smoothing: whether to smooth (default: True)
        * smooth_gamma: Size of Gaussian for blurring, in pixels (default: 12)
    '''
    assert mode in ('direct','gradient'), "segment_watershed: mode '%s' not understood" % mode
    with loadedimage(img):
        dna = img.get('dna')
        if kwargs.get('smoothing',True):
            dnaf = ndimage.gaussian_filter(dna, kwargs.get('smooth_gamma',12))
        else:
            dnaf = dna
        rmax = pymorph.regmax(dnaf)
        rmax_L,_ = ndimage.label(rmax)
        if mode == 'direct':
            watershed_img = dna.max()-dna
        elif mode == 'gradient':
            dnag = pymorph.gradm(dna)
            watershed_img = dnag.max()-dnag
        water = mahotas.cwatershed(watershed_img,rmax_L)
        if thresholding is not None:
            T = threshold(dnaf,thresholding)
            water *= (dnaf >= T)
        if min_obj_size is not None:
            oid = 1
            while oid <= water.max():
                if (water == oid).sum() < min_obj_size:
                    water[water == oid] =0
                    water[water > oid] -= 1
                else:
                    oid += 1
        return water
def _segment(cell):
    # takes a numpy array of a microscopy
    # segments it based on filtering the image then applying a distance transform and
    # a watershed method to get the proper segmentation

    import mahotas as mh
    filt_cell = mh.gaussian_filter(cell, 2)
    T = mh.thresholding.otsu((np.rint(filt_cell).astype('uint8')))
    dist = mh.stretch(mh.distance(filt_cell > T))
    
    Bc = np.ones((3,3))
    rmax = mh.regmin((dist))
    rmax = np.invert(rmax)
    labels, num_cells = mh.label(rmax, Bc)
    surface = (dist.max() - dist)
    areas = mh.cwatershed(dist, labels)
    areas *= T
    return areas
Example #23
0
def segment(fname):
    dna = mh.imread(fname)
    dna = dna[:,:,0]

    sigma = 12.
    dnaf = mh.gaussian_filter(dna, sigma)

    T_mean = dnaf.mean()
    bin_image = dnaf > T_mean
    labeled, nr_objects = mh.label(bin_image)

    maxima = mh.regmax(mh.stretch(dnaf))
    maxima = mh.dilate(maxima, np.ones((5,5)))
    maxima,_ = mh.label(maxima)
    dist = mh.distance(bin_image)
    dist = 255 - mh.stretch(dist)
    watershed = mh.cwatershed(dist, maxima)
    watershed *= bin_image
    return watershed
Example #24
0
def create_segmentation_from_seeds( input_image, seed_image ):
    """Create a Seedwater style segmentation from a bunch of seeds in an image.
    
    Parameters
    ----------
    
    input_image : nd_array
        image that should be segmented
        
    seed_image : nd_array
        image that contains the seeds
        
    Returns
    -------
    
    segmentation : nd_array
        segmented image represented as 16bit integer image
    """
    segmented_image = mahotas.cwatershed( input_image, seed_image )
    segmented_image_as_16_bit = np.array( segmented_image, dtype = 'uint16' )
    
    return segmented_image_as_16_bit
Example #25
0
def test_overflow():
    '''Test whether we can force an overflow in the output of cwatershed

    This was reported as issue #41 on github:

    https://github.com/luispedro/mahotas/issues/41
    '''
    f = np.random.random((128,64))
    f *= 255 
    f = f.astype(np.uint8)
    for max_n in [127, 240, 280]:
        markers = np.zeros(f.shape, np.int)
        for i in range(max_n):
            while True:
                a = np.random.randint(f.shape[0])
                b = np.random.randint(f.shape[1])
                if markers[a,b] == 0:
                    markers[a,b] = i + 1
                    break
                
        r = mh.cwatershed(f, markers)
        assert markers.max() == max_n
        assert r.max() == max_n
def test_mismatched_array_markers():
    S = np.zeros((10,12), np.uint8)
    markers = np.zeros((8,12), np.uint8)
    markers[2,2] = 1
    markers[6,2] = 2
    mahotas.cwatershed(S, markers)
Example #27
0
             with timer.Timer("maxflow"):
                 print "Flow is {0}".format(flow_graph.maxflow())
 
             labels = flow_graph.what_segment_vectorized()
             labels = labels.reshape(imshape)
 
             with timer.Timer("close/open"):
                 labels = mahotas.morph.close(labels.astype(np.bool), disc)
                 labels = mahotas.morph.open(labels.astype(np.bool), disc)
 
             ## Use blurred probabilities and watershed instead of region growing
             with timer.Timer("label2"):
                 seeds,_ = mahotas.label(labels==1)
 
             with timer.Timer("watershed"):
                 ws = mahotas.cwatershed(blur_prob, seeds)
 
             with timer.Timer("gradient2"):
                 dx, dy = np.gradient(ws)
                 ws_boundary = np.logical_or(dx!=0, dy!=0)
 
             ## Identify possible extra-cellular space - distance method
             #extra_cellular = np.logical_and(mahotas.distance(labels==0) > 100, seeds == np.min(seeds))
             #extra_cellular = mahotas.morph.close(extra_cellular.astype(np.bool), disc)
             #extra_cellular = mahotas.morph.open(extra_cellular.astype(np.bool), disc)
             #extra_cellular_indices = np.nonzero(extra_cellular)
 
             ## Identify possible extra-cellular space - minima method
             with timer.Timer("extra_cellular"):
                 with timer.Timer("    (sub)min"):
                     rmin = mahotas.regmin(blur_prob, min_disc)
Example #28
0
        valid_ids = np.nonzero(compressed_id_map)[0]
        compressed_id_map[valid_ids] = np.arange(1, len(valid_ids) + 1, dtype=np.uint32)

        print "Compressing {0} ids down to {1}.".format(compressed_id_map.shape[0], len(valid_ids))

    for file in files:

        original_input_ids_name = file

        original_ids = load_id_image(original_input_ids_name)

        ## Grow regions until there are no boundaries

        ## Method 4 - watershed
        original_ids = mahotas.cwatershed(
            np.zeros(original_ids.shape, dtype=np.uint32), original_ids, return_lines=False
        )

        if compress_ids:
            original_ids = compressed_id_map[original_ids]

        # boundaries = original_ids == 0
        # boundary_indices = np.nonzero(boundaries)
        # grow_count = 0
        # while len(boundary_indices[0]) > 0:

        #    ## Method 1 - dilate (slow)
        #    #original_ids[boundary_indices] = mahotas.dilate(original_ids)[boundary_indices] - 1

        #    ## Method 2 - conditional dilate (doesn't work)
        #    #original_ids[boundary_indices] = mahotas.cdilate(original_ids, boundaries==0)[boundary_indices] - 1
Example #29
0
	boundaries = label_img==0;
	boundaries[0:-1,:] = np.logical_or(boundaries[0:-1,:],  diff(label_img, axis=0)!=0);
	boundaries[:,0:-1] = np.logical_or(boundaries[:,0:-1], diff(label_img, axis=1)!=0);

	# erode to be sure we include at least one membrane
	inside = mahotas.erode(boundaries == 0, shrink_disc)

	#display = input_img.copy()
	#display[np.nonzero(inside)] = 0
	#figure(figsize=(20,20))
	#imshow(display, cmap=cm.gray)

	seeds = label_img.copy()
	seeds[np.nonzero(inside==0)] = 0
	grow = mahotas.cwatershed(255-blur_img, seeds)

	membrane = np.zeros(input_img.shape, dtype=uint8)
	membrane[0:-1,:] = diff(grow, axis=0) != 0;
	membrane[:,0:-1] = np.logical_or(membrane[:,0:-1], diff(grow, axis=1) != 0);

	#display[np.nonzero(membrane)] = 2
	#figure(figsize=(20,20))
	#imshow(display, cmap=cm.gray)

	# erode again to avoid all membrane
	non_membrane = mahotas.erode(inside, shrink_disc)

	if mask is None:
		mask = ones(input_img.shape, dtype=uint8)
		mask[:min_border,:] = 0;
Example #30
0
            nlabels = nlabels + 1

        if nlabels <= 1:
            print "Cleanup only found {0} segment - nothing to do.".format(nlabels)
            clean_vol = label_vol
        else:

            packed_vol = np.reshape(packed_vol, label_vol.shape)

            print "Cleanup starting with {0} segments.".format(nlabels)

            # Grow labels so there are no boundary pixels
            if has_boundaries:
                for image_i in range(packed_vol.shape[2]):
                    label_image = packed_vol[:,:,image_i]
                    packed_vol[:,:,image_i] = mahotas.cwatershed(np.zeros(label_image.shape, dtype=np.uint32), label_image, return_lines=False)

            if Debug:
                from libtiff import TIFF
                for image_i in range(packed_vol.shape[2]):
                    tif = TIFF.open('preclean_z{0:04}.tif'.format(image_i), mode='w')
                    tif.write_image(np.uint8(packed_vol[:, :, image_i] * 13 % 251))

            # Determine label adjicency and sizes

            borders = np.zeros(packed_vol.shape, dtype=np.bool)

            # Code currently only supports a 3d volume
            assert(packed_vol.ndim == 3)

            with timer.Timer("adjicency matrix construction"):