diff --git a/skimage/graph/_spath.pyx b/skimage/graph/_spath.pyx index f342021d..1624bc7d 100644 --- a/skimage/graph/_spath.pyx +++ b/skimage/graph/_spath.pyx @@ -2,9 +2,8 @@ import _mcp cimport _mcp +from libc.math cimport fabs -cdef extern from "math.h": - double fabs(double f) cdef class MCP_Diff(_mcp.MCP): """MCP_Diff(costs, offsets=None, fully_connected=True) diff --git a/skimage/io/_plugins/_colormixer.pyx b/skimage/io/_plugins/_colormixer.pyx index 5d0dd1b9..ace45c94 100644 --- a/skimage/io/_plugins/_colormixer.pyx +++ b/skimage/io/_plugins/_colormixer.pyx @@ -8,15 +8,10 @@ integers, so currently the only way to clip results efficiently one. """ - +import cython import numpy as np cimport numpy as np - -import cython - -cdef extern from "math.h": - float exp(float) nogil - float pow(float, float) nogil +from libc.math cimport exp, pow @cython.boundscheck(False) @@ -189,7 +184,6 @@ def sigmoid_gamma(np.ndarray[np.uint8_t, ndim=3] img, img[i,j,2] = lut[stateimg[i,j,2]] - @cython.boundscheck(False) def gamma(np.ndarray[np.uint8_t, ndim=3] img, np.ndarray[np.uint8_t, ndim=3] stateimg, @@ -219,7 +213,6 @@ def gamma(np.ndarray[np.uint8_t, ndim=3] img, img[i,j,2] = lut[stateimg[i,j,2]] - @cython.cdivision(True) cdef void rgb_2_hsv(float* RGB, float* HSV) nogil: cdef float R, G, B, H, S, V, MAX, MIN @@ -283,6 +276,7 @@ cdef void rgb_2_hsv(float* RGB, float* HSV) nogil: HSV[1] = S HSV[2] = V + @cython.cdivision(True) cdef void hsv_2_rgb(float* HSV, float* RGB) nogil: cdef float H, S, V @@ -388,6 +382,7 @@ def py_hsv_2_rgb(H, S, V): return (R, G, B) + def py_rgb_2_hsv(R, G, B): '''Convert an HSV value to RGB. @@ -561,9 +556,3 @@ def hsv_multiply(np.ndarray[np.uint8_t, ndim=3] img, img[i, j, 0] = RGB[0] img[i, j, 1] = RGB[1] img[i, j, 2] = RGB[2] - - - - - - diff --git a/skimage/segmentation/_quickshift.pyx b/skimage/segmentation/_quickshift.pyx index 57009ad1..57be1040 100644 --- a/skimage/segmentation/_quickshift.pyx +++ b/skimage/segmentation/_quickshift.pyx @@ -1,6 +1,7 @@ import numpy as np cimport numpy as np cimport cython +from libc.math cimport exp, sqrt from itertools import product from scipy import ndimage @@ -9,11 +10,6 @@ from ..util import img_as_float from ..color import rgb2lab -cdef extern from "math.h": - double exp(double) - double sqrt(double) - - @cython.boundscheck(False) @cython.wraparound(False) @cython.cdivision(True) diff --git a/skimage/transform/_hough_transform.pyx b/skimage/transform/_hough_transform.pyx index b34b28e2..906e4464 100644 --- a/skimage/transform/_hough_transform.pyx +++ b/skimage/transform/_hough_transform.pyx @@ -2,27 +2,20 @@ cimport cython import numpy as np cimport numpy as np from random import randint +from libc.math cimport abs, fabs, sqrt, ceil, floor, round +from libc.stdlib cimport rand + + np.import_array() -cdef extern from "stdlib.h": - int rand() - -cdef extern from "math.h": - int abs(int) - double fabs(double) - double sqrt(double) - double ceil(double) - double floor(double) - -cdef double round(double val): - return floor(val + 0.5); cdef double PI_2 = 1.5707963267948966 cdef double NEG_PI_2 = -PI_2 + @cython.boundscheck(False) def _hough(np.ndarray img, np.ndarray[ndim=1, dtype=np.double_t] theta=None): - + if img.ndim != 2: raise ValueError('The input image must be 2D.') @@ -31,7 +24,7 @@ def _hough(np.ndarray img, np.ndarray[ndim=1, dtype=np.double_t] theta=None): cdef np.ndarray[ndim=1, dtype=np.double_t] stheta if theta is None: - theta = np.linspace(PI_2, NEG_PI_2, 180) + theta = np.linspace(PI_2, NEG_PI_2, 180) ctheta = np.cos(theta) stheta = np.sin(theta) @@ -39,14 +32,14 @@ def _hough(np.ndarray img, np.ndarray[ndim=1, dtype=np.double_t] theta=None): # compute the bins and allocate the accumulator array cdef np.ndarray[ndim=2, dtype=np.uint64_t] accum cdef np.ndarray[ndim=1, dtype=np.double_t] bins - cdef int max_distance, offset + cdef int max_distance, offset - max_distance = 2 * ceil((sqrt(img.shape[0] * img.shape[0] + + max_distance = 2 * ceil((sqrt(img.shape[0] * img.shape[0] + img.shape[1] * img.shape[1]))) accum = np.zeros((max_distance, theta.shape[0]), dtype=np.uint64) bins = np.linspace(-max_distance / 2.0, max_distance / 2.0, max_distance) offset = max_distance / 2 - + # compute the nonzero indexes cdef np.ndarray[ndim=1, dtype=np.npy_intp] x_idxs, y_idxs y_idxs, x_idxs = np.PyArray_Nonzero(img) @@ -58,7 +51,7 @@ def _hough(np.ndarray img, np.ndarray[ndim=1, dtype=np.double_t] theta=None): nthetas = theta.shape[0] for i in range(nidxs): x = x_idxs[i] - y = y_idxs[i] + y = y_idxs[i] for j in range(nthetas): accum_idx = round((ctheta[j] * x + stheta[j] * y)) + offset accum[accum_idx, j] += 1 @@ -94,7 +87,7 @@ def _probabilistic_hough(np.ndarray img, int value_threshold, int line_length, \ # maximum line number cutoff cdef int lines_max = 2 ** 15 cdef int xflag, x0, y0, dx0, dy0, dx, dy, gap, x1, y1, good_line, count - max_distance = 2 * ceil((sqrt(img.shape[0] * img.shape[0] + + max_distance = 2 * ceil((sqrt(img.shape[0] * img.shape[0] + img.shape[1] * img.shape[1]))) accum = np.zeros((max_distance, theta.shape[0]), dtype=np.int64) offset = max_distance / 2 @@ -114,11 +107,11 @@ def _probabilistic_hough(np.ndarray img, int value_threshold, int line_length, \ # select random non-zero point count = len(points) if count == 0: - break + break index = rand() % (count) x = points[index][0] y = points[index][1] - del points[index] + del points[index] # if previously eliminated, skip if not mask[y, x]: continue @@ -147,7 +140,7 @@ def _probabilistic_hough(np.ndarray img, int value_threshold, int line_length, \ dx0 = 1 else: dx0 = -1 - dy0 = round(b * (1 << shift) / fabs(a)) + dy0 = round(b * (1 << shift) / fabs(a)) y0 = (y0 << shift) + (1 << (shift - 1)) else: if b > 0: @@ -156,7 +149,7 @@ def _probabilistic_hough(np.ndarray img, int value_threshold, int line_length, \ dy0 = -1 dx0 = round(a * (1 << shift) / fabs(b)) x0 = (x0 << shift) + (1 << (shift - 1)) - + # pass 1: walk the line, merging lines less than specified gap length for k in range(2): gap = 0 @@ -208,9 +201,9 @@ def _probabilistic_hough(np.ndarray img, int value_threshold, int line_length, \ x1 = px >> shift y1 = py # if non-zero point found, continue the line - if mask[y1, x1]: - if good_line: - accum_idx = round((ctheta[j] * x1 + stheta[j] * y1)) + offset + if mask[y1, x1]: + if good_line: + accum_idx = round((ctheta[j] * x1 + stheta[j] * y1)) + offset accum[accum_idx, max_theta] -= 1 mask[y1, x1] = 0 # exit when the point is the line end