def test_num_peaks(self): image = np.zeros((7, 7), dtype=np.uint8) image[1, 1] = 10 image[1, 3] = 11 image[1, 5] = 12 image[3, 5] = 8 image[5, 3] = 7 self.assertEqual( len(peak_local_max(image, min_distance=1, threshold_abs=0)), 5) peaks_limited = peak_local_max(image, min_distance=1, threshold_abs=0, num_peaks=2) self.assertEqual(len(peaks_limited), 2) self.assertIn((1, 3), peaks_limited) self.assertIn((1, 5), peaks_limited) peaks_limited = peak_local_max(image, min_distance=1, threshold_abs=0, num_peaks=4) self.assertEqual(len(peaks_limited), 4) self.assertIn((1, 3), peaks_limited) self.assertIn((1, 5), peaks_limited) self.assertIn((1, 1), peaks_limited) self.assertIn((3, 5), peaks_limited)
def test_sorted_peaks(self): image = np.zeros((5, 5), dtype=np.uint8) image[1, 1] = 20 image[3, 3] = 10 peaks = peak_local_max(image, min_distance=1) self.assertEqual(peaks.tolist(), [[1, 1], [3, 3]]) image = np.zeros((3, 10)) image[1, (1, 3, 5, 7)] = (1, 2, 3, 4) peaks = peak_local_max(image, min_distance=1) self.assertEqual(peaks.tolist(), [[1, 7], [1, 5], [1, 3], [1, 1]])
def test_threshold_rel_default(self): image = np.ones((5, 5)) image[2, 2] = 1 self.assertEqual(len(peak_local_max(image)), 0) image[2, 2] = 2 np.testing.assert_equal(peak_local_max(image), [[2, 2]]) image[2, 2] = 0 with self.assertWarnsRegex(RuntimeWarning, "When min_distance < 1"): self.assertEqual(len(peak_local_max(image, min_distance=0)), image.size - 1)
def test_num_peaks3D(self): # Issue 1354: the old code only hold for 2D arrays # and this code would die with IndexError image = np.zeros((10, 10, 100)) image[5, 5, ::5] = np.arange(20) peaks_limited = peak_local_max(image, min_distance=1, num_peaks=2) self.assertEqual(len(peaks_limited), 2)
def test_absolute_threshold(self): image = np.zeros((5, 5), dtype=np.uint8) image[1, 1] = 10 image[3, 3] = 20 peaks = peak_local_max(image, min_distance=1, threshold_abs=10) self.assertEqual(len(peaks), 1) np.testing.assert_array_almost_equal(peaks, [(3, 3)])
def test_exclude_border(self): for indices in itertools.product(range(5), range(5)): with self.subTest(indices=indices): image = np.zeros((5, 5)) image[indices] = 1 # exclude_border = False, means it will always be found. self.assertEqual( len(peak_local_max(image, exclude_border=False)), 1) # exclude_border = 0, means it will always be found. self.assertEqual(len(peak_local_max(image, exclude_border=0)), 1) # exclude_border = True, min_distance=1 means it will be found # unless it's on the edge. if indices[0] in (0, 4) or indices[1] in (0, 4): expected_peaks = 0 else: expected_peaks = 1 self.assertEqual( len( peak_local_max(image, min_distance=1, exclude_border=True)), expected_peaks, ) # exclude_border = (1, 0) means it will be found unless it's on # the edge of the first dimension. if indices[0] in (0, 4): expected_peaks = 0 else: expected_peaks = 1 self.assertEqual( len(peak_local_max(image, exclude_border=(1, 0))), expected_peaks) # exclude_border = (0, 1) means it will be found unless it's on # the edge of the second dimension. if indices[1] in (0, 4): expected_peaks = 0 else: expected_peaks = 1 self.assertEqual( len(peak_local_max(image, exclude_border=(0, 1))), expected_peaks)
def find_spot_positions( image: numpy.ndarray, sigma: float, threshold_abs: Optional[float] = None, threshold_rel: Optional[float] = None, num_spots: Optional[int] = None, ) -> numpy.ndarray: """ Find the center coordinates of spots with the highest intensity in an image. Parameters ---------- image : ndarray The input image. sigma : float Expected size of the spots. Assuming the spots are Gaussian shaped, this is the standard deviation. threshold_abs : float, optional Minimum intensity of peaks. By default, the absolute threshold is the minimum intensity of the image. threshold_rel : float, optional If provided, apply a threshold on the minimum intensity of peaks, calculated as `max(image) * threshold_rel`. num_spots : int, optional Maximum number of spots. When the number of spots exceeds `num_spots`, return `num_spots` peaks based on highest spot intensity. Returns ------- refined_position : ndarray A 2-dimensional array of shape `(N, 2)` containing the coordinates of the maxima. """ size = int(round(3 * sigma)) min_distance = 2 * size filtered = bandpass_filter(image, sigma, min_distance) coordinates = peak_local_max( filtered, min_distance=min_distance, threshold_abs=threshold_abs, threshold_rel=threshold_rel, num_peaks=num_spots, p_norm=2, ) # Improve coordinate estimate using radial symmetry center. refined_coordinates = numpy.empty_like(coordinates, dtype=float) for idx, ji in enumerate(coordinates): subimg = _get_subimage(filtered, ji, size) rsc = radial_symmetry_center(subimg, smoothing=False) delta = numpy.subtract(rsc, size) refined_coordinates[idx] = ji + delta return refined_coordinates
def test_empty_non2d_indices(self): image = np.zeros((10, 10, 10)) result = peak_local_max( image, footprint=np.ones((3, 3, 3), bool), min_distance=1, threshold_rel=0, exclude_border=False, ) self.assertEqual(result.shape, (0, image.ndim))
def test_noisy_peaks(self): peak_locations = [(7, 7), (7, 13), (13, 7), (13, 13)] # image with noise of amplitude 0.8 and peaks of amplitude 1 image = 0.8 * np.random.rand(20, 20) for r, c in peak_locations: image[r, c] = 1 peaks_detected = peak_local_max(image, min_distance=5) self.assertEqual(len(peaks_detected), len(peak_locations)) for loc in peaks_detected: self.assertIn(tuple(loc), peak_locations)
def test_4D(self): image = np.zeros((30, 30, 30, 30)) image[15, 15, 15, 15] = 1 image[5, 5, 5, 5] = 1 np.testing.assert_equal( peak_local_max(image, min_distance=10, threshold_rel=0), [[15, 15, 15, 15]]) np.testing.assert_equal( peak_local_max(image, min_distance=6, threshold_rel=0), [[15, 15, 15, 15]]) self.assertEqual( sorted( peak_local_max(image, min_distance=10, threshold_rel=0, exclude_border=False).tolist()), [[5, 5, 5, 5], [15, 15, 15, 15]], ) self.assertEqual( sorted( peak_local_max(image, min_distance=5, threshold_rel=0).tolist()), [[5, 5, 5, 5], [15, 15, 15, 15]], )
def test_flat_peak(self): image = np.zeros((5, 5), dtype=np.uint8) image[1:3, 1:3] = 10 peaks = peak_local_max(image, min_distance=1) self.assertEqual(len(peaks), 4)
def test_constant_image(self): image = np.full((20, 20), 128, dtype=np.uint8) peaks = peak_local_max(image, min_distance=1) self.assertEqual(len(peaks), 0)
def test_trivial_case(self): trivial = np.zeros((25, 25)) peak_indices = peak_local_max(trivial, min_distance=1) self.assertIsInstance(peak_indices, np.ndarray) self.assertEqual(peak_indices.size, 0)