Use typed memoryviews in feature package

This commit is contained in:
Johannes Schönberger
2013-08-17 22:35:13 +02:00
parent cd9f3bd92e
commit 3172f508d6
4 changed files with 30 additions and 43 deletions
+4 -4
View File
@@ -50,9 +50,9 @@ from skimage.transform import integral
def match_template(cnp.ndarray[float, ndim=2, mode="c"] image,
cnp.ndarray[float, ndim=2, mode="c"] template):
cdef cnp.ndarray[float, ndim=2, mode="c"] corr
cdef cnp.ndarray[float, ndim=2, mode="c"] image_sat
cdef cnp.ndarray[float, ndim=2, mode="c"] image_sqr_sat
cdef float[:, ::1] corr
cdef float[:, ::1] image_sat
cdef float[:, ::1] image_sqr_sat
cdef float template_mean = np.mean(template)
cdef float template_ssd
cdef float inv_area
@@ -94,4 +94,4 @@ def match_template(cnp.ndarray[float, ndim=2, mode="c"] image,
den = sqrt((window_sqr_sum - window_mean_sqr) * template_ssd)
corr[r, c] /= den
return corr
return np.asarray(corr)
+19 -23
View File
@@ -8,15 +8,9 @@ from libc.math cimport sin, cos, abs
from skimage._shared.interpolation cimport bilinear_interpolation
def _glcm_loop(cnp.ndarray[dtype=cnp.uint8_t, ndim=2,
negative_indices=False, mode='c'] image,
cnp.ndarray[dtype=cnp.float64_t, ndim=1,
negative_indices=False, mode='c'] distances,
cnp.ndarray[dtype=cnp.float64_t, ndim=1,
negative_indices=False, mode='c'] angles,
int levels,
cnp.ndarray[dtype=cnp.uint32_t, ndim=4,
negative_indices=False, mode='c'] out):
def _glcm_loop(cnp.uint8_t[:, ::1] image, double[:] distances,
double[:] angles, Py_ssize_t levels,
cnp.uint32_t[:, :, :, ::1] out):
"""Perform co-occurrence matrix accumulation.
Parameters
@@ -81,7 +75,7 @@ cdef inline int _bit_rotate_right(int value, int length):
return (value >> 1) | ((value & 1) << (length - 1))
def _local_binary_pattern(cnp.ndarray[double, ndim=2] image,
def _local_binary_pattern(double[:, ::1] image,
int P, float R, char method='D'):
"""Gray scale and rotation invariant LBP (Local Binary Patterns).
@@ -92,8 +86,8 @@ def _local_binary_pattern(cnp.ndarray[double, ndim=2] image,
image : (N, M) double array
Graylevel image.
P : int
Number of circularly symmetric neighbour set points (quantization of the
angular space).
Number of circularly symmetric neighbour set points (quantization of
the angular space).
R : float
Radius of circle (spatial resolution of the operator).
method : {'D', 'R', 'U', 'V'}
@@ -111,19 +105,20 @@ def _local_binary_pattern(cnp.ndarray[double, ndim=2] image,
"""
# texture weights
cdef cnp.ndarray[int, ndim=1] weights = 2 ** np.arange(P, dtype=np.int32)
cdef int[:] weights = 2 ** np.arange(P, dtype=np.int32)
# local position of texture elements
rp = - R * np.sin(2 * np.pi * np.arange(P, dtype=np.double) / P)
cp = R * np.cos(2 * np.pi * np.arange(P, dtype=np.double) / P)
cdef cnp.ndarray[double, ndim=2] coords = np.round(np.vstack([rp, cp]).T, 5)
rr = - R * np.sin(2 * np.pi * np.arange(P, dtype=np.double) / P)
cc = R * np.cos(2 * np.pi * np.arange(P, dtype=np.double) / P)
cdef double[:] rp = np.round(rr, 5)
cdef double[:] cp = np.round(cc, 5)
# pre allocate arrays for computation
cdef cnp.ndarray[double, ndim=1] texture = np.zeros(P, np.double)
cdef cnp.ndarray[char, ndim=1] signed_texture = np.zeros(P, np.int8)
cdef cnp.ndarray[int, ndim=1] rotation_chain = np.zeros(P, np.int32)
# pre-allocate arrays for computation
cdef double[:] texture = np.zeros(P, dtype=np.double)
cdef char[:] signed_texture = np.zeros(P, dtype=np.int8)
cdef int[:] rotation_chain = np.zeros(P, dtype=np.int32)
output_shape = (image.shape[0], image.shape[1])
cdef cnp.ndarray[double, ndim=2] output = np.zeros(output_shape, np.double)
cdef double[:, ::1] output = np.zeros(output_shape, dtype=np.double)
cdef Py_ssize_t rows = image.shape[0]
cdef Py_ssize_t cols = image.shape[1]
@@ -133,8 +128,9 @@ def _local_binary_pattern(cnp.ndarray[double, ndim=2] image,
for r in range(image.shape[0]):
for c in range(image.shape[1]):
for i in range(P):
texture[i] = bilinear_interpolation(<double*>image.data,
rows, cols, r + coords[i, 0], c + coords[i, 1], 'C', 0)
texture[i] = bilinear_interpolation(&image[0, 0], rows, cols,
r + rp[i], c + cp[i],
'C', 0)
# signed / thresholded texture
for i in range(P):
if texture[i] - image[r, c] >= 0:
+6 -15
View File
@@ -59,16 +59,8 @@ def corner_moravec(image, Py_ssize_t window_size=1):
cdef Py_ssize_t rows = image.shape[0]
cdef Py_ssize_t cols = image.shape[1]
cdef cnp.ndarray[dtype=cnp.double_t, ndim=2, mode='c'] cimage, out
if image.ndim == 3:
cimage = rgb2grey(image)
cimage = np.ascontiguousarray(img_as_float(image))
out = np.zeros(image.shape, dtype=np.double)
cdef double* image_data = <double*>cimage.data
cdef double* out_data = <double*>out.data
cdef double[:, ::1] cimage = np.ascontiguousarray(img_as_float(image))
cdef double[:, ::1] out = np.zeros(image.shape, dtype=np.double)
cdef double msum, min_msum
cdef Py_ssize_t r, c, br, bc, mr, mc, a, b
@@ -81,11 +73,10 @@ def corner_moravec(image, Py_ssize_t window_size=1):
msum = 0
for mr in range(- window_size, window_size + 1):
for mc in range(- window_size, window_size + 1):
a = (r + mr) * cols + c + mc
b = (br + mr) * cols + bc + mc
msum += (image_data[a] - image_data[b]) ** 2
msum += (cimage[r + mr, c + mc]
- cimage[br + mr, bc + mc]) ** 2
min_msum = min(msum, min_msum)
out_data[r * cols + c] = min_msum
out[r, c] = min_msum
return out
return np.asarray(out)
+1 -1
View File
@@ -271,6 +271,6 @@ def local_binary_pattern(image, P, R, method='default'):
'uniform': ord('U'),
'var': ord('V')
}
image = np.array(image, dtype='double', copy=True)
image = np.ascontiguousarray(image, dtype=np.double)
output = _local_binary_pattern(image, P, R, methods[method.lower()])
return output