From 3172f508d6f31247aada306b559b850658e2bb8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Sch=C3=B6nberger?= Date: Sat, 17 Aug 2013 22:35:13 +0200 Subject: [PATCH] Use typed memoryviews in feature package --- skimage/feature/_template.pyx | 8 +++---- skimage/feature/_texture.pyx | 42 ++++++++++++++++------------------- skimage/feature/corner_cy.pyx | 21 +++++------------- skimage/feature/texture.py | 2 +- 4 files changed, 30 insertions(+), 43 deletions(-) diff --git a/skimage/feature/_template.pyx b/skimage/feature/_template.pyx index 03695959..855ece23 100644 --- a/skimage/feature/_template.pyx +++ b/skimage/feature/_template.pyx @@ -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) diff --git a/skimage/feature/_texture.pyx b/skimage/feature/_texture.pyx index f98ed4ca..0e17fd1d 100644 --- a/skimage/feature/_texture.pyx +++ b/skimage/feature/_texture.pyx @@ -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(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: diff --git a/skimage/feature/corner_cy.pyx b/skimage/feature/corner_cy.pyx index d4bc5e5a..7d558e52 100644 --- a/skimage/feature/corner_cy.pyx +++ b/skimage/feature/corner_cy.pyx @@ -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 = cimage.data - cdef double* out_data = 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) diff --git a/skimage/feature/texture.py b/skimage/feature/texture.py index 7655b82a..7549cfdd 100644 --- a/skimage/feature/texture.py +++ b/skimage/feature/texture.py @@ -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