mirror of
https://github.com/wassname/scikit-image.git
synced 2026-07-16 11:21:25 +08:00
Use shared bilinear interpolation function and improve performance.
This commit is contained in:
@@ -1,10 +1,13 @@
|
||||
#cython: cdivison=True
|
||||
#cython: boundscheck=False
|
||||
#cython: nonecheck=False
|
||||
#cython: wraparound=False
|
||||
import numpy as np
|
||||
cimport numpy as np
|
||||
cimport cython
|
||||
from libc.math cimport sin, cos, abs, ceil, floor
|
||||
from libc.math cimport sin, cos, abs
|
||||
from skimage.transform._project cimport bilinear_interpolation
|
||||
|
||||
|
||||
@cython.boundscheck(False)
|
||||
def _glcm_loop(np.ndarray[dtype=np.uint8_t, ndim=2,
|
||||
negative_indices=False, mode='c'] image,
|
||||
np.ndarray[dtype=np.float64_t, ndim=1,
|
||||
@@ -62,42 +65,7 @@ def _glcm_loop(np.ndarray[dtype=np.uint8_t, ndim=2,
|
||||
out[i, j, d_idx, a_idx] += 1
|
||||
|
||||
|
||||
@cython.boundscheck(False)
|
||||
@cython.wraparound(False)
|
||||
@cython.nonecheck(False)
|
||||
@cython.cdivision(True)
|
||||
cdef _bilinear_interpolation(np.ndarray[double, ndim=2] image,
|
||||
np.ndarray[double, ndim=2] coords,
|
||||
np.ndarray[double, ndim=1] output,
|
||||
double r0=0, double c0=0, double cval=0):
|
||||
cdef double r, c, dr, dc
|
||||
cdef int i, minr, minc, maxr, maxc
|
||||
|
||||
for i in range(coords.shape[0]):
|
||||
r = r0 + coords[i, 0]
|
||||
c = c0 + coords[i, 1]
|
||||
minr = <int>floor(r)
|
||||
minc = <int>floor(c)
|
||||
maxr = <int>ceil(r)
|
||||
maxc = <int>ceil(c)
|
||||
dr = r - minr
|
||||
dc = c - minc
|
||||
if (
|
||||
minr < 0 or maxr >= image.shape[0]
|
||||
or minc < 0 or maxc >= image.shape[1]
|
||||
):
|
||||
output[i] = cval
|
||||
else:
|
||||
top = (1 - dc) * image[minr, minc] + dc * image[minr, maxc]
|
||||
bottom = (1 - dc) * image[maxr, minc] + dc * image[maxr, maxc]
|
||||
output[i] = (1 - dr) * top + dr * bottom
|
||||
|
||||
|
||||
@cython.boundscheck(False)
|
||||
@cython.wraparound(False)
|
||||
@cython.nonecheck(False)
|
||||
@cython.cdivision(True)
|
||||
cdef int _bit_rotate_right(int value, int length):
|
||||
cdef inline int _bit_rotate_right(int value, int length):
|
||||
"""Cyclic bit shift to the right.
|
||||
|
||||
Parameters
|
||||
@@ -111,10 +79,6 @@ cdef int _bit_rotate_right(int value, int length):
|
||||
return (value >> 1) | ((value & 1) << (length - 1))
|
||||
|
||||
|
||||
@cython.boundscheck(False)
|
||||
@cython.wraparound(False)
|
||||
@cython.nonecheck(False)
|
||||
@cython.cdivision(True)
|
||||
def _local_binary_pattern(np.ndarray[double, ndim=2] image,
|
||||
int P, float R, int method=0):
|
||||
# texture weights
|
||||
@@ -132,11 +96,16 @@ def _local_binary_pattern(np.ndarray[double, ndim=2] image,
|
||||
output_shape = (image.shape[0], image.shape[1])
|
||||
cdef np.ndarray[double, ndim=2] output = np.zeros(output_shape, 'double')
|
||||
|
||||
cdef int rows = image.shape[0]
|
||||
cdef int cols = image.shape[1]
|
||||
|
||||
cdef double lbp
|
||||
cdef int r, c, changes, i
|
||||
for r in range(image.shape[0]):
|
||||
for c in range(image.shape[1]):
|
||||
_bilinear_interpolation(image, coords, texture, r, c)
|
||||
for i in range(P):
|
||||
texture[i] = bilinear_interpolation(<double*>image.data,
|
||||
rows, cols, r + coords[i, 0], c + coords[i, 1], 'C')
|
||||
# signed / thresholded texture
|
||||
for i in range(P):
|
||||
if texture[i] - image[r, c] >= 0:
|
||||
|
||||
@@ -16,7 +16,8 @@ def configuration(parent_package='', top_path=None):
|
||||
cython(['_template.pyx'], working_path=base_path)
|
||||
|
||||
config.add_extension('_texture', sources=['_texture.c'],
|
||||
include_dirs=[get_numpy_include_dirs()])
|
||||
include_dirs=[get_numpy_include_dirs(),
|
||||
'../transform'])
|
||||
config.add_extension('_template', sources=['_template.c'],
|
||||
include_dirs=[get_numpy_include_dirs()])
|
||||
|
||||
|
||||
@@ -154,49 +154,48 @@ class TestLBP():
|
||||
|
||||
def test_default(self):
|
||||
lbp = local_binary_pattern(self.image, 8, 1, 'default')
|
||||
ref = np.array([[ 0., 241., 0., 255., 96., 255.],
|
||||
[135., 0., 20., 153., 64., 56.],
|
||||
[198., 255., 12., 191., 0., 124.],
|
||||
[129., 64., 62., 159., 199., 0.],
|
||||
[255., 4., 255., 175., 0., 124.],
|
||||
[ 3., 5., 0., 255., 4., 24.]])
|
||||
print lbp
|
||||
ref = np.array([[ 0, 251, 0, 255, 96, 255],
|
||||
[143, 0, 20, 153, 64, 56],
|
||||
[238, 255, 12, 191, 0, 252],
|
||||
[129, 64., 62, 159, 199, 0],
|
||||
[255, 4, 255, 175, 0, 254],
|
||||
[ 3, 5, 0, 255, 4, 24]])
|
||||
np.testing.assert_array_equal(lbp, ref)
|
||||
|
||||
def test_ror(self):
|
||||
lbp = local_binary_pattern(self.image, 8, 1, 'ror')
|
||||
ref = np.array([[ 0., 31., 0., 255., 3., 255.],
|
||||
[ 15., 0., 5., 51., 1., 7.],
|
||||
[ 27., 255., 3., 127., 0., 31.],
|
||||
[ 3., 1., 31., 63., 31., 0.],
|
||||
[255., 1., 255., 95., 0., 31.],
|
||||
[ 3., 5., 0., 255., 1., 3.]])
|
||||
ref = np.array([[ 0, 127, 0, 255, 3, 255],
|
||||
[ 31, 0, 5, 51, 1, 7],
|
||||
[119, 255, 3, 127, 0, 63],
|
||||
[ 3, 1, 31, 63, 31, 0],
|
||||
[255, 1, 255, 95, 0, 127],
|
||||
[ 3, 5, 0, 255, 1, 3]])
|
||||
np.testing.assert_array_equal(lbp, ref)
|
||||
|
||||
def test_uniform(self):
|
||||
lbp = local_binary_pattern(self.image, 8, 1, 'uniform')
|
||||
ref = np.array([[0., 5., 0., 8., 2., 8.],
|
||||
[4., 0., 9., 9., 1., 3.],
|
||||
[9., 8., 2., 7., 0., 5.],
|
||||
[2., 1., 5., 6., 5., 0.],
|
||||
[8., 1., 8., 9., 0., 5.],
|
||||
[2., 9., 0., 8., 1., 2.]])
|
||||
ref = np.array([[0, 7, 0, 8, 2, 8],
|
||||
[5, 0, 9, 9, 1, 3],
|
||||
[9, 8, 2, 7, 0, 6],
|
||||
[2, 1, 5, 6, 5, 0],
|
||||
[8, 1, 8, 9, 0, 7],
|
||||
[2, 9, 0, 8, 1, 2]])
|
||||
np.testing.assert_array_equal(lbp, ref)
|
||||
|
||||
def test_var(self):
|
||||
lbp = local_binary_pattern(self.image, 8, 1, 'var')
|
||||
ref = np.array([[0. , 0.00039254, 0. , 0.00089309,
|
||||
0.00030782, 0.00203232],
|
||||
[0.00037561, 0. , 0.00263827, 0.00163246,
|
||||
0.00027414, 0.00039593],
|
||||
[0.00170876, 0.00130368, 0.00042095, 0.00171893,
|
||||
0. , 0.00044912],
|
||||
[0.00021898, 0.00019464, 0.00082291, 0.00225383,
|
||||
ref = np.array([[0. , 0.00072786, 0. , 0.00115377,
|
||||
0.00032355, 0.00224467],
|
||||
[0.00051758, 0. , 0.0026383 , 0.00163246,
|
||||
0.00027414, 0.00041124],
|
||||
[0.00192834, 0.00130368, 0.00042095, 0.00171894,
|
||||
0. , 0.00063726],
|
||||
[0.00023048, 0.00019464 , 0.00082291, 0.00225386,
|
||||
0.00076696, 0. ],
|
||||
[0.00079791, 0.00013236, 0.0009134 , 0.0014467 ,
|
||||
0. , 0.00046857],
|
||||
[0.00022553, 0.00089319, 0. , 0.00089274,
|
||||
0.00013659, 0.00031981]])
|
||||
[0.00097253, 0.00013236, 0.0009134 , 0.0014467 ,
|
||||
0. , 0.00082472],
|
||||
[0.00024701, 0.0012277 , 0. , 0.00109869,
|
||||
0.00015445, 0.00035881]])
|
||||
np.testing.assert_array_almost_equal(lbp, ref)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user