From fd0e88b9867b1f398912c8a6cd309c26d0d566db Mon Sep 17 00:00:00 2001 From: Tony S Yu Date: Mon, 9 Jan 2012 20:52:05 -0500 Subject: [PATCH] Minor modifications to Harris corner detector * Add some references. * Make keyword argument explicit in example. * Remove test class in favor of functions since no setup was required. * Clean up docstrings. --- doc/examples/plot_harris.py | 10 +++-- skimage/filter/harris.py | 53 ++++++++++++----------- skimage/filter/tests/test_harris.py | 67 ++++++++++++++++------------- 3 files changed, 72 insertions(+), 58 deletions(-) diff --git a/doc/examples/plot_harris.py b/doc/examples/plot_harris.py index 9c499a3b..2d818e41 100644 --- a/doc/examples/plot_harris.py +++ b/doc/examples/plot_harris.py @@ -3,8 +3,11 @@ Harris Corner detector =============================================================================== -The Harris corner filter detects interest points using edge detection in -multiple direction. +The Harris corner filter [1]_ detects "interest points" [2]_ using edge +detection in multiple directions. + +.. [1] http://en.wikipedia.org/wiki/Corner_detection +.. [2] http://en.wikipedia.org/wiki/Interest_point_detection """ from matplotlib import pyplot as plt @@ -26,5 +29,6 @@ def plot_harris_points(image, filtered_coords): im = img_as_float(data.lena()) -filtered_coords = harris(im, 6) +filtered_coords = harris(im, min_distance=6) plot_harris_points(im, filtered_coords) + diff --git a/skimage/filter/harris.py b/skimage/filter/harris.py index 7eeecd30..b0add2cd 100644 --- a/skimage/filter/harris.py +++ b/skimage/filter/harris.py @@ -1,8 +1,9 @@ -# -# Harris detector -# -# Inspired from Solem's implementation -# http://www.janeriksolem.net/2009/01/harris-corner-detector-in-python.html +""" +Harris corner detector + +Inspired from Solem's implementation +http://www.janeriksolem.net/2009/01/harris-corner-detector-in-python.html +""" import numpy as np from scipy import ndimage @@ -14,18 +15,18 @@ def _compute_harris_response(image, eps=1e-6, gaussian_deviation=1): Parameters ---------- - image: ndarray of floats - Input image + image : ndarray of floats + Input image. - eps: float, optional - Normalisation factor + eps : float, optional + Normalisation factor. - gaussian_deviation: integer, optional - Standard deviation used for the Gaussian kernel + gaussian_deviation : integer, optional + Standard deviation used for the Gaussian kernel. Returns -------- - image: (M, N) ndarray + image : (M, N) ndarray Harris image response """ if len(image.shape) == 3: @@ -43,6 +44,8 @@ def _compute_harris_response(image, eps=1e-6, gaussian_deviation=1): # determinant and trace Wdet = Wxx * Wyy - Wxy ** 2 Wtr = Wxx + Wyy + # Alternate formula for Harris response. + # Alison Noble, "Descriptions of Image Surfaces", PhD thesis (1989) harris = Wdet / (Wtr + eps) # Non maximum filter of size 3 @@ -65,24 +68,25 @@ def harris(image, min_distance=10, threshold=0.1, eps=1e-6, Parameters ---------- - image: ndarray of floats - Input image + image : ndarray of floats + Input image. - min_distance: int, optional - Minimum number of pixels separating interest points and image boundary + min_distance : int, optional + Minimum number of pixels separating interest points and image boundary. - threshold: float, optional + threshold : float, optional Relative threshold impacting the number of interest points. - eps: float, optional - Normalisation factor + eps : float, optional + Normalisation factor. - gaussian_deviation: integer, optional - Standard deviation used for the Gaussian kernel + gaussian_deviation : integer, optional + Standard deviation used for the Gaussian kernel. - returns: - -------- - array: coordinates of interest points + Returns + ------- + coordinates : (N, 2) array + (row, column) coordinates of interest points. """ harrisim = _compute_harris_response(image, eps=eps, gaussian_deviation=gaussian_deviation) @@ -116,3 +120,4 @@ def harris(image, min_distance=10, threshold=0.1, eps=1e-6, (coords[i][1] - min_distance):(coords[i][1] + min_distance)] = 0 return np.array(filtered_coords) + diff --git a/skimage/filter/tests/test_harris.py b/skimage/filter/tests/test_harris.py index 853a00a0..295ab358 100644 --- a/skimage/filter/tests/test_harris.py +++ b/skimage/filter/tests/test_harris.py @@ -6,37 +6,42 @@ from skimage import img_as_float from skimage.filter import harris -class TestHarris(): - def test_square_image(self): - im = np.zeros((50, 50)).astype(float) - im[:25, :25] = 1. - results = harris(im) - assert results.any() - assert len(results) == 1 +def test_square_image(): + im = np.zeros((50, 50)).astype(float) + im[:25, :25] = 1. + results = harris(im) + assert results.any() + assert len(results) == 1 - def test_noisy_square_image(self): - im = np.zeros((50, 50)).astype(float) - im[:25, :25] = 1. - im = im + np.random.uniform(size=im.shape) * .5 - results = harris(im) - assert results.any() - assert len(results) == 1 +def test_noisy_square_image(): + im = np.zeros((50, 50)).astype(float) + im[:25, :25] = 1. + im = im + np.random.uniform(size=im.shape) * .5 + results = harris(im) + assert results.any() + assert len(results) == 1 - def test_squared_dot(self): - im = np.zeros((50, 50)) - im[4:8, 4:8] = 1 - im = img_as_float(im) - results = harris(im, min_distance=3) - print results - assert (results == np.array([[6, 6]])).all() +def test_squared_dot(): + im = np.zeros((50, 50)) + im[4:8, 4:8] = 1 + im = img_as_float(im) + results = harris(im, min_distance=3) + print results + assert (results == np.array([[6, 6]])).all() + +def test_rotated_lena(): + """ + The harris filter should yield the same results with an image and it's + rotation. + """ + im = img_as_float(data.lena().mean(axis=2)) + results = harris(im) + im_rotated = im.T + results_rotated = harris(im_rotated) + assert (results[:, 0] == results_rotated[:, 1]).all() + + +if __name__ == '__main__': + from numpy import testing + testing.run_module_suite() - def test_rotated_lena(self): - """ - The harris filter should yield the same results with an image and it's - rotation. - """ - im = img_as_float(data.lena().mean(axis=2)) - results = harris(im) - im_rotated = im.T - results_rotated = harris(im_rotated) - assert (results[:, 0] == results_rotated[:, 1]).all()