Example #1
0
def test_square_image():
    im = np.zeros((50, 50)).astype(float)
    im[:25, :25] = 1.

    # Moravec
    results = peak_local_max(corner_moravec(im),
                             min_distance=10, threshold_rel=0)
    # interest points along edge
    assert len(results) == 57

    # Harris
    results = peak_local_max(corner_harris(im, method='k'),
                             min_distance=10, threshold_rel=0)
    # interest at corner
    assert len(results) == 1

    results = peak_local_max(corner_harris(im, method='eps'),
                             min_distance=10, threshold_rel=0)
    # interest at corner
    assert len(results) == 1

    # Shi-Tomasi
    results = peak_local_max(corner_shi_tomasi(im),
                             min_distance=10, threshold_rel=0)
    # interest at corner
    assert len(results) == 1
    def average_hough_detections(self, hough_radii, hough_res, num_best=5):
        """
        Smooths `num_best` hough detections with Gaussian and
        computes weighted average across the `num_best` hough
        detections to get more precise center_x, center_y and
        radius of circle
        """

        centers = []
        accums = []
        radii = []

        for radius, h in zip(hough_radii, hough_res):
            # For each radius, extract two circles
            h_smooth = skifilt.gaussian_filter(h, sigma=4)
            num_peaks = 1
            peaks = skif.peak_local_max(h, min_distance=40, num_peaks=num_peaks)
            centers.extend(peaks)
            accums.extend(h[peaks[:, 0], peaks[:, 1]])
            radii.extend([radius] * num_peaks)

        h_sum = np.sum([skifilt.gaussian_filter(x, sigma=2)
                        for x in hough_res[np.argsort(accums)[::-1][:num_best]]], axis=0)

        peaks = skif.peak_local_max(h_sum, min_distance=40, num_peaks=num_peaks)

        center_x, center_y = peaks[0]

        max_sel = [np.max(x.ravel()) for x in hough_res[np.argsort(accums)[::-1][:num_best]]]
        radii_sel = [radii[i] for i in np.argsort(accums)[::-1][:num_best]]

        radius = sum([m * r for m, r in zip(max_sel, radii_sel)]) / float(sum(max_sel))

        return center_x, center_y, int(radius)
Example #3
0
def find_peaks(img, npeaks=float("inf")):
    threshold = lambda x: 10.0 ** (-x)
    log_th = __MIN_THRESHOLD
    peaks = peak_local_max(img, threshold_rel=threshold(log_th))

    while len(peaks) > npeaks and log_th > __MAX_THRESHOLD:
        log_th -= 0.05
        peaks = peak_local_max(img, threshold_rel=threshold(log_th))

    return peaks
def get_local_maxima(im_array, min_distance, threshold_rel):
    """Return the local maxima."""
    img =  peak_local_max(im_array,
                          indices=False,
                          min_distance=min_distance,
                          threshold_rel=threshold_rel)
    coords =  peak_local_max(im_array,
                             indices=True,
                             min_distance=min_distance,
                             threshold_rel=threshold_rel)
    return img, coords
Example #5
0
def test_squared_dot():
    im = np.zeros((50, 50))
    im[4:8, 4:8] = 1
    im = img_as_float(im)

    # Moravec fails

    # Harris
    results = peak_local_max(corner_harris(im))
    assert (results == np.array([[6, 6]])).all()

    # Shi-Tomasi
    results = peak_local_max(corner_shi_tomasi(im))
    assert (results == np.array([[6, 6]])).all()
Example #6
0
def find_n_local_minima(image, n=0):
    """Takes a 3D image and creates a local minimum mask, and n minima mask

    """
    # Invert image so we are searching for maximas
    im_inv = np.invert(image)
    
    # Find peaks in each of r,g,b
    minimaR = peak_local_max(im_inv[:,:,0])
    minimaG = peak_local_max(im_inv[:,:,1])
    minimaB = peak_local_max(im_inv[:,:,2])
    
    # each of the minima will have an array of shape (n, 2)
    # where n is the number of minima

    # get 2D dimensions of the image
    y, x, z = image.shape
    zR = np.zeros((y, x))
    zG = np.zeros((y, x))
    zB = np.zeros((y, x))
    nMinima = np.zeros((y, x))

    # Make zR, zG, zB an accumulator space for the minima points
    zR[minimaR[:,0], minimaR[:,1]] = 1
    zG[minimaG[:,0], minimaG[:,1]] = 1
    zB[minimaB[:,0], minimaB[:,1]] = 1
    # Find where peaks in rgb overlap
    minima = zR * zG * zB

    if n != 0:
        i, j = np.nonzero(minima)

        # making sure the number of minima is not exceeded
        if n > np.sum(minima):
            n = np.sum(minima)

        ix = np.random.choice(len(i), n, replace=False)
        
        nMinima[i[ix], j[ix]] = 1

        # Label the masked image
        labelled = label(nMinima)

        #Make an nMinima shape of the image
        markers = np.zeros(image.shape)
        for i in range(z):
            markers[:,:,i] = labelled
        return minima, markers
    else:
        return minima
Example #7
0
def detect_Hough(data):
    image = data.copy()
    edges = canny(image, sigma=10, low_threshold=60, high_threshold=90)

    # Detect circles between 80% and 100% of image semi-diagonal
    lx, ly = data.shape
    sizex, sizey = lx/2., ly/2.
    max_r = numpy.sqrt(sizex**2 + sizey**2) 
    hough_radii = numpy.linspace(0.5*max_r, 0.9 * max_r, 20)
    hough_res = hough_circle(edges, hough_radii)


    centers = []
    accums = []
    radii = []
    for radius, h in zip(hough_radii, hough_res):
        # For each radius, extract two circles
        num_peaks = 2
        peaks = peak_local_max(h, num_peaks=num_peaks)
        centers.extend(peaks)
        accums.extend(h[peaks[:, 0], peaks[:, 1]])
        radii.extend([radius] * num_peaks)

    # Use the most prominent circle
    idx = numpy.argsort(accums)[::-1][:1]
    center_x, center_y = centers[idx]
    radius = radii[idx]
    return center_x, center_y, radius
def LargestWatershedRegion(shapes,dims,skipBias): 
    L=len(shapes)-skipBias     
    shapes=shapes.reshape((-1,) + dims[1:]) 
    D=len(dims)
    num_peaks=4
#    structure=np.ones(tuple(3*np.ones((np.ndim(shapes)-1,1))))
    for ll in range(L): 
        temp=shapes[ll]
        local_maxi = peak_local_max(gaussian_filter(temp,[1]*(D-1)), exclude_border=False, indices=False, num_peaks=num_peaks)
        markers,junk = label(local_maxi)
        nonzero_mask=temp>0
        if np.sum(nonzero_mask)>(3**3)*num_peaks:
            labels = watershed(-temp, markers, mask=nonzero_mask) #watershed regions
            ind = 1
            temp2 = np.copy(temp)
            temp2[labels!=1]=0
            total_intensity = sum(temp2.reshape(-1,))
            for kk in range(2,labels.max()+1):
                temp2 = np.copy(temp)
                temp2[labels!=kk]=0
                total_intensity2 = sum(temp2.reshape(-1,))
                if total_intensity2>total_intensity:
                    ind = kk
                    total_intensity=total_intensity2
            temp[labels!=ind]=0
            shapes[ll]=temp
    shapes=shapes.reshape((len(shapes),-1))
    return shapes
Example #9
0
def test_circles2():
    data = np.memmap("E:\\guts_tracking\\data\\fish202_aligned_masked_8bit_150x200x440.raw", dtype='uint8', shape=(440,200,150)).copy()

    i = 157

    hough_radii = np.arange(10, 100, 10)
    edges = feature.canny(data[i], sigma=3.0, low_threshold=0.4, high_threshold=0.8)
    hough_res = hough_circle(edges, hough_radii)

    centers = []
    accums = []
    radii = []

    for radius, h in zip(hough_radii, hough_res):
        peaks = feature.peak_local_max(h)
        centers.extend(peaks)
        accums.extend(h[peaks[:, 0], peaks[:, 1]])
        radii.extend([radius] * len(peaks))

    image = ski.color.gray2rgb(data[i])

    for idx in np.argsort(accums)[::-1][:5]:
        center_x, center_y = centers[idx]
        radius = radii[idx]
        cx, cy = circle_perimeter(center_y, center_x, radius)

        if max(cx) < 150 and max(cy) < 200:
            image[cy, cx] = (220, 20, 20)

    plt.imshow(image, cmap='gray')

    plt.show()
Example #10
0
    def animate(i):
        print 'Frame %d' % i
        plt.title('Frame %d' % i)

        image = data[i]

        hough_radii = np.arange(10, 100, 10)
        edges = feature.canny(data[i], sigma=3.0, low_threshold=0.4, high_threshold=0.8)
        hough_res = hough_circle(edges, hough_radii)

        centers = []
        accums = []
        radii = []

        for radius, h in zip(hough_radii, hough_res):
            peaks = feature.peak_local_max(h)
            centers.extend(peaks)
            accums.extend(h[peaks[:, 0], peaks[:, 1]])
            radii.extend([radius] * len(peaks))

        image = ski.color.gray2rgb(data[i])

        for idx in np.argsort(accums)[::-1][:5]:
            center_x, center_y = centers[idx]
            radius = radii[idx]
            cx, cy = circle_perimeter(center_y, center_x, radius)

            if max(cx) < 150 and max(cy) < 200:
                image[cy, cx] = (220, 20, 20)

        im.set_data(image)

        return im,
Example #11
0
def test_template():
    size = 100
    # Float prefactors ensure that image range is between 0 and 1
    image = np.full((400, 400), 0.5)
    target = 0.1 * (np.tri(size) + np.tri(size)[::-1])
    target_positions = [(50, 50), (200, 200)]
    for x, y in target_positions:
        image[x:x + size, y:y + size] = target
    np.random.seed(1)
    image += 0.1 * np.random.uniform(size=(400, 400))

    result = match_template(image, target)
    delta = 5

    positions = peak_local_max(result, min_distance=delta)

    if len(positions) > 2:
        # Keep the two maximum peaks.
        intensities = result[tuple(positions.T)]
        i_maxsort = np.argsort(intensities)[::-1]
        positions = positions[i_maxsort][:2]

    # Sort so that order matches `target_positions`.
    positions = positions[np.argsort(positions[:, 0])]

    for xy_target, xy in zip(target_positions, positions):
        assert_almost_equal(xy, xy_target)
Example #12
0
def watershed_segmentation(rgb_img, mask, distance=10):
    """Uses the watershed algorithm to detect boundary of objects. Needs a marker file which specifies area which is
       object (white), background (grey), unknown area (black).

    Inputs:
    rgb_img             = image to perform watershed on needs to be 3D (i.e. np.shape = x,y,z not np.shape = x,y)
    mask                = binary image, single channel, object in white and background black
    distance            = min_distance of local maximum

    Returns:
    analysis_images     = list of output images

    :param rgb_img: numpy.ndarray
    :param mask: numpy.ndarray
    :param distance: int
    :return analysis_images: list
    """
    params.device += 1
    # # Will be depricating opencv version 2
    # if cv2.__version__[0] == '2':
    #     dist_transform = cv2.distanceTransform(mask, cv2.cv.CV_DIST_L2, maskSize=0)
    # else:
    dist_transform = cv2.distanceTransformWithLabels(mask, cv2.DIST_L2, maskSize=0)[0]

    localMax = peak_local_max(dist_transform, indices=False, min_distance=distance, labels=mask)

    markers = ndi.label(localMax, structure=np.ones((3, 3)))[0]
    dist_transform1 = -dist_transform
    labels = watershed(dist_transform1, markers, mask=mask)

    img1 = np.copy(rgb_img)

    for x in np.unique(labels):
        rand_color = color_palette(len(np.unique(labels)))
        img1[labels == x] = rand_color[x]

    img2 = apply_mask(img1, mask, 'black')

    joined = np.concatenate((img2, rgb_img), axis=1)

    estimated_object_count = len(np.unique(markers)) - 1

    analysis_image = []
    analysis_image.append(joined)

    if params.debug == 'print':
        print_image(dist_transform, os.path.join(params.debug_outdir, str(params.device) + '_watershed_dist_img.png'))
        print_image(joined, os.path.join(params.debug_outdir, str(params.device) + '_watershed_img.png'))
    elif params.debug == 'plot':
        plot_image(dist_transform, cmap='gray')
        plot_image(joined)

    outputs.add_observation(variable='estimated_object_count', trait='estimated object count',
                            method='plantcv.plantcv.watershed', scale='none', datatype=int,
                            value=estimated_object_count, label='none')

    # Store images
    outputs.images.append(analysis_image)

    return analysis_image
Example #13
0
def findBraggs(A, min_distance=2, threshold_rel=0.5, norm='linear', rspace=True, zero_center=True):
    '''
    find Bragg peaks of topo image A using peak_local_max, will plot modulus of FT of A with result points
    NOTE: PLEASE REMOVE NON-BRAGG PEAKS MANUALLY BY 'Bragg = np.delete(coords, [indices], axis=0)'

    Parameters: 
    min_distance - peaks are separated by at least min_distance in pixel;
    threshold_rel - minimum intensity of peaks, calculated as max(image) * threshold_rel
    norm: 'linear' or 'log', scale of display
    rspace: True - real space; False - reciprocal space
    zero_center - whether or not zero the DC point of Fourier transform
    '''
    if rspace:
        ft = np.fft.fft2(A)
        if zero_center:
            ft[0,0] = 0
        F = np.absolute(np.fft.fftshift(ft))
    else:
        F = np.copy(A)
    cnorm = mpl.colors.Normalize(vmin=F.min(), vmax=F.max())
    if norm is 'log':
        cnorm = mpl.colors.LogNorm(vmin=F.mean(), vmax=F.max())
    coords = peak_local_max(F, min_distance=min_distance, threshold_rel=threshold_rel)
    coords = np.fliplr(coords)
    plt.imshow(F, cmap=plt.cm.gray, origin='lower', norm=cnorm, aspect=1)
    plt.plot(coords[:, 0], coords[:, 1], 'r.')
    plt.gca().set_aspect(1)
    plt.axis('tight')
    print('#:\t[x y]')
    for ix, iy in enumerate(coords):
        print(ix, end='\t')
        print(iy)
    return coords
def segment_out_cells(base):
    # TODO: try using OTSU for GFP thresholding

    sel_elem = disk(2)
    gfp_collector = np.sum(base, axis=0)
    gfp_clustering_markers = np.zeros(gfp_collector.shape, dtype=np.uint8)
    # random walker segment
    gfp_clustering_markers[gfp_collector > np.mean(gfp_collector) * 2] = 2
    gfp_clustering_markers[gfp_collector < np.mean(gfp_collector) * 0.20] = 1
    labels = random_walker(gfp_collector, gfp_clustering_markers, beta=10, mode='bf')
    # round up the labels and set the background to 0 from 1
    labels = closing(labels, sel_elem)
    labels -= 1
    # prepare distances for the watershed
    distance = ndi.distance_transform_edt(labels)
    local_maxi = peak_local_max(distance,
                                indices=False,  # we want the image mask, not peak position
                                min_distance=10,  # about half of a bud with our size
                                threshold_abs=10,  # allows to clear the noise
                                labels=labels)
    # we fuse the labels that are close together that escaped the min distance in local_maxi
    local_maxi = ndi.convolve(local_maxi, np.ones((5, 5)), mode='constant', cval=0.0)
    # finish the watershed
    expanded_maxi_markers = ndi.label(local_maxi, structure=np.ones((3, 3)))[0]
    segmented_cells_labels = watershed(-distance, expanded_maxi_markers, mask=labels)

    # log debugging data
    running_debug_frame.gfp_collector = gfp_collector
    running_debug_frame.gfp_clustering_markers = gfp_clustering_markers
    running_debug_frame.labels = labels
    running_debug_frame.segmented_cells_labels = segmented_cells_labels

    return gfp_collector, segmented_cells_labels
Example #15
0
def label_nuclei(binary, min_size):
    '''Label, watershed and remove small objects'''

    distance = medial_axis(binary, return_distance=True)[1]

    distance_blured = gaussian_filter(distance, 5)

    local_maxi = peak_local_max(distance_blured, indices=False, labels=binary, min_distance = 30)

    markers = measure_label(local_maxi)

#    markers[~binary] = -1

#    labels_rw = segmentation.random_walker(binary, markers)

#    labels_rw[labels_rw == -1] = 0

#    labels_rw = segmentation.relabel_sequential(labels_rw)

    labels_ws = watershed(-distance, markers, mask=binary)

    labels_large = remove_small_objects(labels_ws,min_size)

    labels_clean_border = clear_border(labels_large)

    labels_from_one = relabel_sequential(labels_clean_border)

#    plt.imshow(ndimage.morphology.binary_dilation(markers))
#    plt.show()

    return labels_from_one[0]
Example #16
0
def local_maximum(data, dist=1):
    """Generate the local maxinum value in image."""
    lmax = np.zeros(data.shape)
    p = skft.peak_local_max(data, dist).T
    p = (np.array(p[0]), np.array(p[1]), np.array(p[2]))
    lmax[p] = 1
    return lmax
Example #17
0
def test_subpix_dot():
    img = np.zeros((50, 50))
    img[25, 25] = 255
    corner = peak_local_max(corner_harris(img),
                            min_distance=10, threshold_rel=0, num_peaks=1)
    subpix = corner_subpix(img, corner)
    assert_array_equal(subpix[0], (25, 25))
Example #18
0
def corner_peaks(image, min_distance=10, threshold_abs=0, threshold_rel=0.1,
                 exclude_border=True, indices=True, num_peaks=np.inf,
                 footprint=None, labels=None):
    """Find corners in corner measure response image.

    This differs from `skimage.feature.peak_local_max` in that it suppresses
    multiple connected peaks with the same accumulator value.

    Parameters
    ----------
    See `skimage.feature.peak_local_max`.

    Returns
    -------
    See `skimage.feature.peak_local_max`.

    Examples
    --------
    >>> from skimage.feature import peak_local_max, corner_peaks
    >>> response = np.zeros((5, 5))
    >>> response[2:4, 2:4] = 1
    >>> response
    array([[ 0.,  0.,  0.,  0.,  0.],
           [ 0.,  0.,  0.,  0.,  0.],
           [ 0.,  0.,  1.,  1.,  0.],
           [ 0.,  0.,  1.,  1.,  0.],
           [ 0.,  0.,  0.,  0.,  0.]])
    >>> peak_local_max(response, exclude_border=False)
    array([[2, 2],
           [2, 3],
           [3, 2],
           [3, 3]])
    >>> corner_peaks(response, exclude_border=False)
    array([[2, 2]])
    >>> corner_peaks(response, exclude_border=False, min_distance=0)
    array([[2, 2],
           [2, 3],
           [3, 2],
           [3, 3]])

    """

    peaks = peak_local_max(image, min_distance=min_distance,
                           threshold_abs=threshold_abs,
                           threshold_rel=threshold_rel,
                           exclude_border=exclude_border,
                           indices=False, num_peaks=num_peaks,
                           footprint=footprint, labels=labels)
    if min_distance > 0:
        coords = np.transpose(peaks.nonzero())
        for r, c in coords:
            if peaks[r, c]:
                peaks[r - min_distance:r + min_distance + 1,
                      c - min_distance:c + min_distance + 1] = False
                peaks[r, c] = True

    if indices is True:
        return np.transpose(peaks.nonzero())
    else:
        return peaks
Example #19
0
def test_subpix():
    img = np.zeros((50, 50))
    img[:25,:25] = 255
    img[25:,25:] = 255
    corner = peak_local_max(corner_harris(img), num_peaks=1)
    subpix = corner_subpix(img, corner)
    assert_array_equal(subpix[0], (24.5, 24.5))
Example #20
0
def stk_to_rois(stk, threshold, min_size, max_window=8, downscale_factor=2):
    thresholded_stk = stk > threshold
    thresholded_stk = remove_small_objects(thresholded_stk, min_size)
    distance = ndi.distance_transform_edt(thresholded_stk)
    cropped_stk = stk.copy()
    cropped_stk[np.logical_not(thresholded_stk)] = 0
    combined_stk = cropped_stk + distance/distance.max()
    local_max = peak_local_max(combined_stk, indices=False, 
                               footprint=np.ones((max_window, max_window)), 
                               labels=thresholded_stk)
    markers = ndi.label(local_max)[0]
    labels = watershed(-combined_stk, markers, mask=thresholded_stk)
    new_markers = markers.copy()
    for i in set(labels.flatten()):
        if i == 0: continue
        if np.sum(labels==i) < min_size:
            new_markers[markers==i] = 0
    labels = watershed(-combined_stk, new_markers, mask=thresholded_stk)
    labels_set = set(labels.flatten())
    rois = []
    for label in labels_set:
        if label == 0: continue
        if np.sum((labels==label).astype(int)) < min_size: continue
        nroi = np.zeros((stk.shape[0], stk.shape[1]))
        cx,cy = np.where(labels==label)
        cx,cy = int(cx.mean()), int(cy.mean())
        x,y = np.ogrid[0:nroi.shape[0], 0:nroi.shape[1]]
        r = 4
        mask =  (cx-x)**2 + (cy-y)**2 <= r*r
        nroi[mask] = 1
        #nroi[labels==label] = 1
        rois.append(zoom(nroi, downscale_factor, order=0))
    rois = np.array(rois)
    return rois, thresholded_stk, labels
Example #21
0
def waterShed(blob, shape):
	img = np.zeros(shape, np.uint16)
	img[zip(*blob)] = 99999

	D = ndimage.distance_transform_edt(img)
	mindist = 7
	labels = [1,2,3,4]
	while len(np.unique(labels)) > 3:
		mindist += 1
		localMax = peak_local_max(D, indices=False, min_distance=mindist, labels=img)

		markers = ndimage.label(localMax, structure=np.ones((3,3)))[0]
		labels = watershed(-D, markers, mask=img)

	subBlobs = []
	for label in np.unique(labels):
		if label == 0:
			continue
		ww = np.where(labels==label)
		bb = zip(ww[0], ww[1])
		subBlobs.append(bb)
	# code.interact(local=locals())
	try:
		return subBlobs, zip(np.where(localMax==True)[0],np.where(localMax==True)[1])[0]
	except IndexError:
		return subBlobs, 0
Example #22
0
def segment(image, thresh):
    #preprocess image
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    
    #perform euclidean distance transform
    distances = ndimage.distance_transform_edt(thresh)
    localMax = peak_local_max(distances, indices = False, min_distance = 3, labels = thresh)

    #perform connected component analysis on local peaks
    markers = ndimage.label(localMax, structure = np.ones((3, 3)))[0]
    labels = watershed(-distances, markers, mask = thresh)

    #loop over labels returned from watershed to mark them
    for label in np.unique(labels):
        if label == 0:
            continue

        mask = np.zeros(gray.shape, dtype="uint8")
        mask[labels == label] = 255

        #find contours in mask and choose biggest contour by area
        contours = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2]
        contour = max(contours, key = cv2.contourArea)

        #draw circle around max size contour
        ((x, y), r) = cv2.minEnclosingCircle(contour)
        cv2.circle(image, (int(x), int(y)), int(r), (0, 255, 0), 2)
    
    #show final image
    cv2.imshow("Output", image)
    return len(np.unique(labels) - 1)
def segmentationize(imageSe):
    """
    Divides coherent forms of an image in smaller groups of type integer.
    """
    
    # create an matrix of distances to the next sourrounding area
    distance = ndimage.distance_transform_edt(imageSe, sampling=3)
    erosed = ndimage.binary_erosion(imageSe, iterations=8).astype(imageSe.dtype)
    distanceE = ndimage.distance_transform_edt(erosed, sampling=3)
    distance += (2 * distanceE)
    labels, num = label(imageSe, background=0, return_num='True')
    sizes_image = ndimage.sum(imageSe, labels, range(num))
    sizes_image = np.sort(sizes_image, axis=None)
    pos = int(0.4 * num)
    areal = int(sizes_image[pos] ** 0.5)
    if areal <= 10:
        areal = 10
    elif (areal % 2) != 0:
        areal += 1
    footer = circarea(areal) # draw circle area
    
    # find the positions of the maxima from the distances
    local_maxi = peak_local_max(distance, indices=False, footprint=footer, labels=imageSe)
    markers = label(local_maxi)
    
    # watershed algorithm starts at the maxima and returns labels of particles
    simplefilter("ignore", FutureWarning)   # avoid warning in watershed method
    labels_ws = watershed(-distance, markers, mask=imageSe)
    simplefilter("default", FutureWarning)
    
    return labels, labels_ws, local_maxi
Example #24
0
    def process(self, im):
        (width, height, _) = im.image.shape

        img_adapted = im.prep(self.transform)

        if width > self.max_resized or height > self.max_resized:
            scale_height = self.max_resized / height
            scale_width = self.max_resized / width
            scale = min(scale_height, scale_width)
            img_adapted = resize(img_adapted, (int(width * scale), int(height * scale)))

        edges = canny(img_adapted, sigma=self.sigma)

        # Detect two radii
        # Calculate image diameter
        shape = im.image.shape
        diam = math.sqrt(shape[0] ** 2 + shape[1] ** 2)
        radii = np.arange(diam / 3, diam * 0.8, 2)
        hough_res = hough_circle(edges, radii)

        accums = []
        for radius, h in zip(radii, hough_res):
            # For each radius, extract two circles
            peaks = peak_local_max(h, num_peaks=1, min_distance=1)
            if len(peaks) > 0:
                accums.extend(h[peaks[:, 0], peaks[:, 1]])

        if len(accums) == 0:  # TODO: fix, should not happen
            return [0]

        idx = np.argmax(accums)
        return [accums[idx]]
Example #25
0
def hugh_circle_detection(image):
	# Load picture and detect edges
	edges = canny(image, sigma=3, low_threshold=10, high_threshold=50)

	fig, ax = plt.subplots(ncols=1, nrows=1, figsize=(5, 2))

	# Detect two radii
	hough_radii = np.arange(15, 30, 2)
	hough_res = hough_circle(edges, hough_radii)

	centers = []
	accums = []
	radii = []

	for radius, h in zip(hough_radii, hough_res):
		# For each radius, extract two circles
		num_peaks = 2
		peaks = peak_local_max(h, num_peaks=num_peaks)
		centers.extend(peaks)
		accums.extend(h[peaks[:, 0], peaks[:, 1]])
		radii.extend([radius] * num_peaks)

	# Draw the most prominent 5 circles
	image = color.gray2rgb(image)
	for idx in np.argsort(accums)[::-1][:5]:
		center_x, center_y = centers[idx]
		radius = radii[idx]
		cx, cy = circle_perimeter(center_y, center_x, radius)
		image[cy, cx] = (220, 20, 20)

	ax.imshow(image, cmap=plt.cm.gray)
	plt.show()
Example #26
0
	def run(self, im, skin_thresh=[-1,1], n_peaks=3):
		'''
		im : color image
		'''
		im_skin = rgb2lab(im.astype(np.int16))[:,:,2]
		self.im_skin = im_skin
		# im_skin = skimage.exposure.equalize_hist(im_skin)
		# im_skin = skimage.exposure.rescale_intensity(im_skin, out_range=[0,1])
		im_skin *= im_skin > skin_thresh[0]
		im_skin *= im_skin < skin_thresh[1]

		skin_match_c = nd.correlate(-im_skin, self.hand_template)
		self.skin_match = skin_match_c

		# Display Predictions - Color Based matching
		optima = peak_local_max(skin_match_c, min_distance=20, num_peaks=n_peaks, exclude_border=False)
		# Visualize
		if len(optima) > 0:
			optima_values = skin_match_c[optima[:,0], optima[:,1]]
			optima_thresh = np.max(optima_values) / 2
			optima = optima.tolist()

			for i,o in enumerate(optima):
				if optima_values[i] < optima_thresh:
					optima.pop(i)
					break
		self.markers = optima

		return self.markers
Example #27
0
	def run(self, im, skin_thresh=[-1,1], n_peaks=3):
		'''
		im : color image
		'''
		im_skin = im
		self.im_skin = im_skin
		skin_match_c = match_template(im_skin, self.template, pad_input=True)*(im>0)
		self.skin_match = skin_match_c
		# cv2.matchTemplate(im_skin, self.template, cv2.cv.CV_TM_SQDIFF_NORMED)
		# imshow(cv2.matchTemplate(im_skin.astype(np.float32), self.template.astype(np.float32), cv2.cv.CV_TM_CCOEFF_NORMED))

		# Display Predictions - Color Based matching
		optima = peak_local_max(skin_match_c, min_distance=20, num_peaks=n_peaks, exclude_border=False)
		# Visualize
		if len(optima) > 0:
			optima_values = skin_match_c[optima[:,0], optima[:,1]]
			optima_thresh = np.max(optima_values) / 2
			optima = optima.tolist()

			for i,o in enumerate(optima):
				if optima_values[i] < optima_thresh:
					optima.pop(i)
					break
		self.markers = optima

		return self.markers
    def blackout_outside(self, img, sigma=3):
        img_g = skic.rgb2gray(img)
        edges = skif.canny(img_g, sigma=sigma)

        hough_radii = np.arange(180, 210, 2)
        hough_res = skit.hough_circle(edges, hough_radii)

        centers = []
        accums = []
        radii = []

        for radius, h in zip(hough_radii, hough_res):
            # For each radius, extract two circles
            num_peaks = 1
            peaks = skif.peak_local_max(h, min_distance=40, num_peaks=num_peaks)
            if peaks != []:
                centers.extend(peaks)
                accums.extend(h[peaks[:, 0], peaks[:, 1]])
                radii.extend([radius] * num_peaks)

#                print radius, np.max(h.ravel()), len(peaks)

        if accums == [] and sigma==3:
            return self.blackout_outside(img, sigma=3)

    #     Draw the most prominent 5 circles
        image = (img.copy() / 4.0).astype(np.uint8)
        cx, cy = skid.circle(*self.average_hough_detections(hough_radii, hough_res))
        image[cy, cx] = img[cy, cx]

        return image
Example #29
0
def black_background(image, kernel):

    shifted = cv2.pyrMeanShiftFiltering(image, 10, 39)
    gray = cv2.cvtColor(shifted, cv2.COLOR_BGR2GRAY)
    thresh = cv2.threshold(gray, 0, 255,
                           cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
    D = ndimage.distance_transform_edt(thresh)
    localMax = peak_local_max(D, indices=False, min_distance=10,
                              labels=thresh)

    # perform a connected component analysis on the local peaks,
    # using 8-connectivity, then appy the Watershed algorithm
    markers = ndimage.label(localMax, structure=np.ones((3, 3)))[0]
    labels = watershed(-D, markers, mask=thresh)
    # create a mask
    mask2 = np.zeros(gray.shape, dtype="uint8")
    #  loop over the unique labels returned by the Watershed  algorithm for
    for label in np.unique(labels):
        # if the label is zero, we are examining the 'background' so simply ignore it
        if label == 0:
            continue
        # otherwise, allocate memory for the label region and draw
        # it on the mask
        mask2[labels == label] = 255
    return mask2
Example #30
0
def find_storms(z):
	thresh_z = 20 #min z value for finding peaks
	min_distance = 5 #minimum distance between peaks
	#find peaks, using local maxima
	peaks = feature.peak_local_max(z, threshold_abs=thresh_z,
				min_distance=min_distance, indices=False)

	#uniquely label each peak
	markers, num_markers = ndimage.label(peaks)

	#use watershed algorithm to split image into basins, starting at markers
	labels = watershed(-z, markers, mask=z>thresh_z/2)

	#compute region properties
	props = measure.regionprops(labels, z)

	props = filter_storms(props)
	
	storms = []
	for p in props:
		s = {}
		s['x'], s['y'] = p.centroid
		s['centroid'] = p.centroid[::-1]
		s['max_intensity'] = p.max_intensity
		s['majlen'] = p.major_axis_length
		s['minlen'] = p.minor_axis_length
		s['angle'] = 180 - np.rad2deg(p.orientation)
		s['area'] = p.area
		storms.append(s)

	return storms
Example #31
0
    def act(self, obs, info):
        """Run inference and return best action given visual observations."""
        del info

        act = {'camera_config': self.camera_config, 'primitive': None}
        if not obs:
            return act

        # Get heightmap from RGB-D images.
        colormap, heightmap = self.get_heightmap(obs, self.camera_config)

        # Concatenate color with depth images.
        input_image = np.concatenate(
            (colormap, heightmap[Ellipsis, None], heightmap[Ellipsis, None],
             heightmap[Ellipsis, None]),
            axis=2)

        # Get top-k pixels from pick and place heatmaps.
        k = 100
        pick_heatmap = self.pick_model.forward(input_image,
                                               apply_softmax=True).squeeze()
        place_heatmap = self.place_model.forward(input_image,
                                                 apply_softmax=True).squeeze()
        descriptors = np.float32(self.match_model.forward(input_image))

        # V4
        pick_heatmap = cv2.GaussianBlur(pick_heatmap, (49, 49), 0)
        place_heatmap = cv2.GaussianBlur(place_heatmap, (49, 49), 0)
        pick_topk = np.int32(
            np.unravel_index(
                np.argsort(pick_heatmap.reshape(-1))[-k:],
                pick_heatmap.shape)).T
        pick_pixel = pick_topk[-1, :]
        from skimage.feature import peak_local_max  # pylint: disable=g-import-not-at-top
        place_peaks = peak_local_max(place_heatmap, num_peaks=1)
        distances = np.ones((place_peaks.shape[0], self.num_rotations)) * 10
        pick_descriptor = descriptors[0, pick_pixel[0],
                                      pick_pixel[1], :].reshape(1, -1)
        for i in range(place_peaks.shape[0]):
            peak = place_peaks[i, :]
            place_descriptors = descriptors[:, peak[0], peak[1], :]
            distances[i, :] = np.linalg.norm(place_descriptors -
                                             pick_descriptor,
                                             axis=1)
        ibest = np.unravel_index(np.argmin(distances), shape=distances.shape)
        p0_pixel = pick_pixel
        p0_theta = 0
        p1_pixel = place_peaks[ibest[0], :]
        p1_theta = ibest[1] * (2 * np.pi / self.num_rotations)

        # # V3
        # pick_heatmap = cv2.GaussianBlur(pick_heatmap, (49, 49), 0)
        # place_heatmap = cv2.GaussianBlur(place_heatmap, (49, 49), 0)
        # pick_topk = np.int32(
        #     np.unravel_index(
        #         np.argsort(pick_heatmap.reshape(-1))[-k:], pick_heatmap.shape)).T
        # place_topk = np.int32(
        #     np.unravel_index(
        #         np.argsort(place_heatmap.reshape(-1))[-k:],
        #         place_heatmap.shape)).T
        # pick_pixel = pick_topk[-1, :]
        # place_pixel = place_topk[-1, :]
        # pick_descriptor = descriptors[0, pick_pixel[0],
        #                               pick_pixel[1], :].reshape(1, -1)
        # place_descriptor = descriptors[:, place_pixel[0], place_pixel[1], :]
        # distances = np.linalg.norm(place_descriptor - pick_descriptor, axis=1)
        # irotation = np.argmin(distances)
        # p0_pixel = pick_pixel
        # p0_theta = 0
        # p1_pixel = place_pixel
        # p1_theta = irotation * (2 * np.pi / self.num_rotations)

        # # V2
        # pick_topk = np.int32(
        #     np.unravel_index(
        #         np.argsort(pick_heatmap.reshape(-1))[-k:], pick_heatmap.shape)).T
        # place_topk = np.int32(
        #     np.unravel_index(
        #         np.argsort(place_heatmap.reshape(-1))[-k:],
        #         place_heatmap.shape)).T
        # pick_pixel = pick_topk[-1, :]
        # pick_descriptor = descriptors[0, pick_pixel[0],
        #                               pick_pixel[1], :].reshape(1, 1, 1, -1)
        # distances = np.linalg.norm(descriptors - pick_descriptor, axis=3)
        # distances = np.transpose(distances, [1, 2, 0])
        # max_distance = int(np.round(np.max(distances)))
        # for i in range(self.num_rotations):
        #   distances[:, :, i] = cv2.circle(distances[:, :, i],
        #                                   (pick_pixel[1], pick_pixel[0]), 50,
        #                                   max_distance, -1)
        # ibest = np.unravel_index(np.argmin(distances), shape=distances.shape)
        # p0_pixel = pick_pixel
        # p0_theta = 0
        # p1_pixel = ibest[:2]
        # p1_theta = ibest[2] * (2 * np.pi / self.num_rotations)

        # # V1
        # pick_topk = np.int32(
        #     np.unravel_index(
        #         np.argsort(pick_heatmap.reshape(-1))[-k:], pick_heatmap.shape)).T
        # place_topk = np.int32(
        #     np.unravel_index(
        #         np.argsort(place_heatmap.reshape(-1))[-k:],
        #         place_heatmap.shape)).T
        # distances = np.zeros((k, k, self.num_rotations))
        # for ipick in range(k):
        #   pick_descriptor = descriptors[0, pick_topk[ipick, 0],
        #                                 pick_topk[ipick, 1], :].reshape(1, -1)
        #   for iplace in range(k):
        #     place_descriptors = descriptors[:, place_topk[iplace, 0],
        #                                     place_topk[iplace, 1], :]
        #     distances[ipick, iplace, :] = np.linalg.norm(
        #         place_descriptors - pick_descriptor, axis=1)
        # ibest = np.unravel_index(np.argmin(distances), shape=distances.shape)
        # p0_pixel = pick_topk[ibest[0], :]
        # p0_theta = 0
        # p1_pixel = place_topk[ibest[1], :]
        # p1_theta = ibest[2] * (2 * np.pi / self.num_rotations)

        # Pixels to end effector poses.
        p0_position = utils.pix_to_xyz(p0_pixel, heightmap, self.bounds,
                                       self.pixel_size)
        p1_position = utils.pix_to_xyz(p1_pixel, heightmap, self.bounds,
                                       self.pixel_size)
        p0_rotation = utils.eulerXYZ_to_quatXYZW((0, 0, -p0_theta))
        p1_rotation = utils.eulerXYZ_to_quatXYZW((0, 0, -p1_theta))

        act['primitive'] = 'pick_place'
        if self.task == 'sweeping':
            act['primitive'] = 'sweep'
        elif self.task == 'pushing':
            act['primitive'] = 'push'
        params = {
            'pose0': (p0_position, p0_rotation),
            'pose1': (p1_position, p1_rotation)
        }
        act['params'] = params
        return act
# make marker array for labelling
markers = np.zeros_like(yellow_channel_greyscalef)
markers[yellow_channel_greyscalef < 1] = 1
markers[yellow_channel_greyscalef > 30] = 2

# nope
elevation_map = sobel(yellow_channel_greyscalef)
ws = watershed(elevation_map, markers)

from skimage.feature import peak_local_max
distance = distance_transform_edt(yellow_channel_greyscalef)

# insanely slow....90p[]\]
local_maxi = peak_local_max(-distance,
                            indices=False,
                            footprint=np.ones(
                                (3, 3)))  #, labels=yellow_channel_greyscalef)

# also doesn't work.....
markers = ndimage.label(local_maxi)[0]
labels = watershed(-distance, markers, mask=image)

# the larger you make sigma, the more blurred it gets
ycf = ndimage.gaussian_filter(yellow_channel_greyscale2, 1)
bin_image = np.zeros_like(ycf)
bin_image[ycf > 12] = 1

# think that will be ok....
labelled = measure.label(bin_image)
labels = skimage.morphology.remove_small_objects(labelled, 30)
xx, yy = np.mgrid[xmin:xmax:dx, ymin:ymax:dy]
positions = np.vstack([xx.ravel(), yy.ravel()])
#kernel = st.gaussian_kde(Y.T, bw_method = 'silverman');
kernel = st.gaussian_kde(Y.T, bw_method=0.25)

Y_xy = kernel(positions)
Y_xy = np.reshape(Y_xy, xx.shape)

fplt.plot_array(Y_xy)

#watershed it
from scipy import ndimage as ndi
from skimage.morphology import watershed
from skimage.feature import peak_local_max

local_maxi = peak_local_max(Y_xy, indices=False, footprint=np.ones((7, 7)))
markers = ndi.label(local_maxi)[0]
labels = watershed(-Y_xy, markers)  #, mask=image)

#classify points

Y_idx = np.array(np.round(
    (Y - [xmin, ymin]) / [xmax - xmin, ymax - ymin] * (npts - 1)),
                 dtype=int)
Y_idx[Y_idx < 0] = 0
Y_idx[Y_idx > npts - 1] = npts - 1
Y_class = labels[Y_idx[:, 0], Y_idx[:, 1]]

cmap = 'jet'
fig = plt.figure(1)
plt.clf()
Example #34
0
def seeds(args):
    """
    %prog seeds [pngfile|jpgfile]

    Extract seed metrics from [pngfile|jpgfile]. Use --rows and --cols to crop image.
    """
    p = OptionParser(seeds.__doc__)
    p.set_outfile()
    opts, args, iopts = add_seeds_options(p, args)

    if len(args) != 1:
        sys.exit(not p.print_help())

    pngfile, = args
    pf = opts.prefix or op.basename(pngfile).rsplit(".", 1)[0]
    sigma, kernel = opts.sigma, opts.kernel
    rows, cols = opts.rows, opts.cols
    labelrows, labelcols = opts.labelrows, opts.labelcols
    ff = opts.filter
    calib = opts.calibrate
    outdir = opts.outdir
    if outdir != '.':
        mkdir(outdir)
    if calib:
        calib = json.load(must_open(calib))
        pixel_cm_ratio, tr = calib["PixelCMratio"], calib["RGBtransform"]
        tr = np.array(tr)

    pngfile = convert_background(pngfile)
    resizefile, mainfile, labelfile, exif = \
                      convert_image(pngfile, pf, outdir=outdir,
                                    rotate=opts.rotate,
                                    rows=rows, cols=cols,
                                    labelrows=labelrows, labelcols=labelcols)

    oimg = load_image(resizefile)
    img = load_image(mainfile)

    fig, (ax1, ax2, ax3, ax4) = plt.subplots(ncols=4,
                                             nrows=1,
                                             figsize=(iopts.w, iopts.h))
    # Edge detection
    img_gray = rgb2gray(img)
    logging.debug("Running {0} edge detection ...".format(ff))
    if ff == "canny":
        edges = canny(img_gray, sigma=opts.sigma)
    elif ff == "roberts":
        edges = roberts(img_gray)
    elif ff == "sobel":
        edges = sobel(img_gray)
    edges = clear_border(edges, buffer_size=opts.border)
    selem = disk(kernel)
    closed = closing(edges, selem) if kernel else edges
    filled = binary_fill_holes(closed)

    # Watershed algorithm
    if opts.watershed:
        distance = distance_transform_edt(filled)
        local_maxi = peak_local_max(distance, threshold_rel=.05, indices=False)
        coordinates = peak_local_max(distance, threshold_rel=.05)
        markers, nmarkers = label(local_maxi, return_num=True)
        logging.debug("Identified {0} watershed markers".format(nmarkers))
        labels = watershed(closed, markers, mask=filled)
    else:
        labels = label(filled)

    # Object size filtering
    w, h = img_gray.shape
    canvas_size = w * h
    min_size = int(round(canvas_size * opts.minsize / 100))
    max_size = int(round(canvas_size * opts.maxsize / 100))
    logging.debug("Find objects with pixels between {0} ({1}%) and {2} ({3}%)"\
                    .format(min_size, opts.minsize, max_size, opts.maxsize))

    # Plotting
    ax1.set_title('Original picture')
    ax1.imshow(oimg)

    params = "{0}, $\sigma$={1}, $k$={2}".format(ff, sigma, kernel)
    if opts.watershed:
        params += ", watershed"
    ax2.set_title('Edge detection\n({0})'.format(params))
    closed = gray2rgb(closed)
    ax2_img = labels
    if opts.edges:
        ax2_img = closed
    elif opts.watershed:
        ax2.plot(coordinates[:, 1], coordinates[:, 0], 'g.')
    ax2.imshow(ax2_img, cmap=iopts.cmap)

    ax3.set_title('Object detection')
    ax3.imshow(img)

    filename = op.basename(pngfile)
    if labelfile:
        accession = extract_label(labelfile)
    else:
        accession = pf

    # Calculate region properties
    rp = regionprops(labels)
    rp = [x for x in rp if min_size <= x.area <= max_size]
    nb_labels = len(rp)
    logging.debug("A total of {0} objects identified.".format(nb_labels))
    objects = []
    for i, props in enumerate(rp):
        i += 1
        if i > opts.count:
            break

        y0, x0 = props.centroid
        orientation = props.orientation
        major, minor = props.major_axis_length, props.minor_axis_length
        major_dx = cos(orientation) * major / 2
        major_dy = sin(orientation) * major / 2
        minor_dx = sin(orientation) * minor / 2
        minor_dy = cos(orientation) * minor / 2
        ax2.plot((x0 - major_dx, x0 + major_dx),
                 (y0 + major_dy, y0 - major_dy), 'r-')
        ax2.plot((x0 - minor_dx, x0 + minor_dx),
                 (y0 - minor_dy, y0 + minor_dy), 'r-')

        npixels = int(props.area)
        # Sample the center of the blob for color
        d = min(int(round(minor / 2 * .35)) + 1, 50)
        x0d, y0d = int(round(x0)), int(round(y0))
        square = img[(y0d - d):(y0d + d), (x0d - d):(x0d + d)]
        pixels = []
        for row in square:
            pixels.extend(row)
        logging.debug("Seed #{0}: {1} pixels ({2} sampled) - {3:.2f}%".\
                        format(i, npixels, len(pixels), 100. * npixels / canvas_size))

        rgb = pixel_stats(pixels)
        objects.append(Seed(filename, accession, i, rgb, props, exif))
        minr, minc, maxr, maxc = props.bbox
        rect = Rectangle((minc, minr),
                         maxc - minc,
                         maxr - minr,
                         fill=False,
                         ec='w',
                         lw=1)
        ax3.add_patch(rect)
        mc, mr = (minc + maxc) / 2, (minr + maxr) / 2
        ax3.text(mc,
                 mr,
                 "{0}".format(i),
                 color='w',
                 ha="center",
                 va="center",
                 size=6)

    for ax in (ax2, ax3):
        ax.set_xlim(0, h)
        ax.set_ylim(w, 0)

    # Output identified seed stats
    ax4.text(.1, .92, "File: {0}".format(latex(filename)), color='g')
    ax4.text(.1, .86, "Label: {0}".format(latex(accession)), color='m')
    yy = .8
    fw = must_open(opts.outfile, "w")
    if not opts.noheader:
        print(Seed.header(calibrate=calib), file=fw)
    for o in objects:
        if calib:
            o.calibrate(pixel_cm_ratio, tr)
        print(o, file=fw)
        i = o.seedno
        if i > 7:
            continue
        ax4.text(.01, yy, str(i), va="center", bbox=dict(fc='none', ec='k'))
        ax4.text(.1, yy, o.pixeltag, va="center")
        yy -= .04
        ax4.add_patch(
            Rectangle((.1, yy - .025), .12, .05, lw=0, fc=rgb_to_hex(o.rgb)))
        ax4.text(.27, yy, o.hashtag, va="center")
        yy -= .06
    ax4.text(.1,
             yy,
             "(A total of {0} objects displayed)".format(nb_labels),
             color="darkslategray")
    normalize_axes(ax4)

    for ax in (ax1, ax2, ax3):
        xticklabels = [int(x) for x in ax.get_xticks()]
        yticklabels = [int(x) for x in ax.get_yticks()]
        ax.set_xticklabels(xticklabels, family='Helvetica', size=8)
        ax.set_yticklabels(yticklabels, family='Helvetica', size=8)

    image_name = op.join(outdir, pf + "." + iopts.format)
    savefig(image_name, dpi=iopts.dpi, iopts=iopts)
    return objects
def __proposal_old(img_preprocessed, min_dim, max_dim):
    """
    This algorithm depends on Hough circle detection using skii-image
    Which turned out to be crap
    :param img_preprocessed:
    :param min_dim:
    :param max_dim:
    :return:
    """

    img = img_preprocessed
    img_edge = canny(img * 255, sigma=3, low_threshold=10, high_threshold=50)

    centers = []
    accums = []
    radii = []
    regions = []

    # detect all radii within the range
    min_radius = int(min_dim / 2)
    max_radius = int(max_dim / 2)
    hough_radii = np.arange(start=min_radius, stop=max_radius, step=1)
    hough_res = hough_circle(img_edge, hough_radii)

    for radius, h in zip(hough_radii, hough_res):
        # for each radius, extract 2 circles
        num_peaks = 2
        peaks = peak_local_max(h, num_peaks=num_peaks)
        centers.extend(peaks)
        accums.extend(h[peaks[:, 0], peaks[:, 1]])
        radii.extend([radius] * num_peaks)

    # don't consider circles with accum value less than the threshold
    idx_sorted = np.argsort(accums)[::-1]
    accum_threshold = 0.3
    for idx in idx_sorted:
        idx = int(idx)
        if accums[idx] < accum_threshold:
            continue
        center_y, center_x = centers[idx]
        radius = radii[idx]
        x1 = center_x - radius
        y1 = center_y - radius
        x2 = center_x + radius
        y2 = center_y + radius

        # we don't want to collect circles, but we want to collect regions
        # later on, we'll suppress these regions
        regions.append([x1, y1, x2, y2])

    # suppress the regions to extract the strongest ones
    if len(regions) > 0:
        min_overlap = 3
        overlap_thresh = 0.7
        regions_weak, regions_strong = CNN.nms.suppression(
            boxes=regions,
            overlap_thresh=overlap_thresh,
            min_overlap=min_overlap)

        # create binary map using only the strong regions
        img_shape = img_preprocessed.shape
        map = np.zeros(shape=(img_shape[0], img_shape[1]), dtype=bool)
        for r in regions_strong:
            map[r[1]:r[3], r[0]:r[2]] = True
    else:
        regions_weak = []
        regions_strong = []
        map = []

    return regions_weak, regions_strong, map
Example #36
0
def extractWells(imagename): 
    im = skimage.io.imread(imagename)
    edges = feature.canny(im)
    hough_radii = np.arange(130,131,2)
    hough_res = hough_circle(edges, hough_radii)
    peaks = peak_local_max(hough_res[0], num_peaks=30)#num_peaks gives the number of potential locations for wells; can be increased if oo few are found and decreased if wells are found in the wrong location
    plt.imshow(im, cmap=plt.cm.gray)
    outimages = []
    outPoints = []
    for [point, idx] in zip(peaks, range(len(peaks))):
        for pointTmp in peaks[:idx]: 
            if (abs(point[0]-pointTmp[0]) < 200) and (abs(point[1]-pointTmp[1]) < 200): 
                break
        else: 
            plt.scatter(point[1], point[0])
            plt.scatter(point[1]-130, point[0]-130, c='r', marker='+')
            plt.scatter(point[1]-130, point[0]+130, c='r', marker='+')
            plt.scatter(point[1]+130, point[0]-130, c='r', marker='+')
            plt.scatter(point[1]+130, point[0]+130, c='r', marker='+')
            
            plt.scatter(point[1]+130, point[0], c='r', marker='+')
            plt.scatter(point[1]-130, point[0], c='r', marker='+')
            plt.scatter(point[1], point[0]-130, c='r', marker='+')
            plt.scatter(point[1], point[0]+130, c='r', marker='+')
            outPoints.append(point)
            #outimages.append(im[point[0]-130:point[0]+130, point[1]-130:point[1]+130]) 
    # Get Points with smalles x
    outPoints = sorted(outPoints, key=lambda x:x[1])
    columns = []
    for idx in xrange(6): 
        columns.append(sorted(outPoints[idx*4:(idx+1)*4], key=lambda x:x[0]))
    imagedir = os.path.dirname(imagename)
    imageid = int(os.path.splitext(os.path.basename(imagename))[0])
    with open('%s/debug/%03d.csv'%(imagedir, imageid), 'w') as outfile: 
        for [point, idx] in zip(columns[0], range(4)): 
            plt.annotate("0_%d" % (idx), (point[1], point[0]))
            #plt.scatter(point[1], point[0], c='r') 
            outfile.write("0_%d: %d %d\n" % (idx, point[1], point[0]))
            #skimage.io.imsave('%s/0_%d/%03d.png'%(imagedir, idx, imageid), im[point[0]-130:point[0]+130, point[1]-130:point[1]+130])
        
        for [point, idx] in zip(columns[1], range(4)): 
            plt.annotate("1_%d" % (idx), (point[1], point[0]))
            #plt.scatter(point[1], point[0], c='y')
            outfile.write("1_%d: %d %d\n" % (idx, point[1], point[0]))
            #skimage.io.imsave('%s/1_%d/%03d.png'%(imagedir, idx, imageid), im[point[0]-130:point[0]+130, point[1]-130:point[1]+130])
        
        for [point, idx] in zip(columns[2], range(4)): 
            plt.annotate("2_%d" % (idx), (point[1], point[0]))
            #plt.scatter(point[1], point[0], c='g')
            outfile.write("2_%d: %d %d\n" % (idx, point[1], point[0]))
            #skimage.io.imsave('%s/2_%d/%03d.png'%(imagedir, idx, imageid), im[point[0]-130:point[0]+130, point[1]-130:point[1]+130])
        
        for [point, idx] in zip(columns[3], range(4)): 
            plt.annotate("3_%d" % (idx), (point[1], point[0]))
            #plt.scatter(point[1], point[0], c='r', marker='x')
            outfile.write("3_%d: %d %d\n" % (idx, point[1], point[0]))
            #skimage.io.imsave('%s/3_%d/%03d.png'%(imagedir, idx, imageid), im[point[0]-130:point[0]+130, point[1]-130:point[1]+130])
        
        for [point, idx] in zip(columns[4], range(4)): 
            plt.annotate("4_%d" % (idx), (point[1], point[0]))
            #plt.scatter(point[1], point[0], c='y', marker='x')
            outfile.write("4_%d: %d %d\n" % (idx, point[1], point[0]))
            #skimage.io.imsave('%s/4_%d/%03d.png'%(imagedir, idx, imageid), im[point[0]-130:point[0]+130, point[1]-130:point[1]+130])
        
        for [point, idx] in zip(columns[5], range(4)): 
            plt.annotate("5_%d" % (idx), (point[1], point[0]))
            #plt.scatter(point[1], point[0], c='g', marker='x')
            outfile.write("5_%d: %d %d\n" % (idx, point[1], point[0]))
            #skimage.io.imsave('%s/5_%d/%03d.png'%(imagedir, idx, imageid), im[point[0]-130:point[0]+130, point[1]-130:point[1]+130])
            
    
    
    plt.savefig('%s/debug/%03d.png'%(imagedir, imageid))
    
    return columns
#####################################################################
# dividing nuclei in this sample.

#####################################################################
# Segment nuclei
# ==============
# To separate overlapping nuclei, we resort to
# :ref:`sphx_glr_auto_examples_segmentation_plot_watershed.py`.
# To visualize the segmentation conveniently, we colour-code the labelled
# regions using the `color.label2rgb` function, specifying the background
# label with argument `bg_label=0`.

distance = ndi.distance_transform_edt(cells)

local_maxi = feature.peak_local_max(distance, indices=False, min_distance=7)

markers = measure.label(local_maxi)

segmented_cells = segmentation.watershed(-distance, markers, mask=cells)

fig, ax = plt.subplots(ncols=2, figsize=(10, 5))
ax[0].imshow(cells, cmap='gray')
ax[0].set_title('Overlapping nuclei')
ax[0].axis('off')
ax[1].imshow(color.label2rgb(segmented_cells, bg_label=0))
ax[1].set_title('Segmented nuclei')
ax[1].axis('off')
plt.show()

#####################################################################
Example #38
0
# load the image and perform pyramid mean shift filtering
# to aid the thresholding step
shifted = cv2.pyrMeanShiftFiltering(image, 21, 51)
cv2.imshow("Shifted", shifted)

# convert the mean shift image to grayscale, then apply
# Otsu's thresholding
gray = cv2.cvtColor(shifted, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
cv2.imshow("Threshold Image", thresh)

# compute the exact Euclidean distance from every binary
# pixel to the nearest zero pixel, then find peaks in this
# distance map
D = ndimage.distance_transform_edt(thresh)
localMax = peak_local_max(D, indices=False, min_distance=20, labels=thresh)

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

# loop over the unique labels returned by the Watershed
# algorithm
for label in np.unique(labels):
    # if the label is zero, we are examining the 'background'
    # so simply ignore it
    if label == 0:
        continue
Example #39
0
    async def controller(self, cancel_id, executor, job_is_cancelled, send_results):

        stddev_udf = StdDevUDF()
        roi = self.get_sd_roi()

        result_iter = UDFRunner([stddev_udf]).run_for_dataset_async(
            self.dataset, executor, roi=roi, cancel_id=cancel_id
        )
        async for (sd_udf_results,) in result_iter:
            pass
        if job_is_cancelled():
            raise JobCancelledError()

        sd_udf_results = consolidate_result(sd_udf_results)

        center = (self.parameters["cy"], self.parameters["cx"])
        rad_in = self.parameters["ri"]
        rad_out = self.parameters["ro"]
        n_peaks = self.parameters["n_peaks"]
        min_dist = self.parameters["min_dist"]
        sstd = sd_udf_results['std']
        sshape = sstd.shape
        if not (center is None or rad_in is None or rad_out is None):
            mask_out = 1*_make_circular_mask(center[1], center[0], sshape[1], sshape[0], rad_out)
            mask_in = 1*_make_circular_mask(center[1], center[0], sshape[1], sshape[0], rad_in)
            mask = mask_out - mask_in
            masked_sstd = sstd*mask
        else:
            masked_sstd = sstd

        coordinates = peak_local_max(masked_sstd, num_peaks=n_peaks, min_distance=min_dist)

        y = coordinates[..., 0]
        x = coordinates[..., 1]
        z = range(len(y))

        mask = sparse.COO(
            shape=(len(y), ) + tuple(self.dataset.shape.sig),
            coords=(z, y, x), data=1
        )

        udf = ApplyMasksUDF(
            mask_factories=lambda: mask, mask_count=len(y), mask_dtype=np.uint8,
            use_sparse=True
        )

        result_iter = UDFRunner([udf]).run_for_dataset_async(
            self.dataset, executor, cancel_id=cancel_id
        )
        async for (udf_results,) in result_iter:
            pass

        if job_is_cancelled():
            raise JobCancelledError()

        results = await run_blocking(
            self.get_udf_results,
            udf_results=udf_results,
            roi=roi,
        )
        await send_results(results, True)
Example #40
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 l, vdf in zip(np.arange(1, np.max(labels) + 1), vdf_sep):
            mask_l = np.zeros_like(labels).astype("bool")
            mask_l[np.where(labels == l)] = 1
            seps_img_sum += vdf_temp * mask_l / np.max(
                vdf_temp[np.where(labels == l)])
            seps_img_sum[np.where(labels == l)] += l

        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 #41
0
def blob_log(image, min_sigma=1, max_sigma=50, num_sigma=10, thresholds=[.2],
             overlap=.5, log_scale=False, *, exclude_border=False):
    r"""Finds blobs in the given grayscale image.

    Blobs are found using the Laplacian of Gaussian (LoG) method [1]_.
    For each blob found, the method returns its coordinates and the standard
    deviation of the Gaussian kernel that detected the blob.

    Parameters
    ----------
    image : 2D or 3D ndarray
        Input grayscale image, blobs are assumed to be light on dark
        background (white on black).
    min_sigma : scalar or sequence of scalars, optional
        the minimum standard deviation for Gaussian kernel. Keep this low to
        detect smaller blobs. The standard deviations of the Gaussian filter
        are given for each axis as a sequence, or as a single number, in
        which case it is equal for all axes.
    max_sigma : scalar or sequence of scalars, optional
        The maximum standard deviation for Gaussian kernel. Keep this high to
        detect larger blobs. The standard deviations of the Gaussian filter
        are given for each axis as a sequence, or as a single number, in
        which case it is equal for all axes.
    num_sigma : int, optional
        The number of intermediate values of standard deviations to consider
        between `min_sigma` and `max_sigma`.
    threshold : float, optional.
        The absolute lower bound for scale space maxima. Local maxima smaller
        than thresh are ignored. Reduce this to detect blobs with less
        intensities.
    overlap : float, optional
        A value between 0 and 1. If the area of two blobs overlaps by a
        fraction greater than `threshold`, the smaller blob is eliminated.
    log_scale : bool, optional
        If set intermediate values of standard deviations are interpolated
        using a logarithmic scale to the base `10`. If not, linear
        interpolation is used.
    exclude_border : int or bool, optional
        If nonzero int, `exclude_border` excludes blobs from
        within `exclude_border`-pixels of the border of the image.

    Returns
    -------
    A : (n, image.ndim + sigma) ndarray
        A 2d array with each row representing 2 coordinate values for a 2D
        image, and 3 coordinate values for a 3D image, plus the sigma(s) used.
        When a single sigma is passed, outputs are:
        ``(r, c, sigma)`` or ``(p, r, c, sigma)`` where ``(r, c)`` or
        ``(p, r, c)`` are coordinates of the blob and ``sigma`` is the standard
        deviation of the Gaussian kernel which detected the blob. When an
        anisotropic gaussian is used (sigmas per dimension), the detected sigma
        is returned for each dimension.

    References
    ----------
    .. [1] https://en.wikipedia.org/wiki/Blob_detection#The_Laplacian_of_Gaussian

    Examples
    --------
    >>> from skimage import data, feature, exposure
    >>> img = data.coins()
    >>> img = exposure.equalize_hist(img)  # improves detection
    >>> feature.blob_log(img, threshold = .3)
    array([[ 266.        ,  115.        ,   11.88888889],
           [ 263.        ,  302.        ,   17.33333333],
           [ 263.        ,  244.        ,   17.33333333],
           [ 260.        ,  174.        ,   17.33333333],
           [ 198.        ,  155.        ,   11.88888889],
           [ 198.        ,  103.        ,   11.88888889],
           [ 197.        ,   44.        ,   11.88888889],
           [ 194.        ,  276.        ,   17.33333333],
           [ 194.        ,  213.        ,   17.33333333],
           [ 185.        ,  344.        ,   17.33333333],
           [ 128.        ,  154.        ,   11.88888889],
           [ 127.        ,  102.        ,   11.88888889],
           [ 126.        ,  208.        ,   11.88888889],
           [ 126.        ,   46.        ,   11.88888889],
           [ 124.        ,  336.        ,   11.88888889],
           [ 121.        ,  272.        ,   17.33333333],
           [ 113.        ,  323.        ,    1.        ]])

    Notes
    -----
    The radius of each blob is approximately :math:`\sqrt{2}\sigma` for
    a 2-D image and :math:`\sqrt{3}\sigma` for a 3-D image.
    """
    image = img_as_float(image)

    # if both min and max sigma are scalar, function returns only one sigma
    scalar_sigma = (
        True if np.isscalar(max_sigma) and np.isscalar(min_sigma) else False
    )

    # Gaussian filter requires that sequence-type sigmas have same
    # dimensionality as image. This broadcasts scalar kernels
    if np.isscalar(max_sigma):
        max_sigma = np.full(image.ndim, max_sigma, dtype=float)
    if np.isscalar(min_sigma):
        min_sigma = np.full(image.ndim, min_sigma, dtype=float)

    # Convert sequence types to array
    min_sigma = np.asarray(min_sigma, dtype=float)
    max_sigma = np.asarray(max_sigma, dtype=float)

    if log_scale:
        start, stop = np.log10(min_sigma)[:, None], np.log10(max_sigma)[:, None]
        space = np.concatenate(
            [start, stop, np.full_like(start, num_sigma)], axis=1)
        sigma_list = np.stack([np.logspace(*s) for s in space], axis=1)
    else:
        scale = np.linspace(0, 1, num_sigma)[:, None]
        sigma_list = scale * (max_sigma - min_sigma) + min_sigma

    import time
    start = time.time()
    # computing gaussian laplace
    # average s**2 provides scale invariance
    gl_images = [-gaussian_laplace(image, s) * s ** 2
                 for s in np.mean(sigma_list, axis=1)]

    image_cube = np.stack(gl_images, axis=-1)
    print("LoG filter took {}s".format(round(time.time() - start, 2)))
    ret = list()
    times = list()
    for threshold in thresholds:
        start = time.time()
        local_maxima = peak_local_max(image_cube, threshold_abs=threshold,
                                  footprint=np.ones((3,) * (image.ndim + 1)),
                                  threshold_rel=0.0,
                                  exclude_border=exclude_border)

        # Catch no peaks
        if local_maxima.size == 0:
            ret.append(np.empty((0, 4)))
            continue

        # Convert local_maxima to float64
        lm = local_maxima.astype(np.float64)

        # translate final column of lm, which contains the index of the
        # sigma that produced the maximum intensity value, into the sigma
        sigmas_of_peaks = sigma_list[local_maxima[:, -1]]

        if scalar_sigma:
            # select one sigma column, keeping dimension
            sigmas_of_peaks = sigmas_of_peaks[:, 0:1]

        # Remove sigma index and replace with sigmas
        lm = np.hstack([lm[:, :-1], sigmas_of_peaks])

        ret.append(_prune_blobs(lm, overlap))
        times.append(time.time() - start)
    print("Thresholds took on avg: {}s".format(round(np.average(np.array(times)),2)))
    return np.asarray(ret)


# def blob_doh(image, min_sigma=1, max_sigma=30, num_sigma=10, threshold=0.01,
#              overlap=.5, log_scale=False):
#     """Finds blobs in the given grayscale image.

#     Blobs are found using the Determinant of Hessian method [1]_. For each blob
#     found, the method returns its coordinates and the standard deviation
#     of the Gaussian Kernel used for the Hessian matrix whose determinant
#     detected the blob. Determinant of Hessians is approximated using [2]_.

#     Parameters
#     ----------
#     image : 2D ndarray
#         Input grayscale image.Blobs can either be light on dark or vice versa.
#     min_sigma : float, optional
#         The minimum standard deviation for Gaussian Kernel used to compute
#         Hessian matrix. Keep this low to detect smaller blobs.
#     max_sigma : float, optional
#         The maximum standard deviation for Gaussian Kernel used to compute
#         Hessian matrix. Keep this high to detect larger blobs.
#     num_sigma : int, optional
#         The number of intermediate values of standard deviations to consider
#         between `min_sigma` and `max_sigma`.
#     threshold : float, optional.
#         The absolute lower bound for scale space maxima. Local maxima smaller
#         than thresh are ignored. Reduce this to detect less prominent blobs.
#     overlap : float, optional
#         A value between 0 and 1. If the area of two blobs overlaps by a
#         fraction greater than `threshold`, the smaller blob is eliminated.
#     log_scale : bool, optional
#         If set intermediate values of standard deviations are interpolated
#         using a logarithmic scale to the base `10`. If not, linear
#         interpolation is used.

#     Returns
#     -------
#     A : (n, 3) ndarray
#         A 2d array with each row representing 3 values, ``(y,x,sigma)``
#         where ``(y,x)`` are coordinates of the blob and ``sigma`` is the
#         standard deviation of the Gaussian kernel of the Hessian Matrix whose
#         determinant detected the blob.

#     References
#     ----------
#     .. [1] https://en.wikipedia.org/wiki/Blob_detection#The_determinant_of_the_Hessian

#     .. [2] Herbert Bay, Andreas Ess, Tinne Tuytelaars, Luc Van Gool,
#            "SURF: Speeded Up Robust Features"
#            ftp://ftp.vision.ee.ethz.ch/publications/articles/eth_biwi_00517.pdf

#     Examples
#     --------
#     >>> from skimage import data, feature
#     >>> img = data.coins()
#     >>> feature.blob_doh(img)
#     array([[ 270.        ,  363.        ,   30.        ],
#            [ 265.        ,  113.        ,   23.55555556],
#            [ 262.        ,  243.        ,   23.55555556],
#            [ 260.        ,  173.        ,   30.        ],
#            [ 197.        ,  153.        ,   20.33333333],
#            [ 197.        ,   44.        ,   20.33333333],
#            [ 195.        ,  100.        ,   23.55555556],
#            [ 193.        ,  275.        ,   23.55555556],
#            [ 192.        ,  212.        ,   23.55555556],
#            [ 185.        ,  348.        ,   30.        ],
#            [ 156.        ,  302.        ,   30.        ],
#            [ 126.        ,  153.        ,   20.33333333],
#            [ 126.        ,  101.        ,   20.33333333],
#            [ 124.        ,  336.        ,   20.33333333],
#            [ 123.        ,  205.        ,   20.33333333],
#            [ 123.        ,   44.        ,   23.55555556],
#            [ 121.        ,  271.        ,   30.        ]])

#     Notes
#     -----
#     The radius of each blob is approximately `sigma`.
#     Computation of Determinant of Hessians is independent of the standard
#     deviation. Therefore detecting larger blobs won't take more time. In
#     methods line :py:meth:`blob_dog` and :py:meth:`blob_log` the computation
#     of Gaussians for larger `sigma` takes more time. The downside is that
#     this method can't be used for detecting blobs of radius less than `3px`
#     due to the box filters used in the approximation of Hessian Determinant.
#     """
#     assert_nD(image, 2)

#     image = img_as_float(image)
#     image = integral_image(image)

#     if log_scale:
#         start, stop = log(min_sigma, 10), log(max_sigma, 10)
#         sigma_list = np.logspace(start, stop, num_sigma)
#     else:
#         sigma_list = np.linspace(min_sigma, max_sigma, num_sigma)

#     hessian_images = [_hessian_matrix_det(image, s) for s in sigma_list]
#     image_cube = np.dstack(hessian_images)

#     local_maxima = peak_local_max(image_cube, threshold_abs=threshold,
#                                   footprint=np.ones((3,) * image_cube.ndim),
#                                   threshold_rel=0.0,
#                                   exclude_border=False)

#     # Catch no peaks
#     if local_maxima.size == 0:
#         return np.empty((0, 3))
#     # Convert local_maxima to float64
#     lm = local_maxima.astype(np.float64)
#     # Convert the last index to its corresponding scale value
#     lm[:, -1] = sigma_list[local_maxima[:, -1]]
#     return _prune_blobs(lm, overlap)
Example #42
0
def blob_dog(image, min_sigma=1, max_sigma=50, sigma_ratio=1.6, threshold=2.0,
             overlap=.5, *, exclude_border=False):
    r"""Finds blobs in the given grayscale image.

    Blobs are found using the Difference of Gaussian (DoG) method [1]_.
    For each blob found, the method returns its coordinates and the standard
    deviation of the Gaussian kernel that detected the blob.

    Parameters
    ----------
    image : 2D or 3D ndarray
        Input grayscale image, blobs are assumed to be light on dark
        background (white on black).
    min_sigma : scalar or sequence of scalars, optional
        The minimum standard deviation for Gaussian kernel. Keep this low to
        detect smaller blobs. The standard deviations of the Gaussian filter
        are given for each axis as a sequence, or as a single number, in
        which case it is equal for all axes.
    max_sigma : scalar or sequence of scalars, optional
        The maximum standard deviation for Gaussian kernel. Keep this high to
        detect larger blobs. The standard deviations of the Gaussian filter
        are given for each axis as a sequence, or as a single number, in
        which case it is equal for all axes.
    sigma_ratio : float, optional
        The ratio between the standard deviation of Gaussian Kernels used for
        computing the Difference of Gaussians
    threshold : float, optional.
        The absolute lower bound for scale space maxima. Local maxima smaller
        than thresh are ignored. Reduce this to detect blobs with less
        intensities.
    overlap : float, optional
        A value between 0 and 1. If the area of two blobs overlaps by a
        fraction greater than `threshold`, the smaller blob is eliminated.
    exclude_border : int or bool, optional
        If nonzero int, `exclude_border` excludes blobs from
        within `exclude_border`-pixels of the border of the image.

    Returns
    -------
    A : (n, image.ndim + sigma) ndarray
        A 2d array with each row representing 2 coordinate values for a 2D
        image, and 3 coordinate values for a 3D image, plus the sigma(s) used.
        When a single sigma is passed, outputs are:
        ``(r, c, sigma)`` or ``(p, r, c, sigma)`` where ``(r, c)`` or
        ``(p, r, c)`` are coordinates of the blob and ``sigma`` is the standard
        deviation of the Gaussian kernel which detected the blob. When an
        anisotropic gaussian is used (sigmas per dimension), the detected sigma
        is returned for each dimension.

    References
    ----------
    .. [1] https://en.wikipedia.org/wiki/Blob_detection#The_difference_of_Gaussians_approach

    Examples
    --------
    >>> from skimage import data, feature
    >>> feature.blob_dog(data.coins(), threshold=.5, max_sigma=40)
    array([[ 267.      ,  359.      ,   16.777216],
           [ 267.      ,  115.      ,   10.48576 ],
           [ 263.      ,  302.      ,   16.777216],
           [ 263.      ,  245.      ,   16.777216],
           [ 261.      ,  173.      ,   16.777216],
           [ 260.      ,   46.      ,   16.777216],
           [ 198.      ,  155.      ,   10.48576 ],
           [ 196.      ,   43.      ,   10.48576 ],
           [ 195.      ,  102.      ,   16.777216],
           [ 194.      ,  277.      ,   16.777216],
           [ 193.      ,  213.      ,   16.777216],
           [ 185.      ,  347.      ,   16.777216],
           [ 128.      ,  154.      ,   10.48576 ],
           [ 127.      ,  102.      ,   10.48576 ],
           [ 125.      ,  208.      ,   10.48576 ],
           [ 125.      ,   45.      ,   16.777216],
           [ 124.      ,  337.      ,   10.48576 ],
           [ 120.      ,  272.      ,   16.777216],
           [  58.      ,  100.      ,   10.48576 ],
           [  54.      ,  276.      ,   10.48576 ],
           [  54.      ,   42.      ,   16.777216],
           [  52.      ,  216.      ,   16.777216],
           [  52.      ,  155.      ,   16.777216],
           [  45.      ,  336.      ,   16.777216]])

    Notes
    -----
    The radius of each blob is approximately :math:`\sqrt{2}\sigma` for
    a 2-D image and :math:`\sqrt{3}\sigma` for a 3-D image.
    """
    image = img_as_float(image)

    # if both min and max sigma are scalar, function returns only one sigma
    scalar_sigma = np.isscalar(max_sigma) and np.isscalar(min_sigma)

    # Gaussian filter requires that sequence-type sigmas have same
    # dimensionality as image. This broadcasts scalar kernels
    if np.isscalar(max_sigma):
        max_sigma = np.full(image.ndim, max_sigma, dtype=float)
    if np.isscalar(min_sigma):
        min_sigma = np.full(image.ndim, min_sigma, dtype=float)

    # Convert sequence types to array
    min_sigma = np.asarray(min_sigma, dtype=float)
    max_sigma = np.asarray(max_sigma, dtype=float)

    # k such that min_sigma*(sigma_ratio**k) > max_sigma
    k = int(np.mean(np.log(max_sigma / min_sigma) / np.log(sigma_ratio) + 1))

    # a geometric progression of standard deviations for gaussian kernels
    sigma_list = np.array([min_sigma * (sigma_ratio ** i)
                           for i in range(k + 1)])

    gaussian_images = [gaussian_filter(image, s) for s in sigma_list]

    # computing difference between two successive Gaussian blurred images
    # multiplying with average standard deviation provides scale invariance
    dog_images = [(gaussian_images[i] - gaussian_images[i + 1])
                  * np.mean(sigma_list[i]) for i in range(k)]

    image_cube = np.stack(dog_images, axis=-1)

    # local_maxima = get_local_maxima(image_cube, threshold)
    local_maxima = peak_local_max(image_cube, threshold_abs=threshold,
                                  footprint=np.ones((3,) * (image.ndim + 1)),
                                  threshold_rel=0.0,
                                  exclude_border=exclude_border)
    # Catch no peaks
    if local_maxima.size == 0:
        return np.empty((0, 3))

    # Convert local_maxima to float64
    lm = local_maxima.astype(np.float64)

    # translate final column of lm, which contains the index of the
    # sigma that produced the maximum intensity value, into the sigma
    sigmas_of_peaks = sigma_list[local_maxima[:, -1]]

    if scalar_sigma:
        # select one sigma column, keeping dimension
        sigmas_of_peaks = sigmas_of_peaks[:, 0:1]

    # Remove sigma index and replace with sigmas
    lm = np.hstack([lm[:, :-1], sigmas_of_peaks])

    return _prune_blobs(lm, overlap)
Example #43
0
b, g, r = cv2.split(data_array)

# Sauvola

binary_global = canny(r)

fill_masks = ndi.binary_fill_holes(binary_global)
cells_cleaned = morphology.remove_small_objects(fill_masks, 70)
labeled_cells, num = ndi.label(cells_cleaned)

print("Number of Cells detected: " + str(num))
# Now we want to separate the two objects in image
# Generate the markers as local maxima of the distance to the background
distance = ndi.distance_transform_edt(cells_cleaned)
local_maxi = peak_local_max(distance,
                            indices=False,
                            footprint=np.ones((100, 100)),
                            labels=labeled_cells)
markers = ndi.label(local_maxi)[0]
labels = watershed(-distance, markers, mask=cells_cleaned)

fig, axes = plt.subplots(ncols=4, figsize=(9, 3), sharex=True, sharey=True)
ax = axes.ravel()

ax[0].imshow(cells_cleaned, cmap=plt.cm.gray)
ax[0].set_title('Overlapping objects')
ax[1].imshow(-distance, cmap=plt.cm.gray)
ax[1].set_title('Distances')
ax[2].imshow(labels, cmap=plt.cm.nipy_spectral)
ax[2].set_title('Separated objects')
ax[3].imshow(r, cmap=plt.cm.gray)
ax[3].set_title('Original')
Example #44
0
        if final_rect[i][j] != 0:
            final_rect[i][j] = 0
        else:
            final_rect[i][j] = 1

#show image
show_image(final_rect)

#Exact euclidean distance transform.
distance = ndimage.distance_transform_edt(final_rect)
print distance.shape
#np.savetxt("output_label.txt", distance, fmt = "%.3f")

#Exact local maxima(tree's peak)
binary_rect = np.array(final_rect)
local_maxi = peak_local_max(distance, indices=False, footprint=np.ones((55,55)),threshold_abs = 10, labels = binary_rect)
print type(local_maxi)
print local_maxi.shape
show_image(local_maxi)

#zengqiang peak? ba peak ju zai yi qi?
markers = morphology.label(local_maxi)
print type(markers)
print markers.shape
show_image(markers)

#watershed
start_ws = time.clock() #time when start watershed
labels_ws = watershed(-distance, markers, mask=binary_rect)
end_ws = time.clock()
time_ws = end_ws - start_ws
    def _compute_num_spots_per_threshold(
            self, img: np.ndarray) -> Tuple[np.ndarray, List[int]]:
        """Computes the number of detected spots for each threshold

        Parameters
        ----------
        img : np.ndarray
            The image in which to count spots

        Returns
        -------
        np.ndarray :
            thresholds
        List[int] :
            spot counts
        """

        # thresholds to search over
        thresholds = np.linspace(img.min(), img.max(), num=100)

        # number of spots detected at each threshold
        spot_counts = []

        # where we stop our threshold search
        stop_threshold = None

        if self.verbose and StarfishConfig().verbose:
            threshold_iter = tqdm(thresholds)
            print('Determining optimal threshold ...')
        else:
            threshold_iter = thresholds

        for stop_index, threshold in enumerate(threshold_iter):
            spots = peak_local_max(img,
                                   min_distance=self.min_distance,
                                   threshold_abs=threshold,
                                   exclude_border=False,
                                   indices=True,
                                   num_peaks=np.inf,
                                   footprint=None,
                                   labels=None)

            # stop spot finding when the number of detected spots falls below min_num_spots_detected
            if len(spots) <= self.min_num_spots_detected:
                stop_threshold = threshold
                if self.verbose:
                    print(
                        f'Stopping early at threshold={threshold}. Number of spots fell below: '
                        f'{self.min_num_spots_detected}')
                break
            else:
                spot_counts.append(len(spots))

        if stop_threshold is None:
            stop_threshold = thresholds.max()

        if len(thresholds > 1):
            thresholds = thresholds[:stop_index]
            spot_counts = spot_counts[:stop_index]

        return thresholds, spot_counts
def get_img_nuclei(imgpath, reg_model):
    imgbase = os.path.basename(imgpath)
    img = read_image(imgpath)

    ## Normalization
    img_norm = reinhard(img)

    ## Regression mode
    img_reg = resize_image(img_norm, 512, 512)

    img_reg_scale = img_reg * (2 / 255.) - 1
    reg, _, _ = tfmodels.bayesian_inference(reg_model,
                                            np.expand_dims(img_reg_scale, 0),
                                            samples=10)
    reg = np.squeeze(reg)

    # Comparison between image_max and im to find the coordinates of local maxima
    try:
        reg_max = peak_local_max(reg,
                                 min_distance=min_distance,
                                 threshold_abs=threshold_abs,
                                 indices=False)
        max_coord = peak_local_max(reg,
                                   min_distance=min_distance,
                                   threshold_abs=threshold_abs,
                                   indices=True)
        wshed = instances(reg, reg_max)
    except:
        print(imgpath, 'Failed watershed')
        return None

    if np.random.binomial(1, 0.2):
        reg_max = cv2.dilate(reg_max.astype(np.uint8),
                             kernel=np.ones((3, 3), np.uint8),
                             iterations=1)
        img_out = overlay(img_reg, reg_max.astype(np.bool))
        cv2.imwrite(os.path.join(tiles_dir, imgbase), img_out)

    wshed = cv2.resize(wshed,
                       dsize=(1000, 1000),
                       interpolation=cv2.INTER_NEAREST)
    nuclei = []
    for x, y in max_coord:
        x = int(x * ds_factor)
        y = int(y * ds_factor)
        label = wshed[x, y]
        bbox = get_box(x, y)
        if bbox is None:
            continue

        wsubimg = wshed[bbox[0]:bbox[1], bbox[2]:bbox[3]]
        subimg = img_norm[bbox[0]:bbox[1], bbox[2]:bbox[3], :]
        mask = wsubimg == label
        mask_area = mask.sum()
        if mask_area < area_threshold:
            continue

        mask = cv2.dilate(mask.astype(np.uint8),
                          np.ones((5, 5), np.uint8),
                          iterations=3)

        subimg = apply_mask(subimg, mask)
        # subimg = correct_angle(subimg, mask)

        nuclei.append(np.expand_dims(subimg, axis=0))

    try:
        nuclei = np.concatenate(nuclei, axis=0)
    except:
        print('No nuclei found')
        return None

    return nuclei
Example #47
0
def depth_callback(depth_message):
    global model
    global graph
    global prev_mp
    global ROBOT_Z
    global fx, cx, fy, cy

    with TimeIt('Crop'):
        depth = bridge.imgmsg_to_cv2(depth_message)

        # Crop a square out of the middle of the depth and resize it to 300*300
        crop_size = 400
        depth_crop = cv2.resize(
            depth[(480 - crop_size) // 2:(480 - crop_size) // 2 + crop_size,
                  (640 - crop_size) // 2:(640 - crop_size) // 2 + crop_size],
            (300, 300))

        # Replace nan with 0 for inpainting.
        depth_crop = depth_crop.copy()
        depth_nan = np.isnan(depth_crop).copy()
        depth_crop[depth_nan] = 0

    with TimeIt('Inpaint'):
        # open cv inpainting does weird things at the border.
        depth_crop = cv2.copyMakeBorder(depth_crop, 1, 1, 1, 1,
                                        cv2.BORDER_DEFAULT)

        mask = (depth_crop == 0).astype(np.uint8)
        # Scale to keep as float, but has to be in bounds -1:1 to keep opencv happy.
        depth_scale = np.abs(depth_crop).max()
        depth_crop = depth_crop.astype(
            np.float32) / depth_scale  # Has to be float32, 64 not supported.

        depth_crop = cv2.inpaint(depth_crop, mask, 1, cv2.INPAINT_NS)

        # Back to original size and value range.
        depth_crop = depth_crop[1:-1, 1:-1]
        depth_crop = depth_crop * depth_scale

    with TimeIt('Calculate Depth'):
        # Figure out roughly the depth in mm of the part between the grippers for collision avoidance.
        depth_center = depth_crop[100:141, 130:171].flatten()  #变成1维
        depth_center.sort()  #按行排序,从小到大
        depth_center = depth_center[:10].mean() * 1000.0

    with TimeIt('Inference'):
        # Run it through the network.
        depth_crop = np.clip((depth_crop - depth_crop.mean()), -1, 1)
        with graph.as_default():
            model = load_model(MODEL_FILE)
            pred_out = model.predict(depth_crop.reshape((1, 300, 300, 1)))

        points_out = pred_out[0].squeeze()  #维度为1则降一维
        points_out[depth_nan] = 0

    with TimeIt('Trig'):
        # Calculate the angle map.
        cos_out = pred_out[1].squeeze()
        sin_out = pred_out[2].squeeze()
        ang_out = np.arctan2(sin_out, cos_out) / 2.0

        width_out = pred_out[3].squeeze() * 150.0  # Scaled 0-150:0-1

    with TimeIt('Filter'):
        # Filter the outputs.
        points_out = ndimage.filters.gaussian_filter(points_out, 5.0)  # 卷积滤波
        ang_out = ndimage.filters.gaussian_filter(ang_out, 2.0)

    with TimeIt('Control'):
        # Calculate the best pose from the camera intrinsics.
        maxes = None

        ALWAYS_MAX = False  # Use ALWAYS_MAX = True for the open-loop solution.

        if ROBOT_Z > 0.34 or ALWAYS_MAX:  # > 0.34 initialises the max tracking when the robot is reset.
            # Track the global max.
            max_pixel = np.array(
                np.unravel_index(np.argmax(points_out), points_out.shape))
            prev_mp = max_pixel.astype(np.int)
        else:
            # Calculate a set of local maxes.  Choose the one that is closes to the previous one.
            maxes = peak_local_max(points_out,
                                   min_distance=10,
                                   threshold_abs=0.1,
                                   num_peaks=3)
            if maxes.shape[0] == 0:
                return
            max_pixel = maxes[np.argmin(np.linalg.norm(maxes - prev_mp,
                                                       axis=1))]

            # Keep a global copy for next iteration.
            prev_mp = (max_pixel * 0.25 + prev_mp * 0.75).astype(np.int)

        ang = ang_out[max_pixel[0], max_pixel[1]]
        width = width_out[max_pixel[0], max_pixel[1]]

        # Convert max_pixel back to uncropped/resized image coordinates in order to do the camera transform.
        max_pixel = ((np.array(max_pixel) / 300.0 * crop_size) +
                     np.array([(480 - crop_size) // 2,
                               (640 - crop_size) // 2]))
        max_pixel = np.round(max_pixel).astype(np.int)

        point_depth = depth[max_pixel[0], max_pixel[1]]

        # These magic numbers are my camera intrinsic parameters.
        x = (max_pixel[1] - cx) / (fx) * point_depth
        y = (max_pixel[0] - cy) / (fy) * point_depth
        z = point_depth

        if np.isnan(z):
            return

    with TimeIt('Draw'):
        # Draw grasp markers on the points_out and publish it. (for visualisation)
        grasp_img = np.zeros((300, 300, 3), dtype=np.uint8)
        grasp_img[:, :, 2] = (points_out * 255.0)

        grasp_img_plain = grasp_img.copy()

        rr, cc = circle(prev_mp[0], prev_mp[1], 5)
        grasp_img[rr, cc, 0] = 0
        grasp_img[rr, cc, 1] = 255
        grasp_img[rr, cc, 2] = 0

    with TimeIt('Publish'):
        # Publish the output images (not used for control, only visualisation)
        grasp_img = bridge.cv2_to_imgmsg(grasp_img, 'bgr8')
        grasp_img.header = depth_message.header
        grasp_pub.publish(grasp_img)

        grasp_img_plain = bridge.cv2_to_imgmsg(grasp_img_plain, 'bgr8')
        grasp_img_plain.header = depth_message.header
        grasp_plain_pub.publish(grasp_img_plain)

        depth_pub.publish(bridge.cv2_to_imgmsg(depth_crop))

        ang_pub.publish(bridge.cv2_to_imgmsg(ang_out))

        # Output the best grasp pose relative to camera.
        cmd_msg = Float32MultiArray()
        cmd_msg.data = [x, y, z, ang, width, depth_center]
        cmd_pub.publish(cmd_msg)
# Loop through all tif files in input folder
Images = (glob.glob(InputPath+"/*.tif"))
for img in Images:

    # Read image
    I = io.imread(img)

    # Processing

    # Gaussian filter
    if IntensityBlurRad >= 1:
        I = 255*gaussian(I, sigma=IntensityBlurRad)

    # Adaptive threshold
    mask = threshold_adaptive(I, RadThr, offset = Thr).astype(np.uint8)

    # Binary watershed
    distance = ndimage.distance_transform_edt(mask)
    distance = gaussian(distance, sigma=DistanceBlurRad)
    local_maxi = peak_local_max(distance, indices=False, footprint=np.ones((3, 3)), labels=mask)
    markers = morphology.label(local_maxi)
    nuclei_labels = watershed(-distance, markers, mask=mask)
    nuclei_labels = nuclei_labels.astype(np.uint16)
    nuclei_labels = remove_small_objects(nuclei_labels, min_size=MinSize)
    nuclei_labels = skimage.segmentation.relabel_sequential(nuclei_labels)[0]
    nuclei_labels = nuclei_labels.astype(np.uint16)

    # Write label mask
    filename = os.path.basename(img)
    io.imsave(OutputPath+"/"+filename, nuclei_labels)
def froc_eval(g, t, sig, name, data_type):

    mask_folder = "..\\dataset\\" + data_type + "_cam\\mask"
    result_folder = "..\\results\\" + name + "\\" + data_type

    result_file_list = []
    result_file_list += [
        each for each in os.listdir(result_folder) if each.endswith('.tif')
    ]

    #    result_file_list= [result_file_list[i] for i in [1,0,20,43,61,66,81,99,102,111,10,71]]
    #    result_file_list= [result_file_list[i] for i in [1]]

    #    if data_type=='valid':
    #        result_file_list= [result_file_list[i] for i in [2,0,5,7,9,11,13,15,17]]
    #    else:
    #        result_file_list= [result_file_list[i] for i in np.arange(0,110,3)]

    EVALUATION_MASK_LEVEL = 5  # Image level at which the evaluation is done
    L0_RESOLUTION = 0.243  # pixel resolution at level 0

    FROC_data = np.zeros((4, len(result_file_list)), dtype=np.object)
    FP_summary = np.zeros((2, len(result_file_list)), dtype=np.object)
    detection_summary = np.zeros((2, len(result_file_list)), dtype=np.object)

    caseNum = 0
    for case in result_file_list:
        print(
            str(g) + '  ' + str(t) + '  ' + str(sig) + '  ' +
            'Evaluating Performance on image:', case[0:-4])
        sys.stdout.flush()
        #        csvDIR = os.path.join(result_folder, case)
        #        Probs, Xcorr, Ycorr = readCSVContent(csvDIR)

        result_img_folder = "..\\results\\" + name + "\\" + data_type
        r_n = os.path.join(result_img_folder, case[0:-4]) + '.tif'
        res_img = imread_gdal_mask_small(r_n, EVALUATION_MASK_LEVEL - 3)

        r = int(((2 * np.ceil(2 * sig) + 1) - 1) / 2)

        Probs, Xcorr, Ycorr = [], [], []
        res_img = median_filter(res_img, 5)
        res_img = gaussian_filter(res_img, g)
        res_img[:r, :] = 0
        res_img[-r:, :] = 0
        res_img[:, -r:] = 0
        res_img[:, :r] = 0

        #        res_0=res_img
        #
        #        cont=1
        #        while cont:
        #            ind=np.argmax(res_img,axis=None)
        #            ind = np.unravel_index(ind, res_img.shape)
        #            v=res_0[ind[0],ind[1]]
        #            if v>t:
        #                Probs.append(v)
        #                Xcorr.append(ind[1])
        #                Ycorr.append(ind[0])
        #                rem=np.ones(np.shape(res_img),dtype=np.float32)
        #                di=makeGaussian(sig)
        #                rem[ind[0]-r:ind[0]-r+np.shape(di)[0],ind[1]-r:ind[1]-r+np.shape(di)[1]]=1-di
        #
        #                res_img=res_img*rem
        #
        #            else:
        #                cont=0

        tmp = peak_local_max(res_img, min_distance=int(sig), threshold_abs=t)
        Ycorr = list(tmp[:, 0])
        Xcorr = list(tmp[:, 1])
        Probs = list(res_img[Ycorr, Xcorr])

        #        plt.imshow(res_img)
        #        plt.plot(Xcorr, Ycorr,'*')

        is_tumor = case[0:5] == 'tumor'
        if (is_tumor):
            maskDIR = os.path.join(mask_folder, case[0:-4]) + '_mask.tif'
            evaluation_mask = computeEvaluationMask(maskDIR, L0_RESOLUTION,
                                                    EVALUATION_MASK_LEVEL)
            ITC_labels = computeITCList(evaluation_mask, L0_RESOLUTION,
                                        EVALUATION_MASK_LEVEL)

#            plt.figure()
#            plt.imshow(evaluation_mask)
#            plt.plot(Xcorr, Ycorr,'*')
#            a=fdfdfdfd

        else:
            evaluation_mask = 0
            ITC_labels = []


#

#        a=fsddf
#
        FROC_data[0][caseNum] = case
        FP_summary[0][caseNum] = case
        detection_summary[0][caseNum] = case
        FROC_data[1][caseNum], FROC_data[2][caseNum], FROC_data[3][
            caseNum], detection_summary[1][caseNum], FP_summary[1][
                caseNum] = compute_FP_TP_Probs(Ycorr, Xcorr, Probs, is_tumor,
                                               evaluation_mask, ITC_labels,
                                               EVALUATION_MASK_LEVEL)
        caseNum += 1

    # Compute FROC curve
    total_FPs, total_sensitivity = computeFROC(FROC_data)
    #    sfsdfd=fdfsdfsd

    # plot FROC curve
    #    plotFROC(total_FPs, total_sensitivity)
    if len(total_FPs) > 2:
        results0 = griddata(total_FPs, total_sensitivity,
                            [0.25, 0.5, 1, 2, 4, 8])
        print(results0)
        results = np.array(results0)
        if np.sum(np.isnan(results)) <= 6:
            results[np.isnan(results)] = results[np.isnan(results) == 0][-1]
    else:
        results = np.ones(6) * np.nan

    print(results)
    froc = np.mean(results)
    print(froc)
    return results, froc
def __tutorial_hough_circle_detection_skiimage(img_path,
                                               min_dim=40,
                                               max_dim=60):
    """
    This algorithm is crap, the one using opencv is much much better
    :param img_path:
    :param min_dim:
    :param max_dim:
    :return:
    """

    # load picture and detect edges
    img = cv2.imread(img_path)
    img = cv2.cvtColor(img, cv2.COLOR_BGRA2GRAY)
    img_edges = canny(img, sigma=3, low_threshold=10, high_threshold=50)

    centers = []
    accums = []
    radii = []

    # detect all radii within the range
    min_radius = int(min_dim / 2)
    max_radius = int(max_dim / 2)
    hough_radii = np.arange(start=min_radius, stop=max_radius, step=1)
    hough_res = hough_circle(img_edges, hough_radii)

    for radius, h in zip(hough_radii, hough_res):
        # for each radius, extract 2 circles
        num_peaks = 2
        peaks = peak_local_max(h, num_peaks=num_peaks)
        centers.extend(peaks)
        accums.extend(h[peaks[:, 0], peaks[:, 1]])
        radii.extend([radius] * num_peaks)

    img_width = img.shape[1]
    img_height = img.shape[0]

    # get the sorted accumulated values
    # accums_sorted = np.asarray(accums)
    # accums_sorted = accums_sorted[idx_sorted]

    # don't consider circles with accum value less than the threshold
    accum_threshold = 0.3
    idx_sorted = np.argsort(accums)[::-1]

    # draw the most prominent n circles, i.e those
    # with the highest n peaks
    img_color = color.gray2rgb(img)
    for idx in idx_sorted:
        if accums[idx] < accum_threshold:
            continue
        center_y, center_x = centers[idx]
        radius = radii[idx]
        cx, cy = circle_perimeter(center_x, center_y, radius)
        cx[cx > img_width - 1] = img_width - 1
        cy[cy > img_height - 1] = img_height - 1
        img_color[cy, cx] = (220, 20, 20)

    # save the result
    skimage.io.imsave("D://_Dataset//GTSDB//Test_Regions//_img2_.png",
                      img_color)
    def image_to_spots(self, data_image: xr.DataArray,
                       **kwargs) -> PerImageSliceSpotResults:
        """measure attributes of spots detected by binarizing the image using the selected threshold

        Parameters
        ----------
        data_image : xr.DataArray
            image containing spots to be detected
        kwargs :
            Additional keyword arguments to pass to skimage.feature.peak_local_max

        Returns
        -------
        PerImageSliceSpotResults :
            includes a SpotAttributes DataFrame of metadata containing the coordinates, intensity
            and radius of each spot, as well as any extra information collected during spot finding.
        """

        optimal_threshold, thresholds, spot_counts = self._compute_threshold(
            data_image)

        data_image_np = np.asarray(data_image)

        # identify each spot's size by binarizing and calculating regionprops
        masked_image = data_image_np[:, :] > optimal_threshold
        labels = label(masked_image)[0]
        spot_props = regionprops(np.squeeze(labels))

        # mask spots whose areas are too small or too large
        for spot_prop in spot_props:
            if spot_prop.area < self.min_obj_area or spot_prop.area > self.max_obj_area:
                masked_image[0, spot_prop.coords[:, 0],
                             spot_prop.coords[:, 1]] = 0

        # store re-calculated regionprops and labels based on the area-masked image
        labels = label(masked_image)[0]

        if self.verbose:
            print('computing final spots ...')

        spot_coords = peak_local_max(data_image_np,
                                     min_distance=self.min_distance,
                                     threshold_abs=optimal_threshold,
                                     exclude_border=False,
                                     indices=True,
                                     num_peaks=np.inf,
                                     footprint=None,
                                     labels=labels,
                                     **kwargs)

        if data_image.ndim == 3:
            res = {
                Axes.X.value:
                spot_coords[:, 2],
                Axes.Y.value:
                spot_coords[:, 1],
                Axes.ZPLANE.value:
                spot_coords[:, 0],
                Features.SPOT_RADIUS:
                1,
                Features.SPOT_ID:
                np.arange(spot_coords.shape[0]),
                Features.INTENSITY:
                data_image_np[spot_coords[:, 0], spot_coords[:, 1],
                              spot_coords[:, 2]],
            }
        else:
            zlabel = int(data_image.coords[Axes.ZPLANE.value])
            res = {
                Axes.X.value:
                spot_coords[:, 1],
                Axes.Y.value:
                spot_coords[:, 0],
                Axes.ZPLANE.value:
                zlabel,
                Features.SPOT_RADIUS:
                1,
                Features.SPOT_ID:
                np.arange(spot_coords.shape[0]),
                Features.INTENSITY:
                data_image_np[spot_coords[:, 0], spot_coords[:, 1]],
            }

        extras: Mapping[str, Any] = {
            "threshold": optimal_threshold,
            "thresholds": thresholds,
            "spot_counts": spot_counts
        }

        return PerImageSliceSpotResults(spot_attrs=SpotAttributes(
            pd.DataFrame(res)),
                                        extras=extras)
Example #52
0
def fitter(fname, data, bounds, xaxis, yaxis, rp, binning, angle=0):
	(xmin, xmax, ymin, ymax) = bounds
	(width, height) = (xmax - xmin, ymax - ymin)

	if fname == "Gaussian":
		guess = [0, 0.5, rp["xc"], rp["yc"], 0.2*width, 0.2*height]
		upper_bounds = [defaults.max_od, defaults.max_od, xmax, ymax, width, height]
		lower_bounds = [-defaults.max_od, 0, xmin, ymin, 0, 0]

		res = least_squares(gauss_fit, guess, args=([xaxis, yaxis], angle, data), bounds=(lower_bounds, upper_bounds))
		if not res.success:
			print("Warning: fit did not converge.")
		fits = {
			"f": fname,
			"offset": res.x[0],
			"peak": res.x[1],
			"xc": res.x[2],
			"yc": res.x[3],
			"sigx": res.x[4],
			"sigy": res.x[5],
			"gradx": 0.0,
			"grady": 0.0,
			"angle": angle
		}

		fitted = gauss_fit(res.x, [xaxis, yaxis], angle, 0)
		fitted = np.reshape(fitted, (height, width))

		fitted_x = np.sum(fitted, axis=0) * defaults.od_to_number * binning**2.0 / height
		fitted_y = np.sum(fitted, axis=1) * defaults.od_to_number * binning**2.0  / width

		return (fits, fitted_x, fitted_y)

	if fname == "Gaussian w/ Gradient":
		od_no_bg = subtract_gradient(data)
		blur = ndimage.gaussian_filter(od_no_bg,5,mode='constant')

		# plt.figure()
		# plt.imshow(blur)
		# plt.show()
		
		upper_bounds = [defaults.max_od, defaults.max_od, xmax, ymax, width, height, 0.000375, 0.000375]
		lower_bounds = [-defaults.max_od, 0, xmin, ymin, 0, 0, -0.000375, -0.000375]
		guess = [0, 0.5, rp["xc"], rp["yc"], 0.2*width, 0.2*height, 0.0, 0.0]

		pks=peak_local_max(blur, min_distance=20,exclude_border=2, num_peaks=3)
		guesses = [guess]
		for pk in pks:
			yc = pk[0]
			xc = pk[1]
			peak = data[yc, xc]
			offset = np.mean(data)
			if peak > 0:
				(sigx, sigy) = 15, 15
				guess = [offset, peak, xmin+xc, ymin+yc, sigx, sigy, 0.0, 0.0]
				guesses.append(guess)

		best_fit = None
		best_guess = np.inf		

		for guess in guesses:
			print(upper_bounds)
			print(lower_bounds)
			print(guess)
			try:
				res = least_squares(gauss_grad_fit, guess, args=([xaxis, yaxis], angle, data), bounds=(lower_bounds, upper_bounds))
				print(res.cost)
				print(res.x)
				if not res.success:
					print("Warning: fit did not converge.")
				elif res.cost < best_guess:
					best_guess = res.cost
					best_fit = res
			except ValueError as e:
				print(e)

		res = best_fit

		# Try to get rid of big Gaussians fit when there's no signal
		# if res.x[4] > 0.5 * width and res.x[5] > 0.5 * height and res.x[1] < 0.02:
		# 	res.x[1] = 0

		fits = {
			"f": fname,
			"offset": res.x[0],
			"peak": res.x[1],
			"xc": res.x[2],
			"yc": res.x[3],
			"sigx": res.x[4],
			"sigy": res.x[5],
			"gradx": res.x[6],
			"grady": res.x[7],
			"angle": angle
		}

		fitted = gauss_grad_fit(res.x, [xaxis, yaxis], angle, 0)
		fitted = np.reshape(fitted, (height, width))

		fitted_x = np.sum(fitted, axis=0) * defaults.od_to_number * binning**2.0 / height
		fitted_y = np.sum(fitted, axis=1) * defaults.od_to_number * binning**2.0  / width

		return (fits, fitted_x, fitted_y)

	# if fname == "Gaussian w/ Gradient":
	# 	od_no_bg = subtract_gradient(data)
	# 	blur = ndimage.gaussian_filter(od_no_bg,5,mode='constant')

	# 	# plt.figure()
	# 	# plt.imshow(blur)
	# 	# plt.show()
		
	# 	upper_bounds = [defaults.max_od, defaults.max_od, xmax, ymax, width, height, 0.000375, 0.000375]
	# 	lower_bounds = [-defaults.max_od, 0, xmin, ymin, 0, 0, -0.000375, -0.000375]
	# 	guess = [0, 0.5, rp["xc"], rp["yc"], 0.2*width, 0.2*height, 0.0, 0.0]

	# 	pks=peak_local_max(blur, min_distance=20,exclude_border=2, num_peaks=3)
	# 	guesses = [guess]
	# 	for pk in pks:
	# 		yc = pk[0]
	# 		xc = pk[1]
	# 		peak = data[yc, xc]
	# 		offset = np.mean(data)
	# 		if peak > 0:
	# 			(sigx, sigy) = 15, 15
	# 			guess = [offset, peak, xmin+xc, ymin+yc, sigx, sigy, 0.0, 0.0]
	# 			guesses.append(guess)

	# 	best_fit = None
	# 	best_guess = np.inf		

	# 	for guess in guesses:
	# 		print(upper_bounds)
	# 		print(lower_bounds)
	# 		print(guess)
	# 		try:
	# 			res = least_squares(gauss_grad_fit_45, guess, args=([xaxis, yaxis], data), bounds=(lower_bounds, upper_bounds))
	# 			print(res.cost)
	# 			print(res.x)
	# 			if not res.success:
	# 				print("Warning: fit did not converge.")
	# 			elif res.cost < best_guess:
	# 				best_guess = res.cost
	# 				best_fit = res
	# 		except ValueError as e:
	# 			print(e)

	# 	res = best_fit
	# 	fits = {
	# 		"f": fname,
	# 		"offset": res.x[0],
	# 		"peak": res.x[1],
	# 		"xc": res.x[2],
	# 		"yc": res.x[3],
	# 		"sigx": res.x[4],
	# 		"sigy": res.x[5],
	# 		"gradx": res.x[6],
	# 		"grady": res.x[7]
	# 	}

	# 	fitted = gauss_grad_fit_45(res.x, [xaxis, yaxis], 0)
	# 	fitted = np.reshape(fitted, (height, width))

	# 	fitted_x = np.sum(fitted, axis=0) * defaults.od_to_number * binning**2.0 / height
	# 	fitted_y = np.sum(fitted, axis=1) * defaults.od_to_number * binning**2.0  / width

	# 	return (fits, fitted_x, fitted_y)

	elif fname == "Fermi 2D":
		(fit_gauss, f_x, f_y) = fitter("Gaussian", data, bounds, xaxis, yaxis, rp, binning)
		guess = [fit_gauss["offset"], fit_gauss["peak"], fit_gauss["xc"], fit_gauss["sigx"], 0] # q=0 is T/TF=0.78
		upper_bounds = [fit_gauss["offset"]+0.1, defaults.max_od, xmax, width, 50] # q=50 is T/TF=0.02
		lower_bounds = [fit_gauss["offset"]-0.1, -0.1, xmin, 0, -5] # q=-5 is T/TF=8

		# Integrate out vertical dimension
		data_int = np.sum(data, axis=0) / height

		res = least_squares(fermi2d, guess, args=(xaxis, angle, data_int), bounds=(lower_bounds, upper_bounds))
		if not res.success:
			print "Warning: fit did not converge."

		fits = {
			"f": fname,
			"offset": res.x[0],
			"peak": res.x[1],
			"xc": res.x[2],
			"sigx": res.x[3]/np.sqrt(f(np.exp(res.x[4]))),
			"TTF": TTF2d(res.x[4])
		}

		fitted = fermi2d(res.x, xaxis, np.array([0]))
		fitted_x = fitted * defaults.od_to_number * binning**2.0 

		fits.update(
			{
				"peakGauss": fit_gauss["peak"],
				"sigxGauss": fit_gauss["sigx"],
				"sigyGauss": fit_gauss["sigy"],
				"ycGauss": fit_gauss["yc"],
				"angle" : 0.0
			})
		return (fits, fitted_x, [])

	elif fname == "Fermi 3D":
		(fit_gauss, f_x, f_y) = fitter("Gaussian", data, bounds, xaxis, yaxis, rp, binning, angle)
		guess = [fit_gauss["offset"], fit_gauss["peak"], fit_gauss["xc"], fit_gauss["yc"], fit_gauss["sigx"], fit_gauss["sigy"], 0] # q=0 is T/TF=0.57
		upper_bounds = [fit_gauss["offset"]+0.1, fit_gauss["peak"]+0.5, xmax, ymax, width, height, 50] # q=50 is T/TF=0.02
		lower_bounds = [fit_gauss["offset"]-0.1, fit_gauss["peak"]-0.5, xmin, ymin, 0, 0, -6] # q=-6 is T/TF=4

		res = least_squares(fermi3d, guess, args=([xaxis, yaxis], angle, data), bounds=(lower_bounds, upper_bounds))
		if not res.success:
			print "Warning: fit did not converge."

		fits = {
			"f": fname,
			"offset": res.x[0],
			"peak": res.x[1],
			"xc": res.x[2],
			"yc": res.x[3],
			"sigx": res.x[4]/np.sqrt(f(np.exp(res.x[6]))),
			"sigy": res.x[5]/np.sqrt(f(np.exp(res.x[6]))),
			"TTF": TTF3d(res.x[6])
		}

		fitted = fermi3d(res.x, [xaxis, yaxis], angle, np.array([0]))
		fitted = np.reshape(fitted, (height, width))

		fitted_x = np.sum(fitted, axis=0) * defaults.od_to_number * binning**2.0 / height
		fitted_y = np.sum(fitted, axis=1) * defaults.od_to_number * binning**2.0 / width

		fits.update(
			{
				"peakGauss": fit_gauss["peak"],
				"sigxGauss": fit_gauss["sigx"],
				"sigyGauss": fit_gauss["sigy"],
				"angle" : angle
			})
		return (fits, fitted_x, fitted_y)
Example #53
0
def extract(image_sg, image_og, og_filenames, classlist, nu_filenames):
    #    image_og = cv2.cvtColor(image_og, cv2.COLOR_BGR2RGB)

    #thresholding
    ret, thresh = cv2.threshold(image_sg, 180, 255, cv2.THRESH_BINARY)
    #morphological transformation
    kernel = np.ones((5, 5), np.uint8)
    #class_img = cv2.dilate(class_img,kernel,iterations = 1)
    thresh = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
    #kernel = np.ones((9,9),np.uint8)
    #class_img = cv2.erode(class_img,kernel,iterations = 1)

    # compute the exact Euclidean distance from every binary
    # pixel to the nearest zero pixel, then find peaks in this
    # distance map
    D = ndimage.distance_transform_edt(thresh)
    kernel = np.ones((5, 5), np.float32) / 25
    D = cv2.filter2D(D, -1, kernel)

    localMax = peak_local_max(D, indices=False, min_distance=10, labels=thresh)
    #im = Image.fromarray(D).convert('1')
    #im.show(D)

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

    l = []
    for label in np.unique(labels):
        # if the label is zero, we are examining the 'background'
        # so simply ignore it
        if label == 0:
            continue

        # otherwise, allocate memory for the label region and draw
        # it on the mask
        mask = np.zeros(image_sg.shape, dtype="uint8")
        mask[labels == label] = 255

        # detect contours in the mask and grab the largest one
        #cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        #cnts = imutils.grab_contours(cnts)

        # find contours - cv2.findCountours() function changed from OpenCV3 to OpenCV4: now it have only two parameters instead of 3
        cv2MajorVersion = cv2.__version__.split(".")[0]

        # check for contours on thresh
        if int(cv2MajorVersion) == 4:
            ctrs, hier = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,
                                          cv2.CHAIN_APPROX_SIMPLE)
        else:
            im2, ctrs, hier = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,
                                               cv2.CHAIN_APPROX_SIMPLE)

        #sort contours
        sorted_ctrs = sorted(ctrs, key=lambda ctr: cv2.boundingRect(ctr)[0])

        for i, ctr in enumerate(sorted_ctrs):
            #get centroid
            M = cv2.moments(ctr)
            if M["m00"] > 0:
                cX = int(M["m10"] / M["m00"])
                cY = int(M["m01"] / M["m00"])
                #print(cX, cY)
            else:
                continue

            a = int(64 / 2)
            # Getting ROI
            roi = image_og[(cY - a):(cY + a), (cX - a):(cX + a), :]
            if roi.shape != (a * 2, a * 2, 3):
                continue
            l.append([cX, cY, np.asarray(ctr)])
    print('l=', len(l))

    s = []
    for j, name in enumerate(nu_filenames):
        cX_nu = int(name[-11:-8])
        cY_nu = int(name[-7:-4])
        s.append([cX_nu, cY_nu, classlist[j]])

    for m in range(len(l)):
        for n in range(len(s)):
            if l[m][0] == s[n][0] and l[m][1] == s[n][1]:

                if int(s[n][2]) == 1:
                    # draw the contour and center of the shape on the image
                    cv2.drawContours(image_og, [l[m][2]], -1, (0, 255, 255), 2)

                elif int(s[n][2]) == 0:
                    cv2.drawContours(image_og, [l[m][2]], -1, (255, 0, 0), 2)


#    labels = labels + 50
#    labels[labels==50] = 0
    im = Image.fromarray(image_og).convert('RGB')
    #    im.show(image_og)
    savepath = os.path.join(
        os.path.join(
            'C:/CRC project/CRC_pytorch_chenyu/experiments/base_model/output_imgs_mxif_tumorcell_bottom2last/',
            'marked1'), ('%s.png' % (og_filenames)))
    cv2.imwrite(savepath, image_og)
Example #54
0
def find_disks(image, size_range, maximum=100, canny_sigma=1):
    """ Find circular edges in a 2D image using hough transforms.

    An edge is a sharp light-dark or dark-light transition. These are found
    using a canny edge filter. Subsequently, the edges undergo a circular
    Hough transformation for a range of circle radii. Peaks in the hough
    transformed image correspond to circle centers.

    Parameters
    ----------
    image : ndarray, 2d
    size_range : tuple of numbers
        the range of circle radii to look for, in pixels
    maximum : number, optional
        The maximum number of disks
    canny_sigma : number, optional
        The sigma value used in the Canny edge filter. Default 1.

    See also
    --------
    http://scikit-image.org/docs/dev/auto_examples/plot_canny.html
    http://scikit-image.org/docs/dev/auto_examples/edges/plot_circular_elliptical_hough_transform.html
    """
    # Define the radius at for which hough transforms are done. Take integer
    # values and a maximum of 30 intermediate steps.
    step = max(int(round(abs(size_range[1] - size_range[0]) / 30)), 1)
    radii = np.arange(size_range[0], size_range[1], step=step, dtype=np.intp)

    # Find edges in the image
    edges = canny(image, sigma=canny_sigma)
    # Perform a circular hough transform of the edges
    circles = hough_circle(edges, radii)

    # Collect the peaks in hough space, these are circle centers
    data = []
    for radius, circle in zip(radii, circles):
        peaks = peak_local_max(circle,
                               threshold_rel=0.5,
                               num_peaks=int(maximum))
        try:
            accumulator = circle[peaks[:, 0], peaks[:, 1]]
        except TypeError:
            continue
        data.append(
            pd.DataFrame(
                dict(r=[radius] * peaks.shape[0],
                     y=peaks[:, 0],
                     x=peaks[:, 1],
                     accum=accumulator)))
    if len(data) == 0:
        return pd.DataFrame(columns=['r', 'y', 'x', 'accum'])
    data = pd.concat(data, ignore_index=True)

    # drop features that are closer than the average radius together
    # keep the ones that are brightest in hough space (= the most circular ones)
    to_drop = where_close(data[['y', 'x']].values,
                          data['r'].mean(),
                          intensity=data['accum'].values)
    data.drop(to_drop, inplace=True)

    # Keep only brightest n circles
    try:  # work around API change in pandas 0.17
        data = data.sort_values(by=['accum'], ascending=False)
    except AttributeError:
        data = data.sort(columns=['accum'], ascending=False)

    return data.head(maximum).copy()
Example #55
0
kernel = np.ones((5,5),np.uint8)

erosion_a = cv.erode(inner_a,kernel,iterations = 2)
erosion_b = cv.erode(inner_b,kernel,iterations = 2)

innerA = cv.dilate(erosion_a,kernel,iterations = 1)
innerB = cv.dilate(erosion_b,kernel,iterations = 1)

cv.imwrite('innerA.png',innerA)
cv.imwrite('innerB.png',innerB)
  
eucl_a = ndimage.distance_transform_edt(innerA)
eucl_b = ndimage.distance_transform_edt(innerB)

localMaxA = peak_local_max(eucl_a, indices=False, labels=innerA)
localMaxB = peak_local_max(eucl_b, indices=False, labels=innerB)

markers_a = ndimage.label(localMaxA, structure=np.ones((3, 3)))[0]
markers_b = ndimage.label(localMaxB, structure=np.ones((3, 3)))[0]

labels_a = watershed(-eucl_a, markers_a, mask=innerA)
labels_b = watershed(-eucl_b, markers_b, mask=innerB)

def get_area(labels, inner_mask, img):
    area = 0
    for label in np.unique(labels):
        if label== 0:
            continue

        mask = np.zeros(inner_mask.shape, dtype="uint8")
def Workflow_slc25a17(struct_img,rescale_ratio, output_type, output_path, fn, output_func=None):
    ##########################################################################
    # PARAMETERS:
    #   note that these parameters are supposed to be fixed for the structure
    #   and work well accross different datasets

    intensity_norm_param = [2, 36]
    gaussian_smoothing_sigma = 1
    gaussian_smoothing_truncate_range = 3.0
    dot_3d_sigma = 1
    dot_3d_cutoff = 0.045 #0.03 #0.04
    minArea = 3 #5
    ##########################################################################

    out_img_list = []
    out_name_list = []

    ###################
    # PRE_PROCESSING
    ###################
    # intenisty normalization (min/max)
    struct_img = intensity_normalization(struct_img, scaling_param=intensity_norm_param)

    out_img_list.append(struct_img.copy())
    out_name_list.append('im_norm')
    
    # rescale if needed
    if rescale_ratio>0:
        struct_img = resize(struct_img, [1, rescale_ratio, rescale_ratio], method="cubic")
        struct_img = (struct_img - struct_img.min() + 1e-8)/(struct_img.max() - struct_img.min() + 1e-8)
        gaussian_smoothing_truncate_range = gaussian_smoothing_truncate_range * rescale_ratio

    # smoothing with gaussian filter
    structure_img_smooth = image_smoothing_gaussian_slice_by_slice(struct_img, sigma=gaussian_smoothing_sigma, truncate_range=gaussian_smoothing_truncate_range)

    out_img_list.append(structure_img_smooth.copy())
    out_name_list.append('im_smooth')

    ###################
    # core algorithm
    ###################

    # step 1: LOG 3d 
    response = dot_3d(structure_img_smooth, log_sigma=dot_3d_sigma)
    bw = response > dot_3d_cutoff

    bw = remove_small_objects(bw>0, min_size=minArea, connectivity=1, in_place=False)

    out_img_list.append(bw.copy())
    out_name_list.append('interm_mask')

    # step 2: 'local_maxi + watershed' for cell cutting
    local_maxi = peak_local_max(struct_img,labels=label(bw), min_distance=2, indices=False)

    out_img_list.append(local_maxi.copy())
    out_name_list.append('interm_local_max')

    distance = distance_transform_edt(bw)
    im_watershed = watershed(-1*distance, label(dilation(local_maxi, selem=ball(1))), mask=bw, watershed_line=True)

    ###################
    # POST-PROCESSING
    ###################
    seg = remove_small_objects(im_watershed, min_size=minArea, connectivity=1, in_place=False)

    ###### HACK: Only for 2019 April Release #####
    if np.count_nonzero(seg>0)<50000:
        print('FLAG: please check the meta data of the original CZI for QC')
        
    # output
    seg = seg>0
    seg = seg.astype(np.uint8)
    seg[seg>0]=255

    out_img_list.append(seg.copy())
    out_name_list.append('bw_final')

    if output_type == 'default': 
        # the default final output
        save_segmentation(seg, False, output_path, fn)
    elif output_type == 'AICS_pipeline':
        # pre-defined output function for pipeline data
        save_segmentation(seg, True, output_path, fn)
    elif output_type == 'customize':
        # the hook for passing in a customized output function
        #output_fun(out_img_list, out_name_list, output_path, fn)
        print('please provide custom output function')
    elif output_type == 'array':
        return seg
    elif output_type == 'array_with_contour':
        return (seg, generate_segmentation_contour(seg))
    else:
        # the hook for pre-defined RnD output functions (AICS internal)
        img_list, name_list = SLC25A17_output(out_img_list, out_name_list, output_type, output_path, fn)
        if output_type == 'QCB':
            return img_list, name_list
Example #57
0
    thresh = threshold_otsu(
        img_gray)  # return threshold value based on on otsu's method

    if bright_background:
        foreground_mask = img_gray <= thresh  # for bright background
    else:
        foreground_mask = img_gray > thresh  # for dark background

    # compute the Euclidean distance from every binary pixel to the nearest zero pixel
    # and then find peaks in this distance map
    #
    distance = ndimage.distance_transform_edt(foreground_mask)

    # return a boolean array shaped like image, with peaks represented by True values
    localMax = peak_local_max(distance,
                              indices=False,
                              min_distance=30,
                              labels=foreground_mask)

    # perform a connected component analysis on the local peaks using 8-connectivity
    markers = ndimage.label(localMax, structure=np.ones((3, 3)))[0]

    # apply the Watershed algorithm
    labels = watershed(-distance, markers, mask=foreground_mask)

    print ' [x] Analyzing image %s' % (image_name)
    print ' [x] there are %d segments found' % (len(np.unique(labels)) - 1)

    # loop over the unique labels returned by the Watershed algorithm
    # each label is a unique object
    img.setflags(write=1)
    for label in np.unique(labels):
Example #58
0
def _step_4_find_peaks(
    aligned_composite_bg_removed_im,
    aligned_roi_rect,
    raw_mask_rects,
    border_size,
    field_df,
    sigproc_params,
):
    """
    Find peaks on the composite image

    TASK: Remove the mask rect checks and replace with the same masking
    logic that is now implemented in the alignment phase. That is, just remove
    the peaks from the source instead of in post-processing.
    """
    from skimage.feature import peak_local_max  # Defer slow import
    from scipy.stats import iqr

    n_outchannels, n_inchannels, n_cycles, dim = sigproc_params.channels_cycles_dim
    assert (
        aligned_composite_bg_removed_im.shape[0]
        == aligned_composite_bg_removed_im.shape[1]
    )
    aligned_dim, _ = aligned_composite_bg_removed_im.shape
    check.array_t(aligned_composite_bg_removed_im, is_square=True)

    hat_rad = sigproc_params.hat_rad
    brim_rad = sigproc_params.hat_rad + 1
    hat_mask, brim_mask = _hat_masks(hat_rad, brim_rad)

    kernel = imops.generate_gauss_kernel(1.0)
    kernel = kernel - kernel.mean()
    _fiducial_im = imops.convolve(aligned_composite_bg_removed_im, kernel)

    # Black out the convolution artifact around the perimeter of the _fiducial_im
    search_roi_rect = Rect(
        aligned_roi_rect.b + brim_rad,
        aligned_roi_rect.t - brim_rad,
        aligned_roi_rect.l + brim_rad,
        aligned_roi_rect.r - brim_rad,
    )
    search_roi = search_roi_rect.roi()
    composite_fiducial_im = np.zeros_like(aligned_composite_bg_removed_im)

    # Use Inter-Quartile Range for some easy filtering
    _iqr = 0
    if sigproc_params.iqr_rng is not None:
        _iqr = iqr(
            _fiducial_im[search_roi],
            rng=(100 - sigproc_params.iqr_rng, sigproc_params.iqr_rng),
        )

    composite_fiducial_im[search_roi] = (_fiducial_im[search_roi] - _iqr).clip(min=0)

    locs = peak_local_max(
        composite_fiducial_im,
        min_distance=hat_rad,
        threshold_abs=sigproc_params.threshold_abs,
    )

    # Emergency exit to prevent memory overflows
    # check.affirm(len(locs) < 7000, f"Too many peaks {len(locs)}")

    shift = field_df.set_index("cycle_i").sort_index()[["shift_y", "shift_x"]].values
    shift_y = shift[:, 0]
    shift_x = shift[:, 1]

    # Discard any peak in any mask_rect
    # ALIGN the mask rects to the composite coordinate system
    aligned_mask_rects = []
    for channel in range(sigproc_params.n_output_channels):
        channel_rects = safe_list_get(raw_mask_rects, channel, [])
        for cycle in range(n_cycles):
            for rect in safe_list_get(channel_rects, cycle, []):
                yx = XY(rect[0], rect[1])
                hw = WH(rect[2], rect[3])
                yx += XY(border_size, border_size) - XY(shift_x[cycle], shift_y[cycle])
                aligned_mask_rects += [(yx[0], yx[1], yx[0] + hw[0], yx[1] + hw[1])]

    aligned_mask_rects = np.array(aligned_mask_rects)
    if aligned_mask_rects.shape[0] > 0:

        # To compare every loc with every mask rect we use the tricky np.fn.outer()
        y_hits = np.greater_equal.outer(locs[:, 0], aligned_mask_rects[:, 0])
        y_hits &= np.less.outer(locs[:, 0], aligned_mask_rects[:, 2])

        x_hits = np.greater_equal.outer(locs[:, 1], aligned_mask_rects[:, 1])
        x_hits &= np.less.outer(locs[:, 1], aligned_mask_rects[:, 3])

        inside_rect = x_hits & y_hits  # inside a rect if x and y are inside the rect
        locs_to_keep = ~np.any(
            inside_rect, axis=1
        )  # Reject if inside of any masked rect
        locs = locs[locs_to_keep]

    circle_im = np.zeros((aligned_dim, aligned_dim))

    center = aligned_dim / 2

    peak_rows = []
    for field_peak_i, loc in enumerate(locs):
        if sigproc_params.radial_filter is not None:
            radius = math.sqrt((loc[0] - center) ** 2 + (loc[1] - center) ** 2)
            radius /= center
            if radius >= sigproc_params.radial_filter:
                continue

        imops.set_with_mask_in_place(circle_im, brim_mask, 1, loc=loc, center=True)

        peak_rows += [
            Munch(
                peak_i=0,
                field_peak_i=field_peak_i,
                aln_y=int(loc[0]),
                aln_x=int(loc[1]),
            )
        ]

    peak_df = pd.DataFrame(peak_rows)

    return peak_df, circle_im, aligned_mask_rects
Example #59
0
def depth_callback(depth_message):
    global model
    global graph
    global prev_mp
    global ROBOT_Z
    global fx, cx, fy, cy
    global crop_size
    global Input_Res
    global rgb_crop
    global grey_crop
    with TimeIt('prediction'):
        # with TimeIt('Crop'):

        # depth = bridge.imgmsg_to_cv2(depth_message)
        rgbdImg = bridge.imgmsg_to_cv2(depth_message)
        depthImg = rgbdImg[:, :, 3]
        rgbImg = rgbdImg[:, :, :3]

        rgb_raw_crop = cv2.resize(
            rgbdImg[(304 - crop_size) // 2:(304 - crop_size) // 2 + crop_size,
                    (304 - crop_size) // 2:(304 - crop_size) // 2 + crop_size],
            (Input_Res, Input_Res))
        grey_crop = cv2.cvtColor(rgb_raw_crop, cv2.COLOR_RGB2GRAY)

        near = 0.01
        far = 0.24
        depth = far * near / (far - (far - near) * depthImg)
        depth_crop = cv2.resize(
            depth[(304 - crop_size) // 2:(304 - crop_size) // 2 + crop_size,
                  (304 - crop_size) // 2:(304 - crop_size) // 2 + crop_size],
            (Input_Res, Input_Res))
        depth_crop = cv2.resize(depth, (Input_Res, Input_Res))

        # Replace nan with 0 for inpainting.
        depth_crop = depth_crop.copy()
        depth_nan = np.isnan(depth_crop).copy()
        # print(depth_nan)
        depth_crop[depth_nan] = 0
        # np.save("/home/aarons/catkin_kinect/src/yumi_grasp/src/depth_raw_pub2.npy", depth_crop)

        # with TimeIt('Inpaint'):
        # open cv inpainting does weird things at the border.
        depth_crop = cv2.copyMakeBorder(depth_crop, 1, 1, 1, 1,
                                        cv2.BORDER_DEFAULT)

        mask = (depth_crop == 0).astype(np.uint8)
        # Scale to keep as float, but has to be in bounds -1:1 to keep opencv happy.
        depth_scale = np.abs(depth_crop).max()
        depth_crop = depth_crop.astype(np.float32) / (
            depth_scale)  # Has to be float32, 64 not supported.
        depth_crop = cv2.inpaint(depth_crop, mask, 1, cv2.INPAINT_NS)

        # Back to original size and value range.
        depth_crop = depth_crop[1:-1, 1:-1]
        depth_crop = depth_crop * depth_scale  # kinect output unit is millemeter, but realsense output unit is meter

        # with TimeIt('Calculate Depth'):
        # Figure out roughly the depth in mm of the part between the grippers for collision avoidance.
        depth_crop_neighbor = depth_crop.copy()
        # cv2.imshow('fram22e',depth_crop_neighbor)
        # depth_center = depth_crop[100:141, 130:171].flatten()
        depth_center = depth_crop.flatten()
        depth_center.sort()
        # depth_center = depth_center[:10].mean() * 1000.0
        depth_center = depth_center.mean() * 1000.0
        depth_crop = (depth_crop - depth_crop.min()
                      ) / np.float32(depth_crop.max() - depth_crop.min())
        depth_raw_pub.publish(bridge.cv2_to_imgmsg(grey_crop))
        rgb_crop = np.expand_dims(
            ((grey_crop - grey_crop.min()) /
             np.float32(grey_crop.max() - grey_crop.min())), -1)
        depth_crop = np.expand_dims(depth_crop, axis=2)
        rgbd_input = np.concatenate((rgb_crop, depth_crop), axis=2)
        rgbd_input = np.expand_dims(rgbd_input, axis=0)
        with TimeIt('Inference'):
            with graph.as_default():
                # print("begin prediction")
                # pred_out = model.predict(depth_crop.reshape((1, Input_Res, Input_Res, 1)))
                pred_out = model.predict(rgbd_input)

        points_out = pred_out[0].squeeze()
        points_out[depth_nan] = 0

        # with TimeIt('Trig'):
        # Calculate the angle map.
        cos_out = pred_out[1].squeeze()
        sin_out = pred_out[2].squeeze()
        ang_out = np.arctan2(sin_out, cos_out) / 2.0
        width_out = pred_out[3].squeeze() * 150.0  # Scaled 0-150:0-1

        # with TimeIt('Filter'):
        # Filter the outputs.
        points_out = ndimage.filters.gaussian_filter(points_out,
                                                     5.0)  # 3.0   5.0 aaron
        ang_out = ndimage.filters.gaussian_filter(ang_out, 2.0)

        # with TimeIt('Control'):
        # Calculate the best pose from the camera intrinsics.
        maxes = None

        ALWAYS_MAX = False  # Use ALWAYS_MAX = True for the open-loop solution.

        if ROBOT_Z > 0.34 or ALWAYS_MAX:  # > 0.34 initialises the max tracking when the robot is reset.
            # Track the global max.
            max_pixel = np.array(
                np.unravel_index(np.argmax(points_out), points_out.shape))
            prev_mp = max_pixel.astype(np.int)
        else:
            # Calculate a set of local maxes.  Choose the one that is closes to the previous one.
            # maxes = peak_local_max(points_out, min_distance=20, threshold_abs=0.1, num_peaks=20)  #min_distance=10, threshold_abs=0.1, num_peaks=3  15 0.1 20
            maxes = peak_local_max(
                points_out, min_distance=5, threshold_abs=0.1, num_peaks=1
            )  #min_distance=10, threshold_abs=0.1, num_peaks=3  15 0.1 20
            if maxes.shape[0]:
                max_pixel = maxes[np.argmin(
                    np.linalg.norm(maxes - prev_mp, axis=1))]
                # max_pixel = np.array(np.unravel_index(np.argmax(points_out), points_out.shape))
                visual_max_pixel = max_pixel.copy()

                # Keep a global copy for next iteration.
                # prev_mp = (max_pixel * 0.25 + prev_mp * 0.75).astype(np.int)
                grasp_quality = points_out[max_pixel[0], max_pixel[1]]
            else:
                rospy.loginfo("no lacal maxes! ")
                grasp_quality = 0
                cmd_msg = Float32MultiArray()
                cmd_msg.data = [
                    -63, -52, 699, 0.38, 56, 697, grasp_quality, 730, 109, 85
                ]
                # rospy.loginfo(cmd_msg)
                cmd_pub.publish(cmd_msg)

                state_msg = Float32MultiArray()
                state_msg.data = [True]
                rospy.loginfo(state_msg)
                state_pub.publish(state_msg)
                return

            # max_pixel = maxes[np.argmin(np.linalg.norm(maxes - prev_mp, axis=1))]
            # visual_max_pixel = max_pixel.copy()

            # # Keep a global copy for next iteration.
            # prev_mp = (max_pixel * 0.25 + prev_mp * 0.75).astype(np.int)
            # # print(max_pixel)
            # grasp_quality = points_out[max_pixel[0],max_pixel[1]]
        if max_pixel[0] >= 10 and max_pixel[0] <= 394 and max_pixel[
                1] >= 10 and max_pixel[1] <= 394:
            # print('bound exists! ')
            depth_grasp_neighbor = depth_crop_neighbor[max_pixel[0] -
                                                       10:max_pixel[0] + 10,
                                                       max_pixel[1] -
                                                       10:max_pixel[1] +
                                                       10].flatten()
            depth_grasp_neighbor.sort()
            depth_grasp_neighbor = depth_grasp_neighbor[:50].mean() * 1000.0
            # print(depth_grasp_neighbor)
        else:
            depth_grasp_neighbor = depth_center

        ang = ang_out[max_pixel[0], max_pixel[1]]
        width = width_out[max_pixel[0], max_pixel[1]]
        if abs(depth_grasp_neighbor -
               depth_center) < 2 or abs(grey_crop.min() -
                                        grey_crop.mean()) < 35:
            rospy.loginfo('task space is empty!')
            print(depth_center - depth_grasp_neighbor)
            grasp_quality = 0
        # Convert max_pixel back to uncropped/resized image coordinates in order to do the camera transform.
        max_pixel = ((np.array(max_pixel) / 304.0 * crop_size) +
                     np.array([(304 - crop_size) // 2,
                               (304 - crop_size) // 2]))  #[2,1]
        max_pixel = np.round(max_pixel).astype(np.int)
        point_depth = depthImg[max_pixel[0], max_pixel[1]]

        # convert image space to world space OpenGL
        view_matrix = np.array(
            [[0.0, 1.0, -0.0, 0.0], [-1.0, 0.0, -0.0, 0.0],
             [0.0, 0.0, 1.0, 0.0],
             [-0.0, -0.6499999761581421, -1.2400000095367432, 1.0]])
        proj_matrix = np.array([[4.510708808898926, 0.0, 0.0, 0.0],
                                [0.0, 4.510708808898926, 0.0, 0.0],
                                [0.0, 0.0, -1.0020020008087158, -1.0],
                                [0.0, 0.0, -0.0200200192630291, 0.0]])
        inter_gl = np.dot(view_matrix, proj_matrix)
        px = 2.0 * (max_pixel[1] - 0) / 304.0 - 1.0
        py = 1.0 - (2.0 * max_pixel[0]) / 304.0
        pz = 2.0 * point_depth - 1.0
        PP3D = np.array([px, py, pz, 1.0])
        PP_world = np.dot(PP3D, np.linalg.inv(inter_gl))
        # PP_world = np.dot( np.linalg.inv(inter_gl), PP3D)
        rospy.loginfo("PP_world")
        print(PP3D)
        # print(PP_world)
        print(PP_world / PP_world[3])
        x = PP_world[0] / PP_world[3]
        y = PP_world[1] / PP_world[3]
        z = PP_world[2] / PP_world[3]

        # with TimeIt('Draw'):
        # Draw grasp markers on the points_out and publish it. (for visualisation)
        grasp_img = np.zeros((Input_Res, Input_Res, 3), dtype=np.uint8)
        # with open('/home/aarons/catkin_kinect/src/yumi_grasp/src/heatmap.pkl', 'w') as f:
        #     pickle.dump(points_out, f)
        # print(points_out.shape)
        # np.save("/home/aarons/catkin_kinect/src/yumi_grasp/src/realsense_Umodel.npy", points_out)
        # np.savetxt("/home/aarons/catkin_kinect/src/yumi_grasp/src/light_txt.npy", points_out)
        # exit()
        # pd_pointout = pd.DataFrame(points_out)
        # pd_pointout.to_csv('/home/aarons/catkin_kinect/src/yumi_grasp/src/points_out.csv')

        # heatmap test code
        # fig, ax = plt.subplots()
        # ax = sns.heatmap(ang_out, cmap='jet', xticklabels=False, yticklabels=False, cbar=False)
        # fig.add_axes(ax)
        # fig.canvas.draw()
        # data_heatmap = np.fromstring(fig.canvas.tostring_rgb(), dtype=np.uint8, sep='')
        # data_heatmap = data_heatmap.reshape(fig.canvas.get_width_height()[::-1] + (3,))
        # data_crop = cv2.resize(data_heatmap[(480-crop_size)//2:(480-crop_size)//2+crop_size, (640-crop_size)//2:(640-crop_size)//2+crop_size,:], (Input_Res, Input_Res))
        # print(data_crop.shape)
        if VISUALISE:
            pointout_pub.publish(
                bridge.cv2_to_imgmsg(points_out))  # for visualization module
            grasp_img_plain = grasp_img.copy()
            grasp_img[:, :, 2] = (points_out * 255.0)
            # rr, cc = circle(prev_mp[0], prev_mp[1], 5)
            rr, cc = circle(visual_max_pixel[0], visual_max_pixel[1], 5)
            # depth_crop[rr, cc] = 200
            grasp_img[rr, cc, 0] = 0  # R
            grasp_img[rr, cc, 1] = 255  # G
            grasp_img[rr, cc, 2] = 0  # B
            # with TimeIt('Publish'):
            grasp_img = bridge.cv2_to_imgmsg(grasp_img, 'bgr8')
            grasp_img.header = depth_message.header
            grasp_pub.publish(grasp_img)
            grasp_img_plain = bridge.cv2_to_imgmsg(grasp_img_plain, 'rgb8')
            grasp_img_plain.header = depth_message.header
            grasp_plain_pub.publish(grasp_img_plain)
            depth_pub.publish(bridge.cv2_to_imgmsg(depth_crop))
            ang_pub.publish(bridge.cv2_to_imgmsg(ang_out))

        # Output the best grasp pose relative to camera.
        cmd_msg = Float32MultiArray()
        cmd_msg.data = [
            x, y, z, ang, width, depth_grasp_neighbor, grasp_quality,
            depth_center, visual_max_pixel[0], visual_max_pixel[1]
        ]
        rospy.loginfo(cmd_msg)
        cmd_pub.publish(cmd_msg)

        state_msg = Float32MultiArray()
        state_msg.data = [False]
        rospy.loginfo(state_msg)
        state_pub.publish(state_msg)
#im = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
im = img
import numpy as np
import matplotlib.pyplot as plt
from scipy import ndimage as ndi

from skimage.segmentation import watershed
from skimage.feature import peak_local_max
import time
# Generate an initial image with two overlapping circles
# image_max is the dilation of im with a 20*20 structuring element
# It is used within peak_local_max function
image_max = ndi.maximum_filter(im, size=100, mode='constant')

# Comparison between image_max and im to find the coordinates of local maxima
coordinates = peak_local_max(im, min_distance=300)

# display results
fig, axes = plt.subplots(1, 3, figsize=(8, 3), sharex=True, sharey=True)
ax = axes.ravel()
ax[0].imshow(im, cmap=plt.cm.gray)
ax[0].axis('off')
ax[0].set_title('Original')

ax[1].imshow(image_max, cmap=plt.cm.gray)
ax[1].axis('off')
ax[1].set_title('Maximum filter')

ax[2].imshow(im, cmap=plt.cm.gray)
ax[2].autoscale(False)
ax[2].plot(coordinates[:, 1], coordinates[:, 0], 'r.')