def hough_line_peaks(hspace, angles, dists, min_distance=9, min_angle=10, threshold=None, num_peaks=np.inf): """Return peaks in a straight line Hough transform. Identifies most prominent lines separated by a certain angle and distance in a Hough transform. Non-maximum suppression with different sizes is applied separately in the first (distances) and second (angles) dimension of the Hough space to identify peaks. Parameters ---------- hspace : (N, M) array Hough space returned by the `hough_line` function. angles : (M,) array Angles returned by the `hough_line` function. Assumed to be continuous. (`angles[-1] - angles[0] == PI`). dists : (N, ) array Distances returned by the `hough_line` function. min_distance : int, optional Minimum distance separating lines (maximum filter size for first dimension of hough space). min_angle : int, optional Minimum angle separating lines (maximum filter size for second dimension of hough space). threshold : float, optional Minimum intensity of peaks. Default is `0.5 * max(hspace)`. num_peaks : int, optional Maximum number of peaks. When the number of peaks exceeds `num_peaks`, return `num_peaks` coordinates based on peak intensity. Returns ------- accum, angles, dists : tuple of array Peak values in Hough space, angles and distances. Examples -------- >>> from skimage.transform import hough_line, hough_line_peaks >>> from skimage.draw import line >>> img = np.zeros((15, 15), dtype=np.bool_) >>> rr, cc = line(0, 0, 14, 14) >>> img[rr, cc] = 1 >>> rr, cc = line(0, 14, 14, 0) >>> img[cc, rr] = 1 >>> hspace, angles, dists = hough_line(img) >>> hspace, angles, dists = hough_line_peaks(hspace, angles, dists) >>> len(angles) 2 """ from skimage.feature.peak import _prominent_peaks h, a, d = _prominent_peaks(hspace, min_xdistance=min_angle, min_ydistance=min_distance, threshold=threshold, num_peaks=num_peaks) return (h, angles[a], dists[d])
def test_threshold(self): image = np.zeros((15, 15)) x0, y0, i0 = (12, 8, 10) x1, y1, i1 = (2, 2, 8) x2, y2, i2 = (5, 13, 10) image[y0, x0] = i0 image[y1, x1] = i1 image[y2, x2] = i2 out = peak._prominent_peaks(image, threshold=None) assert len(out[0]) == 3 for i, x, y in zip(out[0], out[1], out[2]): self.assertTrue(i in (i0, i1, i2)) self.assertTrue(x in (x0, x1, x2)) out = peak._prominent_peaks(image, threshold=9) assert len(out[0]) == 2 for i, x, y in zip(out[0], out[1], out[2]): self.assertTrue(i in (i0, i2)) self.assertTrue(x in (x0, x2)) self.assertTrue(y in (y0, y2))
def test_threshold(self): image = np.zeros((15, 15)) x0, y0, i0 = (12, 8, 10) x1, y1, i1 = (2, 2, 8) x2, y2, i2 = (5, 13, 10) image[y0, x0] = i0 image[y1, x1] = i1 image[y2, x2] = i2 out = peak._prominent_peaks(image, threshold=None) assert len(out[0]) == 3 for i, x, y in zip (out[0], out[1], out[2]): self.assertTrue(i in (i0, i1, i2)) self.assertTrue(x in (x0, x1, x2)) out = peak._prominent_peaks(image, threshold=9) assert len(out[0]) == 2 for i, x, y in zip (out[0], out[1], out[2]): self.assertTrue(i in (i0, i2)) self.assertTrue(x in (x0, x2)) self.assertTrue(y in (y0, y2))
def test_peaks_in_contact(self): image = np.zeros((15, 15)) x0, y0, i0 = (8, 8, 1) x1, y1, i1 = (7, 7, 1) # prominent peak x2, y2, i2 = (6, 6, 1) image[y0, x0] = i0 image[y1, x1] = i1 image[y2, x2] = i2 out = peak._prominent_peaks(image, min_xdistance=3, min_ydistance=3,) assert_equal(out[0], np.array((i1,))) assert_equal(out[1], np.array((x1,))) assert_equal(out[2], np.array((y1,)))
def test_isolated_peaks(self): image = np.zeros((15, 15)) x0, y0, i0 = (12, 8, 1) x1, y1, i1 = (2, 2, 1) x2, y2, i2 = (5, 13, 1) image[y0, x0] = i0 image[y1, x1] = i1 image[y2, x2] = i2 out = peak._prominent_peaks(image) assert len(out[0]) == 3 for i, x, y in zip(out[0], out[1], out[2]): assert i in (i0, i1, i2) assert x in (x0, x1, x2) assert y in (y0, y1, y2)
def hough_circle_peaks(hspaces, radii, min_xdistance=1, min_ydistance=1, threshold=None, num_peaks=np.inf, total_num_peaks=np.inf, normalize=False): """Return peaks in a circle Hough transform. Identifies most prominent circles separated by certain distances in a Hough space. Non-maximum suppression with different sizes is applied separately in the first and second dimension of the Hough space to identify peaks. Parameters ---------- hspaces : (N, M) array Hough spaces returned by the `hough_circle` function. radii : (M,) array Radii corresponding to Hough spaces. min_xdistance : int, optional Minimum distance separating centers in the x dimension. min_ydistance : int, optional Minimum distance separating centers in the y dimension. threshold : float, optional Minimum intensity of peaks in each Hough space. Default is `0.5 * max(hspace)`. num_peaks : int, optional Maximum number of peaks in each Hough space. When the number of peaks exceeds `num_peaks`, only `num_peaks` coordinates based on peak intensity are considered for the corresponding radius. total_num_peaks : int, optional Maximum number of peaks. When the number of peaks exceeds `num_peaks`, return `num_peaks` coordinates based on peak intensity. normalize : bool, optional If True, normalize the accumulator by the radius to sort the prominent peaks. Returns ------- accum, cx, cy, rad : tuple of array Peak values in Hough space, x and y center coordinates and radii. Examples -------- >>> from skimage import transform as tf >>> from skimage import draw >>> img = np.zeros((120, 100), dtype=int) >>> radius, x_0, y_0 = (20, 99, 50) >>> y, x = draw.circle_perimeter(y_0, x_0, radius) >>> img[x, y] = 1 >>> hspaces = tf.hough_circle(img, radius) >>> accum, cx, cy, rad = hough_circle_peaks(hspaces, [radius,]) """ from skimage.feature.peak import _prominent_peaks r = [] cx = [] cy = [] accum = [] for rad, hp in zip(radii, hspaces): h_p, x_p, y_p = _prominent_peaks(hp, min_xdistance=min_xdistance, min_ydistance=min_ydistance, threshold=threshold, num_peaks=num_peaks) r.extend((rad, ) * len(h_p)) cx.extend(x_p) cy.extend(y_p) accum.extend(h_p) r = np.array(r) cx = np.array(cx) cy = np.array(cy) accum = np.array(accum) if normalize: s = np.argsort(accum / r) else: s = np.argsort(accum) if total_num_peaks != np.inf: tnp = total_num_peaks return (accum[s][::-1][:tnp], cx[s][::-1][:tnp], cy[s][::-1][:tnp], r[s][::-1][:tnp]) return (accum[s][::-1], cx[s][::-1], cy[s][::-1], r[s][::-1])
def hough_circle_peaks(hspaces, radii, min_xdistance=1, min_ydistance=1, threshold=None, num_peaks=np.inf, total_num_peaks=np.inf, normalize=False): """Return peaks in a circle Hough transform. Identifies most prominent circles separated by certain distances in a Hough space. Non-maximum suppression with different sizes is applied separately in the first and second dimension of the Hough space to identify peaks. Parameters ---------- hspaces : (N, M) array Hough spaces returned by the `hough_circle` function. radii : (M,) array Radii corresponding to Hough spaces. min_xdistance : int, optional Minimum distance separating centers in the x dimension. min_ydistance : int, optional Minimum distance separating centers in the y dimension. threshold : float, optional Minimum intensity of peaks in each Hough space. Default is `0.5 * max(hspace)`. num_peaks : int, optional Maximum number of peaks in each Hough space. When the number of peaks exceeds `num_peaks`, only `num_peaks` coordinates based on peak intensity are considered for the corresponding radius. total_num_peaks : int, optional Maximum number of peaks. When the number of peaks exceeds `num_peaks`, return `num_peaks` coordinates based on peak intensity. normalize : bool, optional If True, normalize the accumulator by the radius to sort the prominent peaks. Returns ------- accum, cx, cy, rad : tuple of array Peak values in Hough space, x and y center coordinates and radii. Examples -------- >>> from skimage import transform as tf >>> from skimage import draw >>> img = np.zeros((120, 100), dtype=int) >>> radius, x_0, y_0 = (20, 99, 50) >>> y, x = draw.circle_perimeter(y_0, x_0, radius) >>> img[x, y] = 1 >>> hspaces = tf.hough_circle(img, radius) >>> accum, cx, cy, rad = hough_circle_peaks(hspaces, [radius,]) """ from skimage.feature.peak import _prominent_peaks r = [] cx = [] cy = [] accum = [] for rad, hp in zip(radii, hspaces): h_p, x_p, y_p = _prominent_peaks(hp, min_xdistance=min_xdistance, min_ydistance=min_ydistance, threshold=threshold, num_peaks=num_peaks) r.extend((rad,)*len(h_p)) cx.extend(x_p) cy.extend(y_p) accum.extend(h_p) r = np.array(r) cx = np.array(cx) cy = np.array(cy) accum = np.array(accum) if normalize: s = np.argsort(accum / r) else: s = np.argsort(accum) if total_num_peaks != np.inf: tnp = total_num_peaks return (accum[s][::-1][:tnp], cx[s][::-1][:tnp], cy[s][::-1][:tnp], r[s][::-1][:tnp]) return (accum[s][::-1], cx[s][::-1], cy[s][::-1], r[s][::-1])