Transferring all the FAST code to corner.py and corner_cy.pyx

This commit is contained in:
Ankit Agrawal
2013-08-21 01:44:04 +05:30
committed by Johannes Schönberger
parent 5a886e69c3
commit b8958ccee0
5 changed files with 140 additions and 8 deletions
-3
View File
@@ -102,9 +102,6 @@ Library:
Extension: skimage.feature.corner_cy
Sources:
skimage/feature/corner_cy.pyx
Extension: skimage.feature.fast_cy
Sources:
skimage/feature/fast_cy.pyx
Extension: skimage.feature._texture
Sources:
skimage/feature/_texture.pyx
+1 -2
View File
@@ -4,13 +4,12 @@ from .texture import greycomatrix, greycoprops, local_binary_pattern
from .peak import peak_local_max
from .corner import (corner_kitchen_rosenfeld, corner_harris,
corner_shi_tomasi, corner_foerstner, corner_subpix,
corner_peaks)
corner_peaks, corner_fast)
from .corner_cy import corner_moravec
from .template import match_template
from ._brief import brief, match_keypoints_brief
from .util import pairwise_hamming_distance
from .censure import keypoints_censure
from .fast import corner_fast
__all__ = ['daisy',
'hog',
+49
View File
@@ -1,10 +1,13 @@
import numpy as np
from scipy import ndimage
from scipy import stats
from scipy.ndimage.filters import maximum_filter
from skimage.color import rgb2grey
from skimage.util import img_as_float, pad
from skimage.feature import peak_local_max
from corner_cy import _corner_fast
def _compute_derivatives(image):
"""Compute derivatives in x and y direction using the Sobel operator.
@@ -542,3 +545,49 @@ def corner_peaks(image, min_distance=10, threshold_abs=0, threshold_rel=0.1,
return np.transpose(peaks.nonzero())
else:
return peaks
def corner_fast(image, n=12, threshold=0.15):
"""Extract FAST corners for a given image.
Parameters
----------
image : 2D ndarray
Input image.
n : int
Number of consecutive pixels out of 16 pixels on the circle that
should be brighter or darker with respect to test pixel above the
`threshold` so as to classify the test pixel as a FAST corner. Also
stands for the n in `FAST-n` corner detector.
threshold : float
Threshold used in deciding whether the pixels on the circle are
brighter, darker or similar w.r.t. the test pixel. Decrease the
threshold when more corners are desired and vice-versa.
Returns
-------
corners : (N, 2) ndarray
Location i.e. (row, col) of extracted FAST corners.
References
----------
.. [1] Edward Rosten and Tom Drummond
"Machine Learning for high-speed corner detection",
http://www.edwardrosten.com/work/rosten_2006_machine.pdf
"""
image = np.squeeze(image)
if image.ndim != 2:
raise ValueError("Only 2-D gray-scale images supported.")
image = np.ascontiguousarray(image, dtype=np.double)
corner_response = _corner_fast(image, n, threshold)
# Non-maximal Suppression
corner_zero_mask = corner_response != 0
maximas = (maximum_filter(corner_response, (3, 3)) == corner_response) & corner_zero_mask
x, y = np.where(maximas == True)
corners = np.squeeze(np.dstack((x, y)))
return corners
+90
View File
@@ -80,3 +80,93 @@ def corner_moravec(image, Py_ssize_t window_size=1):
out[r, c] = min_msum
return np.asarray(out)
def _corner_fast(double[:, ::1] image, int n, double threshold):
cdef int[:] rp = (np.round(3 * np.sin(2 * np.pi * np.arange(16, dtype=np.double) / 16))).astype(np.int32)
cdef int[:] cp = (np.round(3 * np.cos(2 * np.pi * np.arange(16, dtype=np.double) / 16))).astype(np.int32)
cdef Py_ssize_t rows = image.shape[0]
cdef Py_ssize_t cols = image.shape[1]
cdef Py_ssize_t i, j, k, l, m
cdef char[:] bins = np.zeros(16, dtype=np.uint8)
cdef int consecutive_count, speed_sum_b, speed_sum_d
cdef int sp
cdef double sum_b, sum_d, current_pixel
cdef double[:, ::1] corner_response = np.zeros((rows, cols), dtype=np.double)
cdef double circle_intensity
for i in range(3, rows - 3):
for j in range(3, cols - 3):
current_pixel = image[i, j]
speed_sum_b = 0
speed_sum_d = 0
sum_b = 0
sum_d = 0
for k in range(16):
circle_intensity = image[i + rp[k], j + cp[k]]
if circle_intensity > current_pixel + threshold:
# Brighter pixel
bins[k] = 'b'
elif circle_intensity < current_pixel - threshold:
# Darker pixel
bins[k] = 'd'
else:
# Similar pixel
bins[k] = 's'
# High speed test for n>=12
if n >= 12:
for k in range(0, 16, 4):
if bins[k] == 'b':
speed_sum_b += 1
elif bins[k] == 'd':
speed_sum_d += 1
if speed_sum_d < 3 and speed_sum_b < 3:
continue
consecutive_count = 0
for l in range(15 + n):
if bins[l % 16] == 'b':
consecutive_count += 1
if consecutive_count == n:
for m in range(16):
if bins[m] == 'b':
sum_b += image[i + rp[m], j + cp[m]] - current_pixel - threshold
elif bins[m] == 'd':
sum_d += current_pixel - image[i + rp[m], j + cp[m]] - threshold
# Finding the response of the corner
if sum_d > sum_b:
corner_response[i, j] = sum_d
else:
corner_response[i, j] = sum_b
break
else:
consecutive_count = 0
if corner_response[i, j] == 0:
consecutive_count = 0
for l in range(15 + n):
if bins[l % 16] == 'd':
consecutive_count += 1
if consecutive_count == n:
for m in range(16):
if bins[m] == 'b':
sum_b += image[i + rp[m], j + cp[m]] - current_pixel - threshold
elif bins[m] == 'd':
sum_d += current_pixel - image[i + rp[m], j + cp[m]] - threshold
# Finding the response of the corner
if sum_d > sum_b:
corner_response[i, j] = sum_d
else:
corner_response[i, j] = sum_b
break
else:
consecutive_count = 0
return np.asarray(corner_response)
-3
View File
@@ -14,7 +14,6 @@ def configuration(parent_package='', top_path=None):
cython(['corner_cy.pyx'], working_path=base_path)
cython(['censure_cy.pyx'], working_path=base_path)
cython(['fast_cy.pyx'], working_path=base_path)
cython(['_brief_cy.pyx'], working_path=base_path)
cython(['_texture.pyx'], working_path=base_path)
cython(['_template.pyx'], working_path=base_path)
@@ -23,8 +22,6 @@ def configuration(parent_package='', top_path=None):
include_dirs=[get_numpy_include_dirs()])
config.add_extension('censure_cy', sources=['censure_cy.c'],
include_dirs=[get_numpy_include_dirs()])
config.add_extension('fast_cy', sources=['fast_cy.c'],
include_dirs=[get_numpy_include_dirs()])
config.add_extension('_brief_cy', sources=['_brief_cy.c'],
include_dirs=[get_numpy_include_dirs()])
config.add_extension('_texture', sources=['_texture.c'],