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.
This commit is contained in:
Tony S Yu
2012-01-09 20:52:05 -05:00
parent 5999c7ed01
commit fd0e88b986
3 changed files with 72 additions and 58 deletions
+7 -3
View File
@@ -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)
+29 -24
View File
@@ -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)
+36 -31
View File
@@ -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()