From 7ff98597e2cf1a92e4a1b957926a43fdfbb29e1e Mon Sep 17 00:00:00 2001 From: Nelle Varoquaux Date: Thu, 22 Dec 2011 22:08:27 +0100 Subject: [PATCH] Small fixes on the Harris corner detector - documentation, method renaming etc --- CONTRIBUTORS.txt | 1 + doc/examples/plot_harris.py | 21 ++++++------- skimage/filter/__init__.py | 2 +- skimage/filter/harris.py | 48 +++++++++++++++++------------ skimage/filter/tests/test_harris.py | 23 ++++++++------ 5 files changed, 54 insertions(+), 41 deletions(-) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 007f267a..2e97d7e1 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -83,6 +83,7 @@ - Nelle Varoquaux Renaming of the package to ``skimage``. + Harris corner detector - W. Randolph Franklin Point in polygon test. diff --git a/doc/examples/plot_harris.py b/doc/examples/plot_harris.py index 6cb02ba1..9c499a3b 100644 --- a/doc/examples/plot_harris.py +++ b/doc/examples/plot_harris.py @@ -3,29 +3,28 @@ Harris Corner detector =============================================================================== -The Harris corner filter detects interest points using edge detection in many -direction. +The Harris corner filter detects interest points using edge detection in +multiple direction. """ from matplotlib import pyplot as plt -from matplotlib import cm -from skimage import data -from skimage.filter import harris_corner_detector +from skimage import data, img_as_float +from skimage.filter import harris def plot_harris_points(image, filtered_coords): """ plots corners found in image""" - plt.subplot(111) - plt.imshow(image, cmap=cm.gray) + plt.plot() + plt.imshow(image) plt.plot([p[1] for p in filtered_coords], - [p[0] for p in filtered_coords], - 'b.') + [p[0] for p in filtered_coords], + 'b.') plt.axis('off') plt.show() -im = data.lena().astype(float) -filtered_coords = harris_corner_detector(im, 6) +im = img_as_float(data.lena()) +filtered_coords = harris(im, 6) plot_harris_points(im, filtered_coords) diff --git a/skimage/filter/__init__.py b/skimage/filter/__init__.py index 6075291f..529331f0 100644 --- a/skimage/filter/__init__.py +++ b/skimage/filter/__init__.py @@ -5,4 +5,4 @@ from edges import sobel, hsobel, vsobel, hprewitt, vprewitt, prewitt from tv_denoise import tv_denoise from rank_order import rank_order from thresholding import threshold_otsu -from harris import harris_corner_detector +from harris import harris diff --git a/skimage/filter/harris.py b/skimage/filter/harris.py index b5abe7a3..303431dd 100644 --- a/skimage/filter/harris.py +++ b/skimage/filter/harris.py @@ -10,18 +10,20 @@ from scipy import ndimage def _compute_harris_response(image, eps=1e-6): """Compute the Harris corner detector response function - for each pixel in the image + for each pixel in the image - Params - ------- - image: ndarray + Parameters + ---------- + image: ndarray of floats + input image - eps: float, optional, default: 1e-6 - normalisation factor + eps: float, optional + normalisation factor Returns -------- - ndarray + features: (M, 2) ndarray + Harris image response """ if len(image.shape) == 3: image = image.mean(axis=2) @@ -42,8 +44,10 @@ def _compute_harris_response(image, eps=1e-6): # Non maximum filter of size 3 harris_max = ndimage.maximum_filter(harris, 3, mode='constant') - harris *= harris == harris_max - # Remove the image corners + mask = (harris == harris_max) + harris *= mask + + # Remove the image borders harris[:3] = 0 harris[-3:] = 0 harris[:, :3] = 0 @@ -52,23 +56,26 @@ def _compute_harris_response(image, eps=1e-6): return harris -def harris_corner_detector(image, min_distance=10, threshold=0.1, eps=1e-6): +def harris(image, min_distance=10, threshold=0.1, eps=1e-6): """Return corners from a Harris response image - params - ------- - harrisim: ndarray of floats + Parameters + ---------- + image: ndarray of floats + Input image - min_distance: int, optional, default: 10 - minimum number of pixels separating corners and image boundary + min_distance: int, optional + minimum number of pixels separating interest points and image boundary - threshold: float, optional, default: 0.1 + threshold: float, optional + relative threshold impacting the number of interest points. - eps: float, optional, default: 1e-6 + eps: float, optional + Normalisation factor returns: -------- - array: coordinates + array: coordinates of interest points """ harrisim = _compute_harris_response(image, eps=eps) corner_threshold = np.max(harrisim.ravel()) * threshold @@ -78,8 +85,9 @@ def harris_corner_detector(image, min_distance=10, threshold=0.1, eps=1e-6): # get coordinates of candidates candidates = harrisim_t.nonzero() - coords = [(candidates[0][c], candidates[1][c]) for c - in range(len(candidates[0]))] + coords = np.concatenate((candidates[0].reshape((len(candidates[0]), 1)), + candidates[1].reshape((len(candidates[0]), 1))), + axis=1) # ...and their values candidate_values = [harrisim[c[0]][c[1]] for c in coords] diff --git a/skimage/filter/tests/test_harris.py b/skimage/filter/tests/test_harris.py index 19d8cd3b..c78d3e26 100644 --- a/skimage/filter/tests/test_harris.py +++ b/skimage/filter/tests/test_harris.py @@ -1,23 +1,28 @@ import numpy as np -import unittest - -from skimage.filter import harris_corner_detector +from skimage.filter import harris +from skimage import img_as_float -class TestHarris(unittest.TestCase): - +class TestHarris(): def test_square_image(self): im = np.zeros((50, 50)).astype(float) im[:25, :25] = 1. - results = harris_corner_detector(im) - self.assertTrue(results.any()) - self.assertTrue(len(results) == 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_corner_detector(im) + 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) + assert results == np.array([6, 6])