mirror of
https://github.com/wassname/scikit-image.git
synced 2026-07-13 17:45:20 +08:00
Implemented FAST corner detector
This commit is contained in:
committed by
Johannes Schönberger
parent
03980b10ee
commit
5f1976ace2
@@ -102,6 +102,9 @@ 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
|
||||
|
||||
@@ -7,7 +7,10 @@ from .corner import (corner_kitchen_rosenfeld, corner_harris,
|
||||
corner_peaks)
|
||||
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',
|
||||
@@ -22,4 +25,9 @@ __all__ = ['daisy',
|
||||
'corner_subpix',
|
||||
'corner_peaks',
|
||||
'corner_moravec',
|
||||
'match_template']
|
||||
'match_template',
|
||||
'brief',
|
||||
'pairwise_hamming_distance',
|
||||
'match_keypoints_brief',
|
||||
'keypoints_censure',
|
||||
'corner_fast']
|
||||
|
||||
+12
-25
@@ -1,35 +1,22 @@
|
||||
import numpy as np
|
||||
from ..util import img_as_float
|
||||
from scipy.ndimage.filters import maximum_filter
|
||||
|
||||
from fast_cy import _corner_fast
|
||||
|
||||
|
||||
def corner_fast(image, n=9, threshold=0.15):
|
||||
def corner_fast(image, n=12, threshold=0.15):
|
||||
|
||||
image = np.squeeze(image)
|
||||
if image.ndim != 2:
|
||||
raise ValueError("Only 2-D gray-scale images supported.")
|
||||
|
||||
image = img_as_float(image)
|
||||
corner_mask = np.zeros(image.shape, dtype=bool)
|
||||
image = np.ascontiguousarray(image, dtype=np.double)
|
||||
corner = _corner_fast(image, n, threshold)
|
||||
|
||||
test_pixels = np.asarray([[-3, 0], [-3, 1], [-2, 2], [-1, 3], [0, 3],
|
||||
[1, 3], [2, 2], [3, 1], [3, 0], [3, -1],
|
||||
[2, -2], [1, -3], [0, -3], [-1, -3],
|
||||
[-2, -2], [-1, -3]])
|
||||
corner_zero_mask = corner != 0
|
||||
c, d = np.nonzero(corner)
|
||||
|
||||
# TODO : Outsource to Cython
|
||||
for i in range(3, image.shape[0] - 3):
|
||||
for j in range(3, image.shape[1] - 3):
|
||||
test_x = i + test_pixels[:, 0]
|
||||
test_y = j + test_pixels[:, 1]
|
||||
intensities = image[test_x, test_y]
|
||||
low = intensities < image[i, j] - threshold
|
||||
high = intensities > image[i, j] + threshold
|
||||
low = np.concatenate(low, low)
|
||||
high = np.concatenate(high, high)
|
||||
# How to check if a sequence n * [True] exists in low/high ?
|
||||
# if n * [True] in low or n * True in high:
|
||||
# corner_mask[i, j] = True
|
||||
|
||||
corner_x, corner_y = np.where(corner_mask == True)
|
||||
corners = np.dstack(corner_x, corner_y)
|
||||
return corners
|
||||
maximas = (maximum_filter(corner, (3, 3)) == corner) & corner_zero_mask
|
||||
x, y = np.where(maximas == True)
|
||||
|
||||
return np.squeeze(np.dstack((x, y)))
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
#cython: cdivision=True
|
||||
#cython: boundscheck=False
|
||||
#cython: nonecheck=False
|
||||
#cython: wraparound=False
|
||||
|
||||
import numpy as np
|
||||
|
||||
from ..util import img_as_float
|
||||
|
||||
|
||||
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
|
||||
cdef int consecutive_count = 0
|
||||
cdef double sum_b
|
||||
cdef double sum_d
|
||||
cdef double[:, ::1] corner = 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):
|
||||
|
||||
bins = np.zeros(16, dtype='S1')
|
||||
sum_b = 0
|
||||
sum_d = 0
|
||||
|
||||
for k in range(16):
|
||||
circle_intensity = image[i + rp[k], j + cp[k]]
|
||||
if circle_intensity > image[i, j] + threshold:
|
||||
bins[k] = 'b'
|
||||
elif circle_intensity < image[i, j] - threshold:
|
||||
bins[k] = 'd'
|
||||
else:
|
||||
bins[k] = 's'
|
||||
|
||||
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]] - image[i, j] - threshold
|
||||
elif bins[m] == 'd':
|
||||
sum_d += image[i, j] - image[i + rp[m], j + cp[m]] - threshold
|
||||
if sum_d > sum_b:
|
||||
corner[i, j] = sum_d
|
||||
else:
|
||||
corner[i, j] = sum_b
|
||||
break
|
||||
else:
|
||||
consecutive_count = 0
|
||||
|
||||
if corner[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]] - image[i, j] - threshold
|
||||
elif bins[m] == 'd':
|
||||
sum_d += image[i, j] - image[i + rp[m], j + cp[m]] - threshold
|
||||
if sum_d > sum_b:
|
||||
corner[i, j] = sum_d
|
||||
else:
|
||||
corner[i, j] = sum_b
|
||||
break
|
||||
else:
|
||||
consecutive_count = 0
|
||||
|
||||
return np.asarray(corner)
|
||||
@@ -14,6 +14,7 @@ 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)
|
||||
@@ -22,6 +23,8 @@ 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