mirror of
https://github.com/wassname/scikit-image.git
synced 2026-06-27 19:32:26 +08:00
Do not acquire GIL for corner detectors
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
import numpy as np
|
||||
cimport numpy as cnp
|
||||
from libc.float cimport DBL_MAX
|
||||
from libc.math cimport atan2
|
||||
from libc.math cimport atan2, fabs
|
||||
|
||||
from ..util import img_as_float, pad
|
||||
from ..color import rgb2grey
|
||||
@@ -67,27 +67,30 @@ def corner_moravec(image, Py_ssize_t window_size=1):
|
||||
|
||||
cdef double msum, min_msum
|
||||
cdef Py_ssize_t r, c, br, bc, mr, mc, a, b
|
||||
for r in range(2 * window_size, rows - 2 * window_size):
|
||||
for c in range(2 * window_size, cols - 2 * window_size):
|
||||
min_msum = DBL_MAX
|
||||
for br in range(r - window_size, r + window_size + 1):
|
||||
for bc in range(c - window_size, c + window_size + 1):
|
||||
if br != r and bc != c:
|
||||
msum = 0
|
||||
for mr in range(- window_size, window_size + 1):
|
||||
for mc in range(- window_size, window_size + 1):
|
||||
msum += (cimage[r + mr, c + mc]
|
||||
- cimage[br + mr, bc + mc]) ** 2
|
||||
min_msum = min(msum, min_msum)
|
||||
|
||||
out[r, c] = min_msum
|
||||
with nogil:
|
||||
for r in range(2 * window_size, rows - 2 * window_size):
|
||||
for c in range(2 * window_size, cols - 2 * window_size):
|
||||
min_msum = DBL_MAX
|
||||
for br in range(r - window_size, r + window_size + 1):
|
||||
for bc in range(c - window_size, c + window_size + 1):
|
||||
if br != r and bc != c:
|
||||
msum = 0
|
||||
for mr in range(- window_size, window_size + 1):
|
||||
for mc in range(- window_size, window_size + 1):
|
||||
msum += (cimage[r + mr, c + mc]
|
||||
- cimage[br + mr, bc + mc]) ** 2
|
||||
min_msum = min(msum, min_msum)
|
||||
|
||||
out[r, c] = min_msum
|
||||
|
||||
return np.asarray(out)
|
||||
|
||||
|
||||
cdef inline double _corner_fast_response(double curr_pixel,
|
||||
double* circle_intensities,
|
||||
signed char* bins, signed char state, char n):
|
||||
signed char* bins, signed char state,
|
||||
char n) nogil:
|
||||
cdef char consecutive_count = 0
|
||||
cdef double curr_response
|
||||
cdef Py_ssize_t l, m
|
||||
@@ -97,7 +100,7 @@ cdef inline double _corner_fast_response(double curr_pixel,
|
||||
if consecutive_count == n:
|
||||
curr_response = 0
|
||||
for m in range(16):
|
||||
curr_response += abs(circle_intensities[m] - curr_pixel)
|
||||
curr_response += fabs(circle_intensities[m] - curr_pixel)
|
||||
return curr_response
|
||||
else:
|
||||
consecutive_count = 0
|
||||
@@ -124,49 +127,50 @@ def _corner_fast(double[:, ::1] image, signed char n, double threshold):
|
||||
|
||||
cdef double curr_response
|
||||
|
||||
for i in range(3, rows - 3):
|
||||
for j in range(3, cols - 3):
|
||||
with nogil:
|
||||
for i in range(3, rows - 3):
|
||||
for j in range(3, cols - 3):
|
||||
|
||||
curr_pixel = image[i, j]
|
||||
lower_threshold = curr_pixel - threshold
|
||||
upper_threshold = curr_pixel + threshold
|
||||
curr_pixel = image[i, j]
|
||||
lower_threshold = curr_pixel - threshold
|
||||
upper_threshold = curr_pixel + threshold
|
||||
|
||||
for k in range(16):
|
||||
circle_intensities[k] = image[i + rp[k], j + cp[k]]
|
||||
if circle_intensities[k] > upper_threshold:
|
||||
# Brighter pixel
|
||||
bins[k] = 'b'
|
||||
elif circle_intensities[k] < lower_threshold:
|
||||
# Darker pixel
|
||||
bins[k] = 'd'
|
||||
else:
|
||||
# Similar pixel
|
||||
bins[k] = 's'
|
||||
for k in range(16):
|
||||
circle_intensities[k] = image[i + rp[k], j + cp[k]]
|
||||
if circle_intensities[k] > upper_threshold:
|
||||
# Brighter pixel
|
||||
bins[k] = 'b'
|
||||
elif circle_intensities[k] < lower_threshold:
|
||||
# Darker pixel
|
||||
bins[k] = 'd'
|
||||
else:
|
||||
# Similar pixel
|
||||
bins[k] = 's'
|
||||
|
||||
# High speed test for n >= 12
|
||||
if n >= 12:
|
||||
speed_sum_b = 0
|
||||
speed_sum_d = 0
|
||||
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
|
||||
# High speed test for n >= 12
|
||||
if n >= 12:
|
||||
speed_sum_b = 0
|
||||
speed_sum_d = 0
|
||||
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
|
||||
|
||||
# Test for bright pixels
|
||||
curr_response = \
|
||||
_corner_fast_response(curr_pixel, circle_intensities,
|
||||
bins, 'b', n)
|
||||
|
||||
# Test for dark pixels
|
||||
if curr_response == 0:
|
||||
# Test for bright pixels
|
||||
curr_response = \
|
||||
_corner_fast_response(curr_pixel, circle_intensities,
|
||||
bins, 'd', n)
|
||||
bins, 'b', n)
|
||||
|
||||
corner_response[i, j] = curr_response
|
||||
# Test for dark pixels
|
||||
if curr_response == 0:
|
||||
curr_response = \
|
||||
_corner_fast_response(curr_pixel, circle_intensities,
|
||||
bins, 'd', n)
|
||||
|
||||
corner_response[i, j] = curr_response
|
||||
|
||||
return np.asarray(corner_response)
|
||||
|
||||
@@ -254,22 +258,23 @@ def corner_orientations(image, Py_ssize_t[:, :] corners, mask):
|
||||
cdef double curr_pixel
|
||||
cdef double m01, m10, m01_tmp
|
||||
|
||||
for i in range(corners.shape[0]):
|
||||
r0 = corners[i, 0]
|
||||
c0 = corners[i, 1]
|
||||
with nogil:
|
||||
for i in range(corners.shape[0]):
|
||||
r0 = corners[i, 0]
|
||||
c0 = corners[i, 1]
|
||||
|
||||
m01 = 0
|
||||
m10 = 0
|
||||
m01 = 0
|
||||
m10 = 0
|
||||
|
||||
for r in range(mrows):
|
||||
m01_tmp = 0
|
||||
for c in range(mcols):
|
||||
if cmask[r, c]:
|
||||
curr_pixel = cimage[r0 + r, c0 + c]
|
||||
m10 += curr_pixel * (c - mcols2)
|
||||
m01_tmp += curr_pixel
|
||||
m01 += m01_tmp * (r - mrows2)
|
||||
for r in range(mrows):
|
||||
m01_tmp = 0
|
||||
for c in range(mcols):
|
||||
if cmask[r, c]:
|
||||
curr_pixel = cimage[r0 + r, c0 + c]
|
||||
m10 += curr_pixel * (c - mcols2)
|
||||
m01_tmp += curr_pixel
|
||||
m01 += m01_tmp * (r - mrows2)
|
||||
|
||||
orientations[i] = atan2(m01, m10)
|
||||
orientations[i] = atan2(m01, m10)
|
||||
|
||||
return np.asarray(orientations)
|
||||
|
||||
@@ -6,6 +6,7 @@ from skimage import data
|
||||
from skimage import img_as_float
|
||||
from skimage.color import rgb2gray
|
||||
from skimage.morphology import octagon
|
||||
from skimage._shared.testing import test_parallel
|
||||
|
||||
from skimage.feature import (corner_moravec, corner_harris, corner_shi_tomasi,
|
||||
corner_subpix, peak_local_max, corner_peaks,
|
||||
@@ -99,6 +100,7 @@ def test_hessian_matrix_det():
|
||||
assert_almost_equal(det, 0, decimal = 3)
|
||||
|
||||
|
||||
@test_parallel()
|
||||
def test_square_image():
|
||||
im = np.zeros((50, 50)).astype(float)
|
||||
im[:25, :25] = 1.
|
||||
@@ -280,6 +282,7 @@ def test_corner_fast_image_unsupported_error():
|
||||
assert_raises(ValueError, corner_fast, img)
|
||||
|
||||
|
||||
@test_parallel()
|
||||
def test_corner_fast_lena():
|
||||
img = rgb2gray(data.astronaut())
|
||||
expected = np.array([[101, 198],
|
||||
@@ -335,6 +338,7 @@ def test_corner_orientations_even_shape_error():
|
||||
np.asarray([[7, 7]]), np.ones((4, 4)))
|
||||
|
||||
|
||||
@test_parallel()
|
||||
def test_corner_orientations_lena():
|
||||
img = rgb2gray(data.lena())
|
||||
corners = corner_peaks(corner_fast(img, 11, 0.35))
|
||||
|
||||
Reference in New Issue
Block a user