def test_background(self): x = cp.zeros((2, 3, 3), int) # fmt: off x[0] = cp.array([[1, 0, 0], [1, 0, 0], [0, 0, 0]]) x[1] = cp.array([[0, 0, 0], [0, 1, 5], [0, 0, 0]]) lnb = x.copy() lnb[0] = cp.array([[1, 2, 2], [1, 2, 2], [2, 2, 2]]) lnb[1] = cp.array([[2, 2, 2], [2, 1, 3], [2, 2, 2]]) lb = x.copy() lb[0] = cp.array([[1, BG, BG], # noqa [1, BG, BG], # noqa [BG, BG, BG]]) lb[1] = cp.array([[BG, BG, BG], [BG, 1, 2], # noqa [BG, BG, BG]]) # fmt: on assert_array_equal(label(x), lb) assert_array_equal(label(x, background=-1), lnb)
def test_return_num(self): # fmt: off x = cp.array([[1, 0, 6], [0, 0, 6], [5, 5, 5]]) # fmt: on assert_array_equal(label(x, return_num=True)[1], 3) assert_array_equal(label(x, background=-1, return_num=True)[1], 4)
def test_connectivity_1_vs_2(self): x = cp.zeros((2, 2, 2), int) x[0, 1, 1] = 1 x[1, 0, 0] = 1 label1 = x.copy() label1[1, 0, 0] = 2 assert_array_equal(label(x, connectivity=1), label1) assert_array_equal(label(x, connectivity=3), x)
def test_basic(self): assert_array_equal(label(self.x), self.labels) # Make sure data wasn't modified assert self.x[0, 2] == 3 # Check that everything works if there is no background assert_array_equal(label(self.x, background=99), self.labels_nobg) # Check that everything works if background value != 0 assert_array_equal(label(self.x, background=9), self.labels_bg_9)
def test_4_vs_8(self): # fmt: off x = cp.array([[0, 1], [1, 0]], dtype=int) assert_array_equal(label(x, connectivity=1), [[0, 1], [2, 0]]) assert_array_equal(label(x, connectivity=2), [[0, 1], [1, 0]])
def test_background(self): # fmt: off x = cp.array([[1, 0, 0], [1, 1, 5], [0, 0, 0]]) assert_array_equal(label(x), [[1, 0, 0], [1, 1, 2], [0, 0, 0]]) assert_array_equal(label(x, background=0), [[1, 0, 0], [1, 1, 2], [0, 0, 0]])
def test_random(self): x = (cp.random.rand(20, 30) * 5).astype(cp.int) labels = label(x) n = int(labels.max()) for i in range(n): values = x[labels == i] assert cp.all(values == values[0])
def test_background_one_region_center(self): x = cp.zeros((3, 3, 3), int) x[1, 1, 1] = 1 lb = cp.ones_like(x) * BG lb[1, 1, 1] = 1 assert_array_equal(label(x, connectivity=1, background=0), lb)
def test_background_one_region_center(self): # fmt: off x = cp.array([[0, 0, 0], [0, 1, 0], [0, 0, 0]]) assert_array_equal(label(x, connectivity=1, background=0), [[0, 0, 0], [0, 1, 0], [0, 0, 0]])
def test_1D(self): x = cp.array((0, 1, 2, 2, 1, 1, 0, 0)) xlen = len(x) y = cp.array((0, 1, 2, 2, 3, 3, 0, 0)) reshapes = ((xlen,), (1, xlen), (xlen, 1), (1, xlen, 1), (xlen, 1, 1), (1, 1, xlen)) for reshape in reshapes: x2 = x.reshape(reshape) labelled = label(x2) assert_array_equal(y, labelled.flatten())
def test_background_two_regions(self): # fmt: off x = cp.array([[0, 0, 6], [0, 0, 6], [5, 5, 5]]) res = label(x, background=0) assert_array_equal(res, [[0, 0, 1], [0, 0, 1], [2, 2, 2]])
def test_background_two_regions(self): x = cp.zeros((2, 3, 3), int) # fmt: off x[0] = cp.array([[0, 0, 6], [0, 0, 6], [5, 5, 5]]) x[1] = cp.array([[6, 6, 0], [5, 0, 0], [0, 0, 0]]) lb = x.copy() lb[0] = cp.array([[BG, BG, 1], [BG, BG, 1], [2, 2, 2]]) # noqa lb[1] = cp.array([[1, 1, BG], # noqa [2, BG, BG], # noqa [BG, BG, BG]]) # fmt: on res = label(x, background=0) assert_array_equal(res, lb)
def test_diag(self): # fmt: off x = cp.array([[0, 0, 1], [0, 1, 0], [1, 0, 0]]) assert_array_equal(label(x), x)
def test_diag(self): x = cp.zeros((3, 3, 3), int) x[0, 2, 2] = 1 x[1, 1, 1] = 1 x[2, 0, 0] = 1 assert_array_equal(label(x), x)
def test_basic(self): labels = label(self.x) assert_array_equal(labels, self.labels) assert self.x[0, 0, 2] == 2, "Data was modified!"
def _prominent_peaks(image, min_xdistance=1, min_ydistance=1, threshold=None, num_peaks=np.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. """ img = image.copy() rows, cols = img.shape if threshold is None: threshold = 0.5 * np.max(img) ycoords_size = 2 * min_ydistance + 1 xcoords_size = 2 * min_xdistance + 1 img_max = ndi.maximum_filter1d(img, size=ycoords_size, axis=0, mode='constant', cval=0) img_max = ndi.maximum_filter1d(img_max, size=xcoords_size, axis=1, mode='constant', cval=0) mask = (img == img_max) img *= mask img_t = img > threshold label_img = measure.label(img_t) props = measure.regionprops(label_img, img_max) # Sort the list of peaks by intensity, not left-right, so larger peaks # in Hough space cannot be arbitrarily suppressed by smaller neighbors props = sorted(props, key=lambda x: x.max_intensity)[::-1] coords = cp.asarray([np.round(p.centroid) for p in props], dtype=int) 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) 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] return img_peaks, xcoords_peaks, ycoords_peaks