From 12d2cd6855c473e3eb578a64164c546e6bfa80e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Boulogne?= Date: Fri, 22 Mar 2013 22:07:39 +0100 Subject: [PATCH 01/11] be consistant with python implementation --- skimage/transform/_hough_transform.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skimage/transform/_hough_transform.pyx b/skimage/transform/_hough_transform.pyx index 2b1acc7c..b6ff2bb7 100644 --- a/skimage/transform/_hough_transform.pyx +++ b/skimage/transform/_hough_transform.pyx @@ -98,7 +98,7 @@ def _hough(cnp.ndarray img, cnp.ndarray[ndim=1, dtype=cnp.double_t] theta=None): cdef cnp.ndarray[ndim=1, dtype=cnp.double_t] stheta if theta is None: - theta = np.linspace(PI_2, NEG_PI_2, 180) + theta = np.linspace(NEG_PI_2, PI_2, 180) ctheta = np.cos(theta) stheta = np.sin(theta) From 22158fc9da297b383465dd0993af3a336b56cb14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Boulogne?= Date: Fri, 22 Mar 2013 23:11:29 +0100 Subject: [PATCH 02/11] improve unittests --- .../transform/tests/test_hough_transform.py | 34 +++++++++++++------ 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/skimage/transform/tests/test_hough_transform.py b/skimage/transform/tests/test_hough_transform.py index 00427332..2bf7b30c 100644 --- a/skimage/transform/tests/test_hough_transform.py +++ b/skimage/transform/tests/test_hough_transform.py @@ -4,7 +4,7 @@ from numpy.testing import * import skimage.transform as tf import skimage.transform.hough_transform as ht from skimage.transform import probabilistic_hough -from skimage.draw import circle_perimeter +from skimage.draw import circle_perimeter, line def append_desc(func, description): @@ -16,11 +16,11 @@ def append_desc(func, description): return func -def test_hough(): +def test_hough_line(): # Generate a test image - img = np.zeros((100, 100), dtype=int) - for i in range(25, 75): - img[100 - i, i] = 1 + img = np.zeros((100, 150), dtype=int) + rr, cc = line(60, 130, 80, 10) + img[rr, cc] = 1 out, angles, d = tf.hough_line(img) @@ -28,11 +28,11 @@ def test_hough(): dist = d[y[0]] theta = angles[x[0]] - assert_equal(dist > 70, dist < 72) - assert_equal(theta > 0.78, theta < 0.79) + assert_almost_equal(dist, 80.723, 1) + assert_almost_equal(theta, 1.41, 1) -def test_hough_angles(): +def test_hough_line_angles(): img = np.zeros((10, 10)) img[0, 0] = 1 @@ -44,8 +44,8 @@ def test_hough_angles(): def test_py_hough(): ht._hough, fast_hough = ht._py_hough, ht._hough - yield append_desc(test_hough, '_python') - yield append_desc(test_hough_angles, '_python') + yield append_desc(test_hough_line, '_python') + yield append_desc(test_hough_line_angles, '_python') tf._hough = fast_hough @@ -71,6 +71,20 @@ def test_probabilistic_hough(): assert([(25, 25), (74, 74)] in sorted_lines) +def test_hough_peaks(): + img = np.zeros((100, 150), dtype=int) + rr, cc = line(60, 130, 80, 10) + img[rr, cc] = 1 + + out, angles, d = tf.hough_line(img) + + out, theta, dist = tf.hough_peaks(out, angles, d) + + assert_equal(len(dist), 1) + assert_almost_equal(dist[0], 80.723, 1) + assert_almost_equal(theta[0], 1.41, 1) + + def test_hough_peaks_dist(): img = np.zeros((100, 100), dtype=np.bool_) img[:, 30] = True From f18be31822bf6e9cb22cac8374239d64ffc480d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Boulogne?= Date: Fri, 22 Mar 2013 23:12:05 +0100 Subject: [PATCH 03/11] Fix and improve example --- doc/source/plots/hough_tf.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/doc/source/plots/hough_tf.py b/doc/source/plots/hough_tf.py index ea2fc4bb..df1dcd31 100644 --- a/doc/source/plots/hough_tf.py +++ b/doc/source/plots/hough_tf.py @@ -2,13 +2,14 @@ import numpy as np import matplotlib.pyplot as plt from skimage.transform import hough_line +from skimage.draw import line img = np.zeros((100, 150), dtype=bool) img[30, :] = 1 img[:, 65] = 1 img[35:45, 35:50] = 1 -for i in range(90): - img[i, i] = 1 +rr, cc = line(60, 130, 80, 10) +img[rr, cc] = 1 img += np.random.random(img.shape) > 0.95 out, angles, d = hough_line(img) @@ -20,8 +21,8 @@ plt.title('Input image') plt.subplot(1, 2, 2) plt.imshow(out, cmap=plt.cm.bone, - extent=(np.rad2deg(angles[0]), np.rad2deg(angles[-1]), - d[0], d[-1])) + extent=(np.rad2deg(angles[-1]), np.rad2deg(angles[0]), + d[-1], d[0])) plt.title('Hough transform') plt.xlabel('Angle (degree)') plt.ylabel('Distance (pixel)') From 33060e334386dde0a696914cfe27a0b36b032d65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Boulogne?= Date: Fri, 22 Mar 2013 23:12:18 +0100 Subject: [PATCH 04/11] Fix docstring --- skimage/transform/hough_transform.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skimage/transform/hough_transform.py b/skimage/transform/hough_transform.py index f112a025..079ce54e 100644 --- a/skimage/transform/hough_transform.py +++ b/skimage/transform/hough_transform.py @@ -127,7 +127,7 @@ def hough_line(img, theta=None): Notes ----- The origin is the top left corner of the original image. - The angle is counted clockwise from 9 o'clock. + X and Y axis are horizontal and vertical edges respectively. The distance is the minimal algebraic distance from this origin to the line. Examples From 29b91ca01d2b7195063fc1c354b683ad97af623a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Boulogne?= Date: Fri, 22 Mar 2013 23:16:13 +0100 Subject: [PATCH 05/11] minor doc improv. --- skimage/transform/hough_transform.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skimage/transform/hough_transform.py b/skimage/transform/hough_transform.py index 079ce54e..1c36e799 100644 --- a/skimage/transform/hough_transform.py +++ b/skimage/transform/hough_transform.py @@ -128,7 +128,7 @@ def hough_line(img, theta=None): ----- The origin is the top left corner of the original image. X and Y axis are horizontal and vertical edges respectively. - The distance is the minimal algebraic distance from this origin to the line. + The distance is the minimal algebraic distance from the origin to the detected line. Examples -------- From caee53c83c35fa0b82f7a897807e540d2f594375 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Boulogne?= Date: Fri, 22 Mar 2013 23:31:06 +0100 Subject: [PATCH 06/11] doc, minor improv. --- skimage/transform/hough_transform.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/skimage/transform/hough_transform.py b/skimage/transform/hough_transform.py index 1c36e799..bd5e3a2b 100644 --- a/skimage/transform/hough_transform.py +++ b/skimage/transform/hough_transform.py @@ -120,7 +120,7 @@ def hough_line(img, theta=None): H : 2-D ndarray of uint64 Hough transform accumulator. theta : ndarray - Angles at which the transform was computed. + Angles at which the transform was computed, in radians. distances : ndarray Distance values. @@ -186,8 +186,7 @@ def hough_peaks(hspace, angles, dists, min_distance=10, min_angle=10, 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`). + Angles returned by the `hough_line` function. Assumed to be continuous. dists : (N, ) array Distances returned by the `hough_line` function. min_distance : int From a68434b330b72173cb063273d98f87e0f8690c7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Boulogne?= Date: Sun, 24 Mar 2013 15:11:55 +0100 Subject: [PATCH 07/11] big clean-up! --- skimage/transform/__init__.py | 3 + skimage/transform/_hough_transform.pyx | 77 +++++++- skimage/transform/hough_transform.py | 172 ++---------------- .../transform/tests/test_hough_transform.py | 9 - 4 files changed, 90 insertions(+), 171 deletions(-) diff --git a/skimage/transform/__init__.py b/skimage/transform/__init__.py index 089487ee..efe8f0b4 100644 --- a/skimage/transform/__init__.py +++ b/skimage/transform/__init__.py @@ -1,3 +1,6 @@ +from ._hough_transform import hough_circle, + hough_line, + probabilistic_hough_line from .hough_transform import * from .radon_transform import * from .finite_radon_transform import * diff --git a/skimage/transform/_hough_transform.pyx b/skimage/transform/_hough_transform.pyx index b6ff2bb7..a8dabcfc 100644 --- a/skimage/transform/_hough_transform.pyx +++ b/skimage/transform/_hough_transform.pyx @@ -20,7 +20,7 @@ cdef inline Py_ssize_t round(double r): return ((r + 0.5) if (r > 0.0) else (r - 0.5)) -def _hough_circle(cnp.ndarray img, +def hough_circle(cnp.ndarray img, cnp.ndarray[ndim=1, dtype=cnp.intp_t] radius, char normalize=True): """Perform a circular Hough transform. @@ -88,8 +88,51 @@ def _hough_circle(cnp.ndarray img, return acc -def _hough(cnp.ndarray img, cnp.ndarray[ndim=1, dtype=cnp.double_t] theta=None): +def hough_line(cnp.ndarray img, cnp.ndarray[ndim=1, dtype=cnp.double_t] theta=None): + """Perform a straight line Hough transform. + Parameters + ---------- + img : (M, N) ndarray + Input image with nonzero values representing edges. + theta : 1D ndarray of double + Angles at which to compute the transform, in radians. + Defaults to -pi/2 .. pi/2 + + Returns + ------- + H : 2-D ndarray of uint64 + Hough transform accumulator. + theta : ndarray + Angles at which the transform was computed, in radians. + distances : ndarray + Distance values. + + Notes + ----- + The origin is the top left corner of the original image. + X and Y axis are horizontal and vertical edges respectively. + The distance is the minimal algebraic distance from the origin to the detected line. + + Examples + -------- + Generate a test image: + + >>> img = np.zeros((100, 150), dtype=bool) + >>> img[30, :] = 1 + >>> img[:, 65] = 1 + >>> img[35:45, 35:50] = 1 + >>> for i in range(90): + ... img[i, i] = 1 + >>> img += np.random.random(img.shape) > 0.95 + + Apply the Hough transform: + + >>> out, angles, d = hough_line(img) + + .. plot:: hough_tf.py + + """ if img.ndim != 2: raise ValueError('The input image must be 2D.') @@ -131,10 +174,38 @@ def _hough(cnp.ndarray img, cnp.ndarray[ndim=1, dtype=cnp.double_t] theta=None): return accum, theta, bins -def _probabilistic_hough(cnp.ndarray img, int value_threshold, +def probabilistic_hough_line(cnp.ndarray img, int value_threshold, int line_length, int line_gap, cnp.ndarray[ndim=1, dtype=cnp.double_t] theta=None): + """Return lines from a progressive probabilistic line Hough transform. + Parameters + ---------- + img : (M, N) ndarray + Input image with nonzero values representing edges. + threshold : int + Threshold + line_length : int, optional (default 50) + Minimum accepted length of detected lines. + Increase the parameter to extract longer lines. + line_gap : int, optional, (default 10) + Maximum gap between pixels to still form a line. + Increase the parameter to merge broken lines more aggresively. + theta : 1D ndarray, dtype=double, optional, default (-pi/2 .. pi/2) + Angles at which to compute the transform, in radians. + + Returns + ------- + lines : list + List of lines identified, lines in format ((x0, y0), (x1, y0)), indicating + line start and end. + + References + ---------- + .. [1] C. Galamhos, J. Matas and J. Kittler, "Progressive probabilistic + Hough transform for line detection", in IEEE Computer Society + Conference on Computer Vision and Pattern Recognition, 1999. + """ if img.ndim != 2: raise ValueError('The input image must be 2D.') diff --git a/skimage/transform/hough_transform.py b/skimage/transform/hough_transform.py index bd5e3a2b..0c1747d4 100644 --- a/skimage/transform/hough_transform.py +++ b/skimage/transform/hough_transform.py @@ -1,179 +1,32 @@ -__all__ = ['hough', 'hough_line', 'hough_circle', 'hough_peaks', 'probabilistic_hough'] +__all__ = ['hough_peaks'] from itertools import izip as zip import numpy as np from scipy import ndimage -from ._hough_transform import _probabilistic_hough from skimage import measure, morphology -def _hough(img, theta=None): - if img.ndim != 2: - raise ValueError('The input image must be 2-D') - - if theta is None: - theta = np.linspace(-np.pi / 2, np.pi / 2, 180) - - # compute the vertical bins (the distances) - d = np.ceil(np.hypot(*img.shape)) - nr_bins = 2 * d - bins = np.linspace(-d, d, nr_bins) - - # allocate the output image - out = np.zeros((nr_bins, len(theta)), dtype=np.uint64) - - # precompute the sin and cos of the angles - cos_theta = np.cos(theta) - sin_theta = np.sin(theta) - - # find the indices of the non-zero values in - # the input image - y, x = np.nonzero(img) - - # x and y can be large, so we can't just broadcast to 2D - # arrays as we may run out of memory. Instead we process - # one vertical slice at a time. - for i, (cT, sT) in enumerate(zip(cos_theta, sin_theta)): - - # compute the base distances - distances = x * cT + y * sT - - # round the distances to the nearest integer - # and shift them to a nonzero bin - shifted = np.round(distances) - bins[0] - - # cast the shifted values to ints to use as indices - indices = shifted.astype(np.int) - - # use bin count to accumulate the coefficients - bincount = np.bincount(indices) - - # finally assign the proper values to the out array - out[:len(bincount), i] = bincount - - return out, theta, bins - -_py_hough = _hough - -# try to import and use the faster Cython version if it exists -try: - from ._hough_transform import _hough -except ImportError: - pass - - -def probabilistic_hough(img, threshold=10, line_length=50, line_gap=10, - theta=None): - """Return lines from a progressive probabilistic line Hough transform. - - Parameters - ---------- - img : (M, N) ndarray - Input image with nonzero values representing edges. - threshold : int - Threshold - line_length : int, optional (default 50) - Minimum accepted length of detected lines. - Increase the parameter to extract longer lines. - line_gap : int, optional, (default 10) - Maximum gap between pixels to still form a line. - Increase the parameter to merge broken lines more aggresively. - theta : 1D ndarray, dtype=double, optional, default (-pi/2 .. pi/2) - Angles at which to compute the transform, in radians. - - Returns - ------- - lines : list - List of lines identified, lines in format ((x0, y0), (x1, y0)), indicating - line start and end. - - References - ---------- - .. [1] C. Galamhos, J. Matas and J. Kittler, "Progressive probabilistic - Hough transform for line detection", in IEEE Computer Society - Conference on Computer Vision and Pattern Recognition, 1999. - """ - return _probabilistic_hough(img, threshold, line_length, line_gap, theta) - +from ._hough_transform import hough_line, probabilistic_hough_line from skimage._shared.utils import deprecated @deprecated('hough_line') def hough(img, theta=None): return hough_line(img, theta) -from ._hough_transform import _hough_circle - -def hough_line(img, theta=None): - """Perform a straight line Hough transform. - - Parameters - ---------- - img : (M, N) ndarray - Input image with nonzero values representing edges. - theta : 1D ndarray of double - Angles at which to compute the transform, in radians. - Defaults to -pi/2 .. pi/2 - - Returns - ------- - H : 2-D ndarray of uint64 - Hough transform accumulator. - theta : ndarray - Angles at which the transform was computed, in radians. - distances : ndarray - Distance values. - - Notes - ----- - The origin is the top left corner of the original image. - X and Y axis are horizontal and vertical edges respectively. - The distance is the minimal algebraic distance from the origin to the detected line. - - Examples - -------- - Generate a test image: - - >>> img = np.zeros((100, 150), dtype=bool) - >>> img[30, :] = 1 - >>> img[:, 65] = 1 - >>> img[35:45, 35:50] = 1 - >>> for i in range(90): - ... img[i, i] = 1 - >>> img += np.random.random(img.shape) > 0.95 - - Apply the Hough transform: - - >>> out, angles, d = hough_line(img) - - .. plot:: hough_tf.py - - """ - return _hough(img, theta) - -def hough_circle(img, radius, normalize=True): - """Perform a circular Hough transform. - - Parameters - ---------- - img : (M, N) ndarray - Input image with nonzero values representing edges. - radius : ndarray - Radii at which to compute the Hough transform. - normalize : boolean, optional - Normalize the accumulator with the number - of pixels used to draw the radius - - Returns - ------- - H : 3D ndarray (radius index, (M, N) ndarray) - Hough transform accumulator for each radius - - """ - return _hough_circle(img, radius.astype(np.intp), normalize) +@deprecated('probabilistic_hough') +def probabilistic_hough(img, threshold=10, line_length=50, line_gap=10, + theta=None): + return probabilistic_hough_line(img, threshold, line_length, line_gap, theta) +@deprecated('hough_peaks') def hough_peaks(hspace, angles, dists, min_distance=10, min_angle=10, threshold=None, num_peaks=np.inf): + return hough_line_peaks(hspace, angles, dists, min_distance, min_angle, + threshold, num_peaks) + +def hough_line_peaks(hspace, angles, dists, min_distance=10, min_angle=10, + threshold=None, num_peaks=np.inf): """Return peaks in hough transform. Identifies most prominent lines separated by a certain angle and distance in @@ -187,6 +40,7 @@ def hough_peaks(hspace, angles, dists, min_distance=10, min_angle=10, 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 diff --git a/skimage/transform/tests/test_hough_transform.py b/skimage/transform/tests/test_hough_transform.py index 2bf7b30c..5e175945 100644 --- a/skimage/transform/tests/test_hough_transform.py +++ b/skimage/transform/tests/test_hough_transform.py @@ -41,15 +41,6 @@ def test_hough_line_angles(): assert_equal(len(angles), 10) -def test_py_hough(): - ht._hough, fast_hough = ht._py_hough, ht._hough - - yield append_desc(test_hough_line, '_python') - yield append_desc(test_hough_line_angles, '_python') - - tf._hough = fast_hough - - def test_probabilistic_hough(): # Generate a test image img = np.zeros((100, 100), dtype=int) From 42e872f926bb4cf8050d91560a2e9180f5ada79f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Boulogne?= Date: Sun, 24 Mar 2013 15:22:42 +0100 Subject: [PATCH 08/11] fix names --- skimage/transform/__init__.py | 4 +-- skimage/transform/hough_transform.py | 2 +- .../transform/tests/test_hough_transform.py | 33 +++++++++---------- 3 files changed, 19 insertions(+), 20 deletions(-) diff --git a/skimage/transform/__init__.py b/skimage/transform/__init__.py index efe8f0b4..92858010 100644 --- a/skimage/transform/__init__.py +++ b/skimage/transform/__init__.py @@ -1,6 +1,6 @@ -from ._hough_transform import hough_circle, +from ._hough_transform import (hough_circle, hough_line, - probabilistic_hough_line + probabilistic_hough_line) from .hough_transform import * from .radon_transform import * from .finite_radon_transform import * diff --git a/skimage/transform/hough_transform.py b/skimage/transform/hough_transform.py index 0c1747d4..8e680c94 100644 --- a/skimage/transform/hough_transform.py +++ b/skimage/transform/hough_transform.py @@ -1,4 +1,4 @@ -__all__ = ['hough_peaks'] +__all__ = ['hough_line_peaks'] from itertools import izip as zip diff --git a/skimage/transform/tests/test_hough_transform.py b/skimage/transform/tests/test_hough_transform.py index 5e175945..2a2f57d2 100644 --- a/skimage/transform/tests/test_hough_transform.py +++ b/skimage/transform/tests/test_hough_transform.py @@ -3,7 +3,6 @@ from numpy.testing import * import skimage.transform as tf import skimage.transform.hough_transform as ht -from skimage.transform import probabilistic_hough from skimage.draw import circle_perimeter, line @@ -50,7 +49,7 @@ def test_probabilistic_hough(): # decrease default theta sampling because similar orientations may confuse # as mentioned in article of Galambos et al theta = np.linspace(0, np.pi, 45) - lines = probabilistic_hough(img, theta=theta, threshold=10, line_length=10, + lines = tf.probabilistic_hough_line(img, theta=theta, threshold=10, line_length=10, line_gap=1) # sort the lines according to the x-axis sorted_lines = [] @@ -62,59 +61,59 @@ def test_probabilistic_hough(): assert([(25, 25), (74, 74)] in sorted_lines) -def test_hough_peaks(): +def test_hough_line_peaks(): img = np.zeros((100, 150), dtype=int) rr, cc = line(60, 130, 80, 10) img[rr, cc] = 1 out, angles, d = tf.hough_line(img) - out, theta, dist = tf.hough_peaks(out, angles, d) + out, theta, dist = tf.hough_line_peaks(out, angles, d) assert_equal(len(dist), 1) assert_almost_equal(dist[0], 80.723, 1) assert_almost_equal(theta[0], 1.41, 1) -def test_hough_peaks_dist(): +def test_hough_line_peaks_dist(): img = np.zeros((100, 100), dtype=np.bool_) img[:, 30] = True img[:, 40] = True hspace, angles, dists = tf.hough_line(img) - assert len(tf.hough_peaks(hspace, angles, dists, min_distance=5)[0]) == 2 - assert len(tf.hough_peaks(hspace, angles, dists, min_distance=15)[0]) == 1 + assert len(tf.hough_line_peaks(hspace, angles, dists, min_distance=5)[0]) == 2 + assert len(tf.hough_line_peaks(hspace, angles, dists, min_distance=15)[0]) == 1 -def test_hough_peaks_angle(): +def test_hough_line_peaks_angle(): img = np.zeros((100, 100), dtype=np.bool_) img[:, 0] = True img[0, :] = True hspace, angles, dists = tf.hough_line(img) - assert len(tf.hough_peaks(hspace, angles, dists, min_angle=45)[0]) == 2 - assert len(tf.hough_peaks(hspace, angles, dists, min_angle=90)[0]) == 1 + assert len(tf.hough_line_peaks(hspace, angles, dists, min_angle=45)[0]) == 2 + assert len(tf.hough_line_peaks(hspace, angles, dists, min_angle=90)[0]) == 1 theta = np.linspace(0, np.pi, 100) hspace, angles, dists = tf.hough_line(img, theta) - assert len(tf.hough_peaks(hspace, angles, dists, min_angle=45)[0]) == 2 - assert len(tf.hough_peaks(hspace, angles, dists, min_angle=90)[0]) == 1 + assert len(tf.hough_line_peaks(hspace, angles, dists, min_angle=45)[0]) == 2 + assert len(tf.hough_line_peaks(hspace, angles, dists, min_angle=90)[0]) == 1 theta = np.linspace(np.pi / 3, 4. / 3 * np.pi, 100) hspace, angles, dists = tf.hough_line(img, theta) - assert len(tf.hough_peaks(hspace, angles, dists, min_angle=45)[0]) == 2 - assert len(tf.hough_peaks(hspace, angles, dists, min_angle=90)[0]) == 1 + assert len(tf.hough_line_peaks(hspace, angles, dists, min_angle=45)[0]) == 2 + assert len(tf.hough_line_peaks(hspace, angles, dists, min_angle=90)[0]) == 1 -def test_hough_peaks_num(): +def test_hough_line_peaks_num(): img = np.zeros((100, 100), dtype=np.bool_) img[:, 30] = True img[:, 40] = True hspace, angles, dists = tf.hough_line(img) - assert len(tf.hough_peaks(hspace, angles, dists, min_distance=0, + assert len(tf.hough_line_peaks(hspace, angles, dists, min_distance=0, min_angle=0, num_peaks=1)[0]) == 1 -def test_houghcircle(): +def test_hough_circle(): # Prepare picture img = np.zeros((120, 100), dtype=int) radius = 20 From 0e4d10775483ec183b31ab02a0778f341b35da59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Boulogne?= Date: Sun, 24 Mar 2013 15:39:07 +0100 Subject: [PATCH 09/11] fix signature --- skimage/transform/_hough_transform.pyx | 10 +++++----- skimage/transform/hough_transform.py | 3 ++- skimage/transform/tests/test_hough_transform.py | 4 ++-- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/skimage/transform/_hough_transform.pyx b/skimage/transform/_hough_transform.pyx index a8dabcfc..2d5d0230 100644 --- a/skimage/transform/_hough_transform.pyx +++ b/skimage/transform/_hough_transform.pyx @@ -174,8 +174,8 @@ def hough_line(cnp.ndarray img, cnp.ndarray[ndim=1, dtype=cnp.double_t] theta=No return accum, theta, bins -def probabilistic_hough_line(cnp.ndarray img, int value_threshold, - int line_length, int line_gap, +def probabilistic_hough_line(cnp.ndarray img, int threshold=10, + int line_length=50, int line_gap=10, cnp.ndarray[ndim=1, dtype=cnp.double_t] theta=None): """Return lines from a progressive probabilistic line Hough transform. @@ -183,7 +183,7 @@ def probabilistic_hough_line(cnp.ndarray img, int value_threshold, ---------- img : (M, N) ndarray Input image with nonzero values representing edges. - threshold : int + threshold : int, optional (default 10) Threshold line_length : int, optional (default 50) Minimum accepted length of detected lines. @@ -267,7 +267,7 @@ def probabilistic_hough_line(cnp.ndarray img, int value_threshold, continue value = 0 - max_value = value_threshold - 1 + max_value = threshold - 1 max_theta = -1 # apply hough transform on point @@ -278,7 +278,7 @@ def probabilistic_hough_line(cnp.ndarray img, int value_threshold, if value > max_value: max_value = value max_theta = j - if max_value < value_threshold: + if max_value < threshold: continue # from the random point walk in opposite directions and find line diff --git a/skimage/transform/hough_transform.py b/skimage/transform/hough_transform.py index 8e680c94..1b356127 100644 --- a/skimage/transform/hough_transform.py +++ b/skimage/transform/hough_transform.py @@ -17,7 +17,8 @@ def hough(img, theta=None): @deprecated('probabilistic_hough') def probabilistic_hough(img, threshold=10, line_length=50, line_gap=10, theta=None): - return probabilistic_hough_line(img, threshold, line_length, line_gap, theta) + return probabilistic_hough_line(img, threshold=threshold, + line_length=line_length, line_gap=line_gap, theta=theta) @deprecated('hough_peaks') def hough_peaks(hspace, angles, dists, min_distance=10, min_angle=10, diff --git a/skimage/transform/tests/test_hough_transform.py b/skimage/transform/tests/test_hough_transform.py index 2a2f57d2..395e6faa 100644 --- a/skimage/transform/tests/test_hough_transform.py +++ b/skimage/transform/tests/test_hough_transform.py @@ -49,8 +49,8 @@ def test_probabilistic_hough(): # decrease default theta sampling because similar orientations may confuse # as mentioned in article of Galambos et al theta = np.linspace(0, np.pi, 45) - lines = tf.probabilistic_hough_line(img, theta=theta, threshold=10, line_length=10, - line_gap=1) + lines = tf.probabilistic_hough_line(img, threshold=10, line_length=10, + line_gap=1, theta=theta) # sort the lines according to the x-axis sorted_lines = [] for line in lines: From 96d0e677dd1c5be440be7417be7506c87c5c9325 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Boulogne?= Date: Sun, 24 Mar 2013 15:52:14 +0100 Subject: [PATCH 10/11] cosmectics (flake8) --- skimage/transform/_hough_transform.pyx | 13 ++++++----- skimage/transform/hough_transform.py | 23 +++++++++++-------- .../transform/tests/test_hough_transform.py | 5 ++-- 3 files changed, 22 insertions(+), 19 deletions(-) diff --git a/skimage/transform/_hough_transform.pyx b/skimage/transform/_hough_transform.pyx index 2d5d0230..b2250ef3 100644 --- a/skimage/transform/_hough_transform.pyx +++ b/skimage/transform/_hough_transform.pyx @@ -21,8 +21,8 @@ cdef inline Py_ssize_t round(double r): def hough_circle(cnp.ndarray img, - cnp.ndarray[ndim=1, dtype=cnp.intp_t] radius, - char normalize=True): + cnp.ndarray[ndim=1, dtype=cnp.intp_t] radius, + char normalize=True): """Perform a circular Hough transform. Parameters @@ -112,7 +112,8 @@ def hough_line(cnp.ndarray img, cnp.ndarray[ndim=1, dtype=cnp.double_t] theta=No ----- The origin is the top left corner of the original image. X and Y axis are horizontal and vertical edges respectively. - The distance is the minimal algebraic distance from the origin to the detected line. + The distance is the minimal algebraic distance from the origin + to the detected line. Examples -------- @@ -163,7 +164,7 @@ def hough_line(cnp.ndarray img, cnp.ndarray[ndim=1, dtype=cnp.double_t] theta=No # finally, run the transform cdef Py_ssize_t nidxs, nthetas, i, j, x, y, accum_idx - nidxs = y_idxs.shape[0] # x and y are the same shape + nidxs = y_idxs.shape[0] # x and y are the same shape nthetas = theta.shape[0] for i in range(nidxs): x = x_idxs[i] @@ -175,8 +176,8 @@ def hough_line(cnp.ndarray img, cnp.ndarray[ndim=1, dtype=cnp.double_t] theta=No def probabilistic_hough_line(cnp.ndarray img, int threshold=10, - int line_length=50, int line_gap=10, - cnp.ndarray[ndim=1, dtype=cnp.double_t] theta=None): + int line_length=50, int line_gap=10, + cnp.ndarray[ndim=1, dtype=cnp.double_t] theta=None): """Return lines from a progressive probabilistic line Hough transform. Parameters diff --git a/skimage/transform/hough_transform.py b/skimage/transform/hough_transform.py index 1b356127..8f56efe9 100644 --- a/skimage/transform/hough_transform.py +++ b/skimage/transform/hough_transform.py @@ -1,7 +1,5 @@ __all__ = ['hough_line_peaks'] -from itertools import izip as zip - import numpy as np from scipy import ndimage from skimage import measure, morphology @@ -10,30 +8,35 @@ from skimage import measure, morphology from ._hough_transform import hough_line, probabilistic_hough_line from skimage._shared.utils import deprecated + @deprecated('hough_line') def hough(img, theta=None): return hough_line(img, theta) + @deprecated('probabilistic_hough') def probabilistic_hough(img, threshold=10, line_length=50, line_gap=10, theta=None): return probabilistic_hough_line(img, threshold=threshold, - line_length=line_length, line_gap=line_gap, theta=theta) + line_length=line_length, line_gap=line_gap, + theta=theta) + @deprecated('hough_peaks') def hough_peaks(hspace, angles, dists, min_distance=10, min_angle=10, threshold=None, num_peaks=np.inf): return hough_line_peaks(hspace, angles, dists, min_distance, min_angle, - threshold, num_peaks) + threshold, num_peaks) -def hough_line_peaks(hspace, angles, dists, min_distance=10, min_angle=10, - threshold=None, num_peaks=np.inf): + +def hough_line_peaks(hspace, angles, dists, min_distance=9, min_angle=10, + threshold=None, num_peaks=np.inf): """Return peaks in 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. + 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 ---------- diff --git a/skimage/transform/tests/test_hough_transform.py b/skimage/transform/tests/test_hough_transform.py index 395e6faa..256c88a8 100644 --- a/skimage/transform/tests/test_hough_transform.py +++ b/skimage/transform/tests/test_hough_transform.py @@ -2,7 +2,6 @@ import numpy as np from numpy.testing import * import skimage.transform as tf -import skimage.transform.hough_transform as ht from skimage.draw import circle_perimeter, line @@ -50,7 +49,7 @@ def test_probabilistic_hough(): # as mentioned in article of Galambos et al theta = np.linspace(0, np.pi, 45) lines = tf.probabilistic_hough_line(img, threshold=10, line_length=10, - line_gap=1, theta=theta) + line_gap=1, theta=theta) # sort the lines according to the x-axis sorted_lines = [] for line in lines: @@ -110,7 +109,7 @@ def test_hough_line_peaks_num(): img[:, 40] = True hspace, angles, dists = tf.hough_line(img) assert len(tf.hough_line_peaks(hspace, angles, dists, min_distance=0, - min_angle=0, num_peaks=1)[0]) == 1 + min_angle=0, num_peaks=1)[0]) == 1 def test_hough_circle(): From 35d69732155b7df87af1a77b7312a627ae6f31ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Boulogne?= Date: Sun, 24 Mar 2013 16:34:27 +0100 Subject: [PATCH 11/11] fix deprecated variable --- skimage/transform/hough_transform.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/skimage/transform/hough_transform.py b/skimage/transform/hough_transform.py index 8f56efe9..a3c010cd 100644 --- a/skimage/transform/hough_transform.py +++ b/skimage/transform/hough_transform.py @@ -14,7 +14,7 @@ def hough(img, theta=None): return hough_line(img, theta) -@deprecated('probabilistic_hough') +@deprecated('probabilistic_hough_line') def probabilistic_hough(img, threshold=10, line_length=50, line_gap=10, theta=None): return probabilistic_hough_line(img, threshold=threshold, @@ -22,7 +22,7 @@ def probabilistic_hough(img, threshold=10, line_length=50, line_gap=10, theta=theta) -@deprecated('hough_peaks') +@deprecated('hough_line_peaks') def hough_peaks(hspace, angles, dists, min_distance=10, min_angle=10, threshold=None, num_peaks=np.inf): return hough_line_peaks(hspace, angles, dists, min_distance, min_angle,