예제 #1
0
 def test_four_quadrants(self):
     image = cp.asarray(np.random.uniform(size=(20, 30)))
     i, j = cp.mgrid[0:20, 0:30]
     labels = 1 + (i >= 10) + (j >= 15) * 2
     i, j = cp.mgrid[-3:4, -3:4]
     footprint = i * i + j * j <= 9
     expected = cp.zeros(image.shape, float)
     for imin, imax in ((0, 10), (10, 20)):
         for jmin, jmax in ((0, 15), (15, 30)):
             expected[imin:imax,
                      jmin:jmax] = ndi.maximum_filter(image[imin:imax,
                                                            jmin:jmax],
                                                      footprint=footprint)
     expected = expected == image
     with expected_warnings(["indices argument is deprecated"]):
         result = peak.peak_local_max(image,
                                      labels=labels,
                                      footprint=footprint,
                                      min_distance=1,
                                      threshold_rel=0,
                                      indices=False,
                                      exclude_border=False)
     assert cp.all(result == expected)
예제 #2
0
 def test_indices_with_labels(self):
     image = cp.asarray(np.random.uniform(size=(40, 60)))
     i, j = cp.mgrid[0:40, 0:60]
     labels = 1 + (i >= 20) + (j >= 30) * 2
     i, j = cp.mgrid[-3:4, -3:4]
     footprint = i * i + j * j <= 9
     expected = cp.zeros(image.shape, float)
     for imin, imax in ((0, 20), (20, 40)):
         for jmin, jmax in ((0, 30), (30, 60)):
             expected[imin:imax,
                      jmin:jmax] = ndi.maximum_filter(image[imin:imax,
                                                            jmin:jmax],
                                                      footprint=footprint)
     expected = cp.stack(cp.nonzero(expected == image), axis=-1)
     expected = expected[cp.argsort(image[tuple(expected.T)])[::-1]]
     result = peak.peak_local_max(image,
                                  labels=labels,
                                  min_distance=1,
                                  threshold_rel=0,
                                  footprint=footprint,
                                  exclude_border=False)
     result = result[cp.argsort(image[tuple(result.T)])[::-1]]
     assert (result == expected).all()
예제 #3
0
파일: peak.py 프로젝트: grlee77/cucim
def _get_peak_mask(image, footprint, threshold, mask=None):
    """
    Return the mask containing all peak candidates above thresholds.
    """
    if footprint.size == 1 or image.size == 1:
        return image > threshold

    image_max = ndi.maximum_filter(image, footprint=footprint,
                                   mode='constant')

    out = image == image_max

    # no peak for a trivial image
    image_is_trivial = np.all(out) if mask is None else np.all(out[mask])
    if image_is_trivial:  # synchronize
        out[:] = False
        if mask is not None:
            # isolated pixels in masked area are returned as peaks
            isolated_px = cp.logical_xor(mask, ndi.binary_opening(mask))
            out[isolated_px] = True

    out &= image > threshold
    return out
예제 #4
0
 def test_reorder_labels(self):
     image = cp.asarray(np.random.uniform(size=(40, 60)))
     i, j = cp.mgrid[0:40, 0:60]
     labels = 1 + (i >= 20) + (j >= 30) * 2
     labels[labels == 4] = 5
     i, j = cp.mgrid[-3:4, -3:4]
     footprint = i * i + j * j <= 9
     expected = cp.zeros(image.shape, float)
     for imin, imax in ((0, 20), (20, 40)):
         for jmin, jmax in ((0, 30), (30, 60)):
             expected[imin:imax,
                      jmin:jmax] = ndi.maximum_filter(image[imin:imax,
                                                            jmin:jmax],
                                                      footprint=footprint)
     expected = expected == image
     with expected_warnings(["indices argument is deprecated"]):
         result = peak.peak_local_max(image,
                                      labels=labels,
                                      min_distance=1,
                                      threshold_rel=0,
                                      footprint=footprint,
                                      indices=False,
                                      exclude_border=False)
     assert (result == expected).all()
예제 #5
0
def prominent_peaks(img,
                    min_xdistance=1,
                    min_ydistance=1,
                    threshold=None,
                    num_peaks=cp.inf):
    """Return peaks with non-maximum suppression.
    Identifies most prominent features separated by certain distances.
    Non-maximum suppression with different sizes is applied separately
    in the first and second dimension of the image to identify peaks.

    Parameters
    ----------
    image : (M, N) ndarray
        Input image.
    min_xdistance : int
        Minimum distance separating features in the x dimension.
    min_ydistance : int
        Minimum distance separating features in the y dimension.
    threshold : float
        Minimum intensity of peaks. Default is `0.5 * max(image)`.
    num_peaks : int
        Maximum number of peaks. When the number of peaks exceeds `num_peaks`,
        return `num_peaks` coordinates based on peak intensity.

    Returns
    -------
    intensity, xcoords, ycoords : tuple of array
        Peak intensity values, x and y indices.

    Notes
    -----
    Modified from https://github.com/mritools/cupyimg _prominent_peaks method
    """
    t00 = time.time()
    #img = image.copy()
    rows, cols = img.shape

    if threshold is None:
        threshold = 0.5 * cp.max(img)

    ycoords_size = 2 * min_ydistance + 1
    xcoords_size = 2 * min_xdistance + 1

    t0 = time.time()
    img_max = ndi.maximum_filter(img,
                                 size=(ycoords_size, xcoords_size),
                                 mode="constant",
                                 cval=0)
    te = (time.time() - t0) * 1e3
    logger.debug(f"Maxfilter: {te:2.2f} ms")

    t0 = time.time()
    mask = img == img_max
    img *= mask
    mask = img > threshold
    te = (time.time() - t0) * 1e3
    logger.debug(f"bitbash: {te:2.2f} ms")

    t0 = time.time()
    # Find array (x,y) indexes corresponding to max pixels
    peak_idxs = cp.argwhere(mask)
    # Find corresponding maximum values
    peak_vals = img[peak_idxs[:, 0], peak_idxs[:, 1]]
    # Sort peak values low to high
    ## Sort the list of peaks by intensity, not left-right, so larger peaks
    ## in Hough space cannot be arbitrarily suppressed by smaller neighbors
    val_sort_idx = cp.argsort(peak_vals)[::-1]
    # Return (x,y) coordinates corresponding to sorted max pixels
    coords = peak_idxs[val_sort_idx]
    te = (time.time() - t0) * 1e3
    logger.debug(f"coord search: {te:2.2f} ms")

    t0 = time.time()
    img_peaks = []
    ycoords_peaks = []
    xcoords_peaks = []

    # relative coordinate grid for local neighbourhood suppression
    ycoords_ext, xcoords_ext = cp.mgrid[-min_ydistance:min_ydistance + 1,
                                        -min_xdistance:min_xdistance + 1]

    for ycoords_idx, xcoords_idx in coords:
        accum = img_max[ycoords_idx, xcoords_idx]
        if accum > threshold:
            # absolute coordinate grid for local neighbourhood suppression
            ycoords_nh = ycoords_idx + ycoords_ext
            xcoords_nh = xcoords_idx + xcoords_ext

            # no reflection for distance neighbourhood
            ycoords_in = cp.logical_and(ycoords_nh > 0, ycoords_nh < rows)
            ycoords_nh = ycoords_nh[ycoords_in]
            xcoords_nh = xcoords_nh[ycoords_in]

            # reflect xcoords and assume xcoords are continuous,
            # e.g. for angles:
            # (..., 88, 89, -90, -89, ..., 89, -90, -89, ...)
            xcoords_low = xcoords_nh < 0
            ycoords_nh[xcoords_low] = rows - ycoords_nh[xcoords_low]
            xcoords_nh[xcoords_low] += cols
            xcoords_high = xcoords_nh >= cols
            ycoords_nh[xcoords_high] = rows - ycoords_nh[xcoords_high]
            xcoords_nh[xcoords_high] -= cols

            # suppress neighbourhood
            img_max[ycoords_nh, xcoords_nh] = 0

            # add current feature to peaks
            img_peaks.append(accum)
            ycoords_peaks.append(ycoords_idx)
            xcoords_peaks.append(xcoords_idx)

    img_peaks = cp.array(img_peaks)
    ycoords_peaks = cp.array(ycoords_peaks)
    xcoords_peaks = cp.array(xcoords_peaks)
    te = (time.time() - t0) * 1e3
    logger.debug(f"crazyloop: {te:2.2f} ms")

    if num_peaks < len(img_peaks):
        idx_maxsort = cp.argsort(img_peaks)[::-1][:num_peaks]
        img_peaks = img_peaks[idx_maxsort]
        ycoords_peaks = ycoords_peaks[idx_maxsort]
        xcoords_peaks = xcoords_peaks[idx_maxsort]

    te = (time.time() - t0) * 1e3
    logger.debug(f"prominent_peaks total: {te:2.2f} ms")

    return img_peaks, xcoords_peaks, ycoords_peaks