def test_blob_overlap_3d_anisotropic(): # Two spheres with distance between centers equal to radius # One sphere is much smaller than the other so about half of it is within # the bigger sphere. s3 = math.sqrt(3) overlap = _blob_overlap(np.array([0, 0, 0, 2 / s3, 10 / s3, 10 / s3]), np.array([0, 0, 10, 0.2 / s3, 1 / s3, 1 / s3]), sigma_dim=3) assert_almost_equal(overlap, 0.48125) overlap = _blob_overlap(np.array([0, 0, 0, 2 / s3, 10 / s3, 10 / s3]), np.array([2, 0, 0, 0.2 / s3, 1 / s3, 1 / s3]), sigma_dim=3) assert_almost_equal(overlap, 0.48125)
def test_blob_overlap(): img = np.ones((256, 256), dtype=np.uint8) xs, ys = circle(100, 100, 20) img[xs, ys] = 255 xs, ys = circle(120, 100, 30) img[xs, ys] = 255 blobs = blob_doh(img, min_sigma=1, max_sigma=60, num_sigma=10, threshold=.05) assert len(blobs) == 1 r1, r2 = 7, 6 pad1, pad2 = 11, 12 blob1 = ellipsoid(r1, r1, r1) blob1 = util.pad(blob1, pad1, mode='constant') blob2 = ellipsoid(r2, r2, r2) blob2 = util.pad(blob2, [(pad2, pad2), (pad2 - 9, pad2 + 9), (pad2, pad2)], mode='constant') im3 = np.logical_or(blob1, blob2) blobs = blob_log(im3, min_sigma=2, max_sigma=10, overlap=0.1) assert len(blobs) == 1 # Two circles with distance between centers equal to radius overlap = _blob_overlap(np.array([0, 0, 10 / math.sqrt(2)]), np.array([0, 10, 10 / math.sqrt(2)])) assert_almost_equal( overlap, 1. / math.pi * (2 * math.acos(1. / 2) - math.sqrt(3) / 2.))
def elimination_overlap(blob, overlap): remove_mask = [] pts = blob[:, :2] tree = KDTree(pts, leaf_size=200) sets = tree.query_radius(pts, r=blob[:, 2].max() * np.sqrt(2)) for key, set in enumerate(sets): if len(set) > 1: blob1 = blob[key] for s in set: if s != key: blob2 = blob[s] if _blob_overlap(blob1, blob2) > overlap and blob1[2] <= blob2[2]: remove_mask += [key] break return np.delete(blob, remove_mask, axis=0)
def prune_blobs( *, blobs_array: np.ndarray, overlap: float, local_maxima: np.ndarray = None, sigma_dim: int = 1, ) -> np.ndarray: """Find non-overlapping blobs Parameters ---------- blobs_array: n x 3 where first two cols are x,y coords and third col is blob radius overlap: minimum area overlap in order to prune one of the blobs local_maxima: optional maxima values at peaks. if included then stronger maxima will be chosen on overlap sigma_dim: which column in blobs_array has the radius Returns ------- blobs_array: non-overlapping blobs """ sigma = blobs_array[:, -sigma_dim:].max() distance = 2 * sigma * math.sqrt(blobs_array.shape[1] - sigma_dim) tree = spatial.cKDTree(blobs_array[:, :-sigma_dim]) pairs = np.array(list(tree.query_pairs(distance))) if len(pairs) == 0: return blobs_array for (i, j) in pairs: blob1, blob2 = blobs_array[i], blobs_array[j] blob_overlap = _blob_overlap(blob1, blob2, sigma_dim=sigma_dim) if blob_overlap > overlap: # if local maxima then pick stronger maximum if local_maxima is not None: if local_maxima[i] > local_maxima[j]: blob2[-1] = 0 else: blob1[-1] = 0 # else take average else: blob2[-1] = (blob1[-1] + blob2[-1]) / 2 blob1[-1] = 0 return blobs_array[blobs_array[:, -1] > 0]
def prune_neighbors(spots, overlap=0.01, distance=6): """ """ # get points within distance of each other tree = cKDTree(spots[:, :-2]) pairs = np.array(list(tree.query_pairs(distance))) # tag gaussian blobs that overlap too much c = [0, 1, 2, 4] # fancy index for coordinate + small_sigma for (i, j) in pairs: if _blob_overlap(spots[i, c], spots[j, c]) > overlap: if spots[i, 3] > spots[j, 3]: spots[j, 3] = 0 else: spots[i, 3] = 0 # remove tagged spots and return as array return np.array([s for s in spots if s[3] > 0])
def test_blob_log_overlap_3d_anisotropic(): r1, r2 = 7, 6 pad1, pad2 = 11, 12 blob1 = ellipsoid(r1, r1, r1) blob1 = np.pad(blob1, pad1, mode='constant') blob2 = ellipsoid(r2, r2, r2) blob2 = np.pad(blob2, [(pad2, pad2), (pad2 - 9, pad2 + 9), (pad2, pad2)], mode='constant') im3 = np.logical_or(blob1, blob2) blobs = blob_log(im3, min_sigma=[2, 2.01, 2.005], max_sigma=10, overlap=0.1) assert len(blobs) == 1 # Two circles with distance between centers equal to radius overlap = _blob_overlap(np.array([0, 0, 10 / math.sqrt(2)]), np.array([0, 10, 10 / math.sqrt(2)])) assert_almost_equal(overlap, 1./math.pi * (2 * math.acos(1./2) - math.sqrt(3)/2.))
def test_blob_overlap(): img = np.ones((256, 256), dtype=np.uint8) xs, ys = circle(100, 100, 20) img[xs, ys] = 255 xs, ys = circle(120, 100, 30) img[xs, ys] = 255 blobs = blob_doh( img, min_sigma=1, max_sigma=60, num_sigma=10, threshold=.05) assert len(blobs) == 1 r1, r2 = 7, 6 pad1, pad2 = 11, 12 blob1 = ellipsoid(r1, r1, r1) blob1 = util.pad(blob1, pad1, mode='constant') blob2 = ellipsoid(r2, r2, r2) blob2 = util.pad(blob2, [(pad2, pad2), (pad2 - 9, pad2 + 9), (pad2, pad2)], mode='constant') im3 = np.logical_or(blob1, blob2) blobs = blob_log(im3, min_sigma=2, max_sigma=10, overlap=0.1) assert len(blobs) == 1 # Two circles with distance between centers equal to radius overlap = _blob_overlap(np.array([0, 0, 10 / math.sqrt(2)]), np.array([0, 10, 10 / math.sqrt(2)])) assert_almost_equal(overlap, 1./math.pi * (2 * math.acos(1./2) - math.sqrt(3)/2.))