mirror of
https://github.com/wassname/scikit-image.git
synced 2026-06-27 20:22:51 +08:00
Transferring all the FAST code to corner.py and corner_cy.pyx
This commit is contained in:
committed by
Johannes Schönberger
parent
5a886e69c3
commit
b8958ccee0
@@ -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
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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'],
|
||||
|
||||
Reference in New Issue
Block a user