From 33a09c3b1a1727e8f63cc2fce926a460bd50c5c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Sch=C3=B6nberger?= Date: Fri, 12 Jul 2013 22:58:15 +0200 Subject: [PATCH] Add option to return double output image for rank filters --- skimage/filter/rank/bilateral.py | 9 +- skimage/filter/rank/bilateral_cy.pyx | 58 ++-- skimage/filter/rank/core_cy.pxd | 15 +- skimage/filter/rank/core_cy.pyx | 28 +- skimage/filter/rank/generic.py | 21 +- skimage/filter/rank/generic_cy.pyx | 427 +++++++++++--------------- skimage/filter/rank/percentile.py | 9 +- skimage/filter/rank/percentile_cy.pyx | 250 +++++++-------- 8 files changed, 362 insertions(+), 455 deletions(-) diff --git a/skimage/filter/rank/bilateral.py b/skimage/filter/rank/bilateral.py index f0bc2b38..f1b10fec 100644 --- a/skimage/filter/rank/bilateral.py +++ b/skimage/filter/rank/bilateral.py @@ -11,6 +11,9 @@ The pixel neighborhood is defined by: The kernel is flat (i.e. each pixel belonging to the neighborhood contributes equally). +Result image is 8-/16-bit or double with respect to the input image and the +rank filter operation. + References ---------- @@ -30,9 +33,11 @@ from .generic import _handle_input __all__ = ['mean_bilateral', 'pop_bilateral'] -def _apply(func, image, selem, out, mask, shift_x, shift_y, s0, s1): +def _apply(func, image, selem, out, mask, shift_x, shift_y, s0, s1, + out_dtype=None): - image, selem, out, mask, max_bin = _handle_input(image, selem, out, mask) + image, selem, out, mask, max_bin = _handle_input(image, selem, out, mask, + out_dtype) func(image, selem, shift_x=shift_x, shift_y=shift_y, mask=mask, out=out, max_bin=max_bin, s0=s0, s1=s1) diff --git a/skimage/filter/rank/bilateral_cy.pyx b/skimage/filter/rank/bilateral_cy.pyx index d93fdb3c..b8e0d1e7 100644 --- a/skimage/filter/rank/bilateral_cy.pyx +++ b/skimage/filter/rank/bilateral_cy.pyx @@ -6,14 +6,13 @@ cimport numpy as cnp from libc.math cimport log -from .core_cy cimport uint8_t, uint16_t, dtype_t, _core +from .core_cy cimport dtype_t, dtype_t_out, _core -cdef inline dtype_t _kernel_mean(Py_ssize_t* histo, float pop, - dtype_t g, - Py_ssize_t max_bin, Py_ssize_t mid_bin, - float p0, float p1, - Py_ssize_t s0, Py_ssize_t s1): +cdef inline float _kernel_mean(Py_ssize_t* histo, float pop, dtype_t g, + Py_ssize_t max_bin, Py_ssize_t mid_bin, + float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i cdef Py_ssize_t bilat_pop = 0 @@ -25,18 +24,17 @@ cdef inline dtype_t _kernel_mean(Py_ssize_t* histo, float pop, bilat_pop += histo[i] mean += histo[i] * i if bilat_pop: - return (mean / bilat_pop) + return mean / bilat_pop else: - return (0) + return 0 else: - return (0) + return 0 -cdef inline dtype_t _kernel_pop(Py_ssize_t* histo, float pop, - dtype_t g, - Py_ssize_t max_bin, Py_ssize_t mid_bin, - float p0, float p1, - Py_ssize_t s0, Py_ssize_t s1): +cdef inline float _kernel_pop(Py_ssize_t* histo, float pop, dtype_t g, + Py_ssize_t max_bin, Py_ssize_t mid_bin, + float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i cdef Py_ssize_t bilat_pop = 0 @@ -45,36 +43,28 @@ cdef inline dtype_t _kernel_pop(Py_ssize_t* histo, float pop, for i in range(max_bin): if (g > (i - s0)) and (g < (i + s1)): bilat_pop += histo[i] - return (bilat_pop) + return bilat_pop else: - return (0) + return 0 def _mean(dtype_t[:, ::1] image, char[:, ::1] selem, char[:, ::1] mask, - dtype_t[:, ::1] out, + dtype_t_out[:, ::1] out, char shift_x, char shift_y, Py_ssize_t s0, Py_ssize_t s1, Py_ssize_t max_bin): - if dtype_t is uint8_t: - _core[uint8_t](_kernel_mean[uint8_t], image, selem, mask, out, - shift_x, shift_y, 0, 0, s0, s1, max_bin) - elif dtype_t is uint16_t: - _core[uint16_t](_kernel_mean[uint16_t], image, selem, mask, out, - shift_x, shift_y, 0, 0, s0, s1, max_bin) + _core(_kernel_mean[dtype_t], image, selem, mask, out, + shift_x, shift_y, 0, 0, s0, s1, max_bin) def _pop(dtype_t[:, ::1] image, - char[:, ::1] selem, - char[:, ::1] mask, - dtype_t[:, ::1] out, - char shift_x, char shift_y, Py_ssize_t s0, Py_ssize_t s1, - Py_ssize_t max_bin): + char[:, ::1] selem, + char[:, ::1] mask, + dtype_t_out[:, ::1] out, + char shift_x, char shift_y, Py_ssize_t s0, Py_ssize_t s1, + Py_ssize_t max_bin): - if dtype_t is uint8_t: - _core[uint8_t](_kernel_pop[uint8_t], image, selem, mask, out, - shift_x, shift_y, 0, 0, s0, s1, max_bin) - elif dtype_t is uint16_t: - _core[uint16_t](_kernel_pop[uint16_t], image, selem, mask, out, - shift_x, shift_y, 0, 0, s0, s1, max_bin) + _core(_kernel_pop[dtype_t], image, selem, mask, out, + shift_x, shift_y, 0, 0, s0, s1, max_bin) diff --git a/skimage/filter/rank/core_cy.pxd b/skimage/filter/rank/core_cy.pxd index 544368a0..a1e44f98 100644 --- a/skimage/filter/rank/core_cy.pxd +++ b/skimage/filter/rank/core_cy.pxd @@ -1,22 +1,27 @@ -from numpy cimport uint8_t, uint16_t +from numpy cimport uint8_t, uint16_t, double_t ctypedef fused dtype_t: uint8_t uint16_t +ctypedef fused dtype_t_out: + uint8_t + uint16_t + double_t + cdef dtype_t _max(dtype_t a, dtype_t b) cdef dtype_t _min(dtype_t a, dtype_t b) -cdef void _core(dtype_t kernel(Py_ssize_t*, float, dtype_t, - Py_ssize_t, Py_ssize_t, float, - float, Py_ssize_t, Py_ssize_t), +cdef void _core(float kernel(Py_ssize_t*, float, dtype_t, + Py_ssize_t, Py_ssize_t, float, + float, Py_ssize_t, Py_ssize_t), dtype_t[:, ::1] image, char[:, ::1] selem, char[:, ::1] mask, - dtype_t[:, ::1] out, + dtype_t_out[:, ::1] out, char shift_x, char shift_y, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1, diff --git a/skimage/filter/rank/core_cy.pyx b/skimage/filter/rank/core_cy.pyx index 898e1775..854a3ce7 100644 --- a/skimage/filter/rank/core_cy.pyx +++ b/skimage/filter/rank/core_cy.pyx @@ -42,13 +42,13 @@ cdef inline char is_in_mask(Py_ssize_t rows, Py_ssize_t cols, return 0 -cdef void _core(dtype_t kernel(Py_ssize_t*, float, dtype_t, - Py_ssize_t, Py_ssize_t, float, - float, Py_ssize_t, Py_ssize_t), +cdef void _core(float kernel(Py_ssize_t*, float, dtype_t, + Py_ssize_t, Py_ssize_t, float, + float, Py_ssize_t, Py_ssize_t), dtype_t[:, ::1] image, char[:, ::1] selem, char[:, ::1] mask, - dtype_t[:, ::1] out, + dtype_t_out[:, ::1] out, char shift_x, char shift_y, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1, @@ -151,8 +151,8 @@ cdef void _core(dtype_t kernel(Py_ssize_t*, float, dtype_t, r = 0 c = 0 - out[r, c] = kernel(histo, pop, image[r, c], max_bin, mid_bin, - p0, p1, s0, s1) + out[r, c] = kernel(histo, pop, image[r, c], max_bin, mid_bin, + p0, p1, s0, s1) # main loop r = 0 @@ -172,8 +172,8 @@ cdef void _core(dtype_t kernel(Py_ssize_t*, float, dtype_t, if is_in_mask(rows, cols, rr, cc, mask_data): histogram_decrement(histo, &pop, image[rr, cc]) - out[r, c] = kernel(histo, pop, image[r, c], max_bin, - mid_bin, p0, p1, s0, s1) + out[r, c] = kernel(histo, pop, image[r, c], + max_bin, mid_bin, p0, p1, s0, s1) r += 1 # pass to the next row if r >= rows: @@ -192,8 +192,8 @@ cdef void _core(dtype_t kernel(Py_ssize_t*, float, dtype_t, if is_in_mask(rows, cols, rr, cc, mask_data): histogram_decrement(histo, &pop, image[rr, cc]) - out[r, c] = kernel(histo, pop, image[r, c], - max_bin, mid_bin, p0, p1, s0, s1) + out[r, c] = kernel(histo, pop, image[r, c], + max_bin, mid_bin, p0, p1, s0, s1) # ---> east to west for c in range(cols - 2, -1, -1): @@ -209,8 +209,8 @@ cdef void _core(dtype_t kernel(Py_ssize_t*, float, dtype_t, if is_in_mask(rows, cols, rr, cc, mask_data): histogram_decrement(histo, &pop, image[rr, cc]) - out[r, c] = kernel(histo, pop, image[r, c], max_bin, - mid_bin, p0, p1, s0, s1) + out[r, c] = kernel(histo, pop, image[r, c], + max_bin, mid_bin, p0, p1, s0, s1) r += 1 # pass to the next row if r >= rows: @@ -229,8 +229,8 @@ cdef void _core(dtype_t kernel(Py_ssize_t*, float, dtype_t, if is_in_mask(rows, cols, rr, cc, mask_data): histogram_decrement(histo, &pop, image[rr, cc]) - out[r, c] = kernel(histo, pop, image[r, c], max_bin, mid_bin, - p0, p1, s0, s1) + out[r, c] = kernel(histo, pop, image[r, c], + max_bin, mid_bin, p0, p1, s0, s1) # release memory allocated by malloc free(se_e_r) diff --git a/skimage/filter/rank/generic.py b/skimage/filter/rank/generic.py index 595a55ee..0bc8ca50 100644 --- a/skimage/filter/rank/generic.py +++ b/skimage/filter/rank/generic.py @@ -4,7 +4,8 @@ described in [1]_. Input image can be 8-bit or 16-bit, for 16-bit input images, the number of histogram bins is determined from the maximum value present in the image. -Result image is 8- or 16-bit with respect to the input image. +Result image is 8-/16-bit or double with respect to the input image and the +rank filter operation. References ---------- @@ -17,7 +18,7 @@ References import warnings import numpy as np -from skimage import img_as_ubyte, img_as_uint +from skimage import img_as_ubyte from . import generic_cy @@ -27,7 +28,7 @@ __all__ = ['autolevel', 'bottomhat', 'equalize', 'gradient', 'maximum', 'mean', 'pop', 'threshold', 'tophat', 'noise_filter', 'entropy', 'otsu'] -def _handle_input(image, selem, out, mask): +def _handle_input(image, selem, out, mask, out_dtype=None): if image.dtype not in (np.uint8, np.uint16): image = img_as_ubyte(image) @@ -42,7 +43,9 @@ def _handle_input(image, selem, out, mask): mask = np.ascontiguousarray(mask) if out is None: - out = np.empty_like(image, dtype=image.dtype) + if out_dtype is None: + out_dtype = image.dtype + out = np.empty_like(image, dtype=out_dtype) if image is out: raise NotImplementedError("Cannot perform rank operation in place.") @@ -62,9 +65,10 @@ def _handle_input(image, selem, out, mask): return image, selem, out, mask, max_bin -def _apply(func, image, selem, out, mask, shift_x, shift_y): +def _apply(func, image, selem, out, mask, shift_x, shift_y, out_dtype=None): - image, selem, out, mask, max_bin = _handle_input(image, selem, out, mask) + image, selem, out, mask, max_bin = _handle_input(image, selem, out, mask, + out_dtype) func(image, selem, shift_x=shift_x, shift_y=shift_y, mask=mask, out=out, max_bin=max_bin) @@ -668,7 +672,7 @@ def entropy(image, selem, out=None, mask=None, shift_x=False, shift_y=False): Returns ------- - out : ndarray (same dtype as input image) + out : ndarray (double) Output image. References @@ -687,7 +691,8 @@ def entropy(image, selem, out=None, mask=None, shift_x=False, shift_y=False): """ return _apply(generic_cy._entropy, image, selem, - out=out, mask=mask, shift_x=shift_x, shift_y=shift_y) + out=out, mask=mask, shift_x=shift_x, shift_y=shift_y, + out_dtype=np.double) def otsu(image, selem, out=None, mask=None, shift_x=False, shift_y=False): diff --git a/skimage/filter/rank/generic_cy.pyx b/skimage/filter/rank/generic_cy.pyx index ffb52cc8..47cb99da 100644 --- a/skimage/filter/rank/generic_cy.pyx +++ b/skimage/filter/rank/generic_cy.pyx @@ -6,13 +6,13 @@ cimport numpy as cnp from libc.math cimport log -from .core_cy cimport uint8_t, uint16_t, dtype_t, _core +from .core_cy cimport dtype_t, dtype_t_out, _core -cdef inline dtype_t _kernel_autolevel(Py_ssize_t* histo, float pop, dtype_t g, - Py_ssize_t max_bin, Py_ssize_t mid_bin, - float p0, float p1, - Py_ssize_t s0, Py_ssize_t s1): +cdef inline float _kernel_autolevel(Py_ssize_t* histo, float pop, dtype_t g, + Py_ssize_t max_bin, Py_ssize_t mid_bin, + float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i, imin, imax, delta @@ -27,17 +27,17 @@ cdef inline dtype_t _kernel_autolevel(Py_ssize_t* histo, float pop, dtype_t g, break delta = imax - imin if delta > 0: - return ((max_bin - 1) * (g - imin) / delta) + return (max_bin - 1) * (g - imin) / delta else: - return (imax - imin) + return imax - imin else: - return (0) + return 0 -cdef inline dtype_t _kernel_bottomhat(Py_ssize_t* histo, float pop, dtype_t g, - Py_ssize_t max_bin, Py_ssize_t mid_bin, - float p0, float p1, - Py_ssize_t s0, Py_ssize_t s1): +cdef inline float _kernel_bottomhat(Py_ssize_t* histo, float pop, dtype_t g, + Py_ssize_t max_bin, Py_ssize_t mid_bin, + float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i @@ -45,16 +45,15 @@ cdef inline dtype_t _kernel_bottomhat(Py_ssize_t* histo, float pop, dtype_t g, for i in range(max_bin): if histo[i]: break - - return (g - i) + return g - i else: - return (0) + return 0 -cdef inline dtype_t _kernel_equalize(Py_ssize_t* histo, float pop, dtype_t g, - Py_ssize_t max_bin, Py_ssize_t mid_bin, - float p0, float p1, - Py_ssize_t s0, Py_ssize_t s1): +cdef inline float _kernel_equalize(Py_ssize_t* histo, float pop, dtype_t g, + Py_ssize_t max_bin, Py_ssize_t mid_bin, + float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i cdef Py_ssize_t sum = 0 @@ -64,16 +63,15 @@ cdef inline dtype_t _kernel_equalize(Py_ssize_t* histo, float pop, dtype_t g, sum += histo[i] if i >= g: break - - return (((max_bin - 1) * sum) / pop) + return ((max_bin - 1) * sum) / pop else: - return (0) + return 0 -cdef inline dtype_t _kernel_gradient(Py_ssize_t* histo, float pop, dtype_t g, - Py_ssize_t max_bin, Py_ssize_t mid_bin, - float p0, float p1, - Py_ssize_t s0, Py_ssize_t s1): +cdef inline float _kernel_gradient(Py_ssize_t* histo, float pop, dtype_t g, + Py_ssize_t max_bin, Py_ssize_t mid_bin, + float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i, imin, imax @@ -86,64 +84,65 @@ cdef inline dtype_t _kernel_gradient(Py_ssize_t* histo, float pop, dtype_t g, if histo[i]: imin = i break - return (imax - imin) + return imax - imin else: - return (0) + return 0 -cdef inline dtype_t _kernel_maximum(Py_ssize_t* histo, float pop, dtype_t g, - Py_ssize_t max_bin, Py_ssize_t mid_bin, - float p0, float p1, - Py_ssize_t s0, Py_ssize_t s1): +cdef inline float _kernel_maximum(Py_ssize_t* histo, float pop, dtype_t g, + Py_ssize_t max_bin, Py_ssize_t mid_bin, + float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i if pop: for i in range(max_bin - 1, -1, -1): if histo[i]: - return (i) + return i else: - return (0) + return 0 -cdef inline dtype_t _kernel_mean(Py_ssize_t* histo, float pop, dtype_t g, +cdef inline float _kernel_mean(Py_ssize_t* histo, float pop,dtype_t g, + Py_ssize_t max_bin, Py_ssize_t mid_bin, + float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): + + cdef Py_ssize_t i + cdef Py_ssize_t mean = 0 + + if pop: + for i in range(max_bin): + mean += histo[i] * i + return mean / pop + else: + return 0 + + +cdef inline float _kernel_subtract_mean(Py_ssize_t* histo, float pop, + dtype_t g, + Py_ssize_t max_bin, + Py_ssize_t mid_bin, float p0, + float p1, Py_ssize_t s0, + Py_ssize_t s1): + + cdef Py_ssize_t i + cdef Py_ssize_t mean = 0 + + if pop: + for i in range(max_bin): + mean += histo[i] * i + return (g - mean / pop) / 2. + 127 + else: + return 0 + + +cdef inline float _kernel_median(Py_ssize_t* histo, float pop, dtype_t g, Py_ssize_t max_bin, Py_ssize_t mid_bin, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): - cdef Py_ssize_t i - cdef Py_ssize_t mean = 0 - - if pop: - for i in range(max_bin): - mean += histo[i] * i - return (mean / pop) - else: - return (0) - - -cdef inline dtype_t _kernel_subtract_mean(Py_ssize_t* histo, float pop, - dtype_t g, Py_ssize_t max_bin, - Py_ssize_t mid_bin, float p0, - float p1, Py_ssize_t s0, - Py_ssize_t s1): - - cdef Py_ssize_t i - cdef Py_ssize_t mean = 0 - - if pop: - for i in range(max_bin): - mean += histo[i] * i - return ((g - mean / pop) / 2. + 127) - else: - return (0) - - -cdef inline dtype_t _kernel_median(Py_ssize_t* histo, float pop, dtype_t g, - Py_ssize_t max_bin, Py_ssize_t mid_bin, - float p0, float p1, - Py_ssize_t s0, Py_ssize_t s1): - cdef Py_ssize_t i cdef float sum = pop / 2.0 @@ -152,30 +151,30 @@ cdef inline dtype_t _kernel_median(Py_ssize_t* histo, float pop, dtype_t g, if histo[i]: sum -= histo[i] if sum < 0: - return (i) + return i else: - return (0) + return 0 -cdef inline dtype_t _kernel_minimum(Py_ssize_t* histo, float pop, dtype_t g, - Py_ssize_t max_bin, Py_ssize_t mid_bin, - float p0, float p1, - Py_ssize_t s0, Py_ssize_t s1): +cdef inline float _kernel_minimum(Py_ssize_t* histo, float pop, dtype_t g, + Py_ssize_t max_bin, Py_ssize_t mid_bin, + float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i if pop: for i in range(max_bin): if histo[i]: - return (i) + return i else: - return (0) + return 0 -cdef inline dtype_t _kernel_modal(Py_ssize_t* histo, float pop, dtype_t g, - Py_ssize_t max_bin, Py_ssize_t mid_bin, - float p0, float p1, - Py_ssize_t s0, Py_ssize_t s1): +cdef inline float _kernel_modal(Py_ssize_t* histo, float pop, dtype_t g, + Py_ssize_t max_bin, Py_ssize_t mid_bin, + float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t hmax = 0, imax = 0 @@ -184,16 +183,17 @@ cdef inline dtype_t _kernel_modal(Py_ssize_t* histo, float pop, dtype_t g, if histo[i] > hmax: hmax = histo[i] imax = i - return (imax) + return imax else: - return (0) + return 0 -cdef inline dtype_t _kernel_enhance_contrast(Py_ssize_t* histo, float pop, - dtype_t g, Py_ssize_t max_bin, - Py_ssize_t mid_bin, float p0, - float p1, Py_ssize_t s0, - Py_ssize_t s1): +cdef inline float _kernel_enhance_contrast(Py_ssize_t* histo, float pop, + dtype_t g, + Py_ssize_t max_bin, + Py_ssize_t mid_bin, float p0, + float p1, Py_ssize_t s0, + Py_ssize_t s1): cdef Py_ssize_t i, imin, imax @@ -207,25 +207,25 @@ cdef inline dtype_t _kernel_enhance_contrast(Py_ssize_t* histo, float pop, imin = i break if imax - g < g - imin: - return (imax) + return imax else: - return (imin) + return imin else: - return (0) + return 0 -cdef inline dtype_t _kernel_pop(Py_ssize_t* histo, float pop, dtype_t g, - Py_ssize_t max_bin, Py_ssize_t mid_bin, - float p0, float p1, - Py_ssize_t s0, Py_ssize_t s1): +cdef inline float _kernel_pop(Py_ssize_t* histo, float pop, dtype_t g, + Py_ssize_t max_bin, Py_ssize_t mid_bin, + float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): - return (pop) + return pop -cdef inline dtype_t _kernel_threshold(Py_ssize_t* histo, float pop, dtype_t g, - Py_ssize_t max_bin, Py_ssize_t mid_bin, - float p0, float p1, - Py_ssize_t s0, Py_ssize_t s1): +cdef inline float _kernel_threshold(Py_ssize_t* histo, float pop, dtype_t g, + Py_ssize_t max_bin, Py_ssize_t mid_bin, + float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i cdef Py_ssize_t mean = 0 @@ -233,15 +233,15 @@ cdef inline dtype_t _kernel_threshold(Py_ssize_t* histo, float pop, dtype_t g, if pop: for i in range(max_bin): mean += histo[i] * i - return (g > (mean / pop)) + return g > (mean / pop) else: - return (0) + return 0 -cdef inline dtype_t _kernel_tophat(Py_ssize_t* histo, float pop, dtype_t g, - Py_ssize_t max_bin, Py_ssize_t mid_bin, - float p0, float p1, - Py_ssize_t s0, Py_ssize_t s1): +cdef inline float _kernel_tophat(Py_ssize_t* histo, float pop, dtype_t g, + Py_ssize_t max_bin, Py_ssize_t mid_bin, + float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i @@ -249,23 +249,22 @@ cdef inline dtype_t _kernel_tophat(Py_ssize_t* histo, float pop, dtype_t g, for i in range(max_bin - 1, -1, -1): if histo[i]: break - - return (i - g) + return i - g else: - return (0) + return 0 -cdef inline dtype_t _kernel_noise_filter(Py_ssize_t* histo, float pop, - dtype_t g, Py_ssize_t max_bin, - Py_ssize_t mid_bin, float p0, float p1, - Py_ssize_t s0, Py_ssize_t s1): +cdef inline float _kernel_noise_filter(Py_ssize_t* histo, float pop, dtype_t g, + Py_ssize_t max_bin, + Py_ssize_t mid_bin, float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i cdef Py_ssize_t min_i # early stop if at least one pixel of the neighborhood has the same g if histo[g] > 0: - return 0 + return 0 for i in range(g, -1, -1): if histo[i]: @@ -275,35 +274,33 @@ cdef inline dtype_t _kernel_noise_filter(Py_ssize_t* histo, float pop, if histo[i]: break if i - g < min_i: - return (i - g) + return i - g else: - return min_i + return min_i -cdef inline dtype_t _kernel_entropy(Py_ssize_t* histo, float pop, dtype_t g, - Py_ssize_t max_bin, Py_ssize_t mid_bin, - float p0, float p1, - Py_ssize_t s0, Py_ssize_t s1): +cdef inline float _kernel_entropy(Py_ssize_t* histo, float pop, dtype_t g, + Py_ssize_t max_bin, Py_ssize_t mid_bin, + float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i cdef float e, p if pop: e = 0. - for i in range(max_bin): p = histo[i] / pop if p > 0: e -= p * log(p) / 0.6931471805599453 - - return e + return e else: - return (0) + return 0 -cdef inline dtype_t _kernel_otsu(Py_ssize_t* histo, float pop, dtype_t g, - Py_ssize_t max_bin, Py_ssize_t mid_bin, - float p0, float p1, - Py_ssize_t s0, Py_ssize_t s1): +cdef inline float _kernel_otsu(Py_ssize_t* histo, float pop, dtype_t g, + Py_ssize_t max_bin, Py_ssize_t mid_bin, + float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i cdef Py_ssize_t max_i cdef float P, mu1, mu2, q1, new_q1, sigma_b, max_sigma_b @@ -313,9 +310,9 @@ cdef inline dtype_t _kernel_otsu(Py_ssize_t* histo, float pop, dtype_t g, if pop: for i in range(max_bin): mu += histo[i] * i - mu = (mu / pop) + mu = mu / pop else: - return (0) + return 0 # maximizing the between class variance max_i = 0 @@ -335,242 +332,174 @@ cdef inline dtype_t _kernel_otsu(Py_ssize_t* histo, float pop, dtype_t g, max_i = i q1 = new_q1 - return max_i + return max_i def _autolevel(dtype_t[:, ::1] image, char[:, ::1] selem, char[:, ::1] mask, - dtype_t[:, ::1] out, + dtype_t_out[:, ::1] out, char shift_x, char shift_y, Py_ssize_t max_bin): - if dtype_t is uint8_t: - _core[uint8_t](_kernel_autolevel[uint8_t], image, selem, mask, out, - shift_x, shift_y, 0, 0, 0, 0, max_bin) - elif dtype_t is uint16_t: - _core[uint16_t](_kernel_autolevel[uint16_t], image, selem, mask, out, - shift_x, shift_y, 0, 0, 0, 0, max_bin) + _core(_kernel_autolevel[dtype_t], image, selem, mask, out, + shift_x, shift_y, 0, 0, 0, 0, max_bin) def _bottomhat(dtype_t[:, ::1] image, char[:, ::1] selem, char[:, ::1] mask, - dtype_t[:, ::1] out, + dtype_t_out[:, ::1] out, char shift_x, char shift_y, Py_ssize_t max_bin): - if dtype_t is uint8_t: - _core[uint8_t](_kernel_bottomhat[uint8_t], image, selem, mask, out, - shift_x, shift_y, 0, 0, 0, 0, max_bin) - elif dtype_t is uint16_t: - _core[uint16_t](_kernel_bottomhat[uint16_t], image, selem, mask, out, - shift_x, shift_y, 0, 0, 0, 0, max_bin) + _core(_kernel_bottomhat[dtype_t], image, selem, mask, out, + shift_x, shift_y, 0, 0, 0, 0, max_bin) def _equalize(dtype_t[:, ::1] image, char[:, ::1] selem, char[:, ::1] mask, - dtype_t[:, ::1] out, + dtype_t_out[:, ::1] out, char shift_x, char shift_y, Py_ssize_t max_bin): - if dtype_t is uint8_t: - _core[uint8_t](_kernel_equalize[uint8_t], image, selem, mask, out, - shift_x, shift_y, 0, 0, 0, 0, max_bin) - elif dtype_t is uint16_t: - _core[uint16_t](_kernel_equalize[uint16_t], image, selem, mask, out, - shift_x, shift_y, 0, 0, 0, 0, max_bin) + _core(_kernel_equalize[dtype_t], image, selem, mask, out, + shift_x, shift_y, 0, 0, 0, 0, max_bin) def _gradient(dtype_t[:, ::1] image, char[:, ::1] selem, char[:, ::1] mask, - dtype_t[:, ::1] out, + dtype_t_out[:, ::1] out, char shift_x, char shift_y, Py_ssize_t max_bin): - if dtype_t is uint8_t: - _core[uint8_t](_kernel_gradient[uint8_t], image, selem, mask, out, - shift_x, shift_y, 0, 0, 0, 0, max_bin) - elif dtype_t is uint16_t: - _core[uint16_t](_kernel_gradient[uint16_t], image, selem, mask, out, - shift_x, shift_y, 0, 0, 0, 0, max_bin) + _core(_kernel_gradient[dtype_t], image, selem, mask, out, + shift_x, shift_y, 0, 0, 0, 0, max_bin) def _maximum(dtype_t[:, ::1] image, char[:, ::1] selem, char[:, ::1] mask, - dtype_t[:, ::1] out, + dtype_t_out[:, ::1] out, char shift_x, char shift_y, Py_ssize_t max_bin): - if dtype_t is uint8_t: - _core[uint8_t](_kernel_maximum[uint8_t], image, selem, mask, out, - shift_x, shift_y, 0, 0, 0, 0, max_bin) - elif dtype_t is uint16_t: - _core[uint16_t](_kernel_maximum[uint16_t], image, selem, mask, out, - shift_x, shift_y, 0, 0, 0, 0, max_bin) + _core(_kernel_maximum[dtype_t], image, selem, mask, out, + shift_x, shift_y, 0, 0, 0, 0, max_bin) def _mean(dtype_t[:, ::1] image, char[:, ::1] selem, char[:, ::1] mask, - dtype_t[:, ::1] out, + dtype_t_out[:, ::1] out, char shift_x, char shift_y, Py_ssize_t max_bin): - if dtype_t is uint8_t: - _core[uint8_t](_kernel_mean[uint8_t], image, selem, mask, out, - shift_x, shift_y, 0, 0, 0, 0, max_bin) - elif dtype_t is uint16_t: - _core[uint16_t](_kernel_mean[uint16_t], image, selem, mask, out, - shift_x, shift_y, 0, 0, 0, 0, max_bin) + _core(_kernel_mean[dtype_t], image, selem, mask, out, + shift_x, shift_y, 0, 0, 0, 0, max_bin) def _subtract_mean(dtype_t[:, ::1] image, char[:, ::1] selem, char[:, ::1] mask, - dtype_t[:, ::1] out, + dtype_t_out[:, ::1] out, char shift_x, char shift_y, Py_ssize_t max_bin): - if dtype_t is uint8_t: - _core[uint8_t](_kernel_subtract_mean[uint8_t], image, selem, mask, - out, shift_x, shift_y, 0, 0, 0, 0, max_bin) - elif dtype_t is uint16_t: - _core[uint16_t](_kernel_subtract_mean[uint16_t], image, selem, mask, - out, shift_x, shift_y, 0, 0, 0, 0, max_bin) + _core(_kernel_subtract_mean[dtype_t], image, selem, mask, + out, shift_x, shift_y, 0, 0, 0, 0, max_bin) def _median(dtype_t[:, ::1] image, char[:, ::1] selem, char[:, ::1] mask, - dtype_t[:, ::1] out, + dtype_t_out[:, ::1] out, char shift_x, char shift_y, Py_ssize_t max_bin): - if dtype_t is uint8_t: - _core[uint8_t](_kernel_median[uint8_t], image, selem, mask, out, - shift_x, shift_y, 0, 0, 0, 0, max_bin) - elif dtype_t is uint16_t: - _core[uint16_t](_kernel_median[uint16_t], image, selem, mask, out, - shift_x, shift_y, 0, 0, 0, 0, max_bin) + _core(_kernel_median[dtype_t], image, selem, mask, out, + shift_x, shift_y, 0, 0, 0, 0, max_bin) def _minimum(dtype_t[:, ::1] image, char[:, ::1] selem, char[:, ::1] mask, - dtype_t[:, ::1] out, + dtype_t_out[:, ::1] out, char shift_x, char shift_y, Py_ssize_t max_bin): - if dtype_t is uint8_t: - _core[uint8_t](_kernel_minimum[uint8_t], image, selem, mask, out, - shift_x, shift_y, 0, 0, 0, 0, max_bin) - elif dtype_t is uint16_t: - _core[uint16_t](_kernel_minimum[uint16_t], image, selem, mask, out, - shift_x, shift_y, 0, 0, 0, 0, max_bin) + _core(_kernel_minimum[dtype_t], image, selem, mask, out, + shift_x, shift_y, 0, 0, 0, 0, max_bin) def _enhance_contrast(dtype_t[:, ::1] image, char[:, ::1] selem, char[:, ::1] mask, - dtype_t[:, ::1] out, + dtype_t_out[:, ::1] out, char shift_x, char shift_y, Py_ssize_t max_bin): - if dtype_t is uint8_t: - _core[uint8_t](_kernel_enhance_contrast[uint8_t], image, selem, mask, - out, shift_x, shift_y, 0, 0, 0, 0, max_bin) - elif dtype_t is uint16_t: - _core[uint16_t](_kernel_enhance_contrast[uint16_t], image, selem, mask, - out, shift_x, shift_y, 0, 0, 0, 0, max_bin) + _core(_kernel_enhance_contrast[dtype_t], image, selem, mask, + out, shift_x, shift_y, 0, 0, 0, 0, max_bin) def _modal(dtype_t[:, ::1] image, char[:, ::1] selem, char[:, ::1] mask, - dtype_t[:, ::1] out, + dtype_t_out[:, ::1] out, char shift_x, char shift_y, Py_ssize_t max_bin): - if dtype_t is uint8_t: - _core[uint8_t](_kernel_modal[uint8_t], image, selem, mask, out, - shift_x, shift_y, 0, 0, 0, 0, max_bin) - elif dtype_t is uint16_t: - _core[uint16_t](_kernel_modal[uint16_t], image, selem, mask, out, - shift_x, shift_y, 0, 0, 0, 0, max_bin) + _core(_kernel_modal[dtype_t], image, selem, mask, out, + shift_x, shift_y, 0, 0, 0, 0, max_bin) def _pop(dtype_t[:, ::1] image, char[:, ::1] selem, char[:, ::1] mask, - dtype_t[:, ::1] out, + dtype_t_out[:, ::1] out, char shift_x, char shift_y, Py_ssize_t max_bin): - if dtype_t is uint8_t: - _core[uint8_t](_kernel_pop[uint8_t], image, selem, mask, out, - shift_x, shift_y, 0, 0, 0, 0, max_bin) - elif dtype_t is uint16_t: - _core[uint16_t](_kernel_pop[uint16_t], image, selem, mask, out, - shift_x, shift_y, 0, 0, 0, 0, max_bin) + _core(_kernel_pop[dtype_t], image, selem, mask, out, + shift_x, shift_y, 0, 0, 0, 0, max_bin) def _threshold(dtype_t[:, ::1] image, char[:, ::1] selem, char[:, ::1] mask, - dtype_t[:, ::1] out, + dtype_t_out[:, ::1] out, char shift_x, char shift_y, Py_ssize_t max_bin): - if dtype_t is uint8_t: - _core[uint8_t](_kernel_threshold[uint8_t], image, selem, mask, out, - shift_x, shift_y, 0, 0, 0, 0, max_bin) - elif dtype_t is uint16_t: - _core[uint16_t](_kernel_threshold[uint16_t], image, selem, mask, out, - shift_x, shift_y, 0, 0, 0, 0, max_bin) + _core(_kernel_threshold[dtype_t], image, selem, mask, out, + shift_x, shift_y, 0, 0, 0, 0, max_bin) def _tophat(dtype_t[:, ::1] image, char[:, ::1] selem, char[:, ::1] mask, - dtype_t[:, ::1] out, + dtype_t_out[:, ::1] out, char shift_x, char shift_y, Py_ssize_t max_bin): - if dtype_t is uint8_t: - _core[uint8_t](_kernel_tophat[uint8_t], image, selem, mask, out, - shift_x, shift_y, 0, 0, 0, 0, max_bin) - elif dtype_t is uint16_t: - _core[uint16_t](_kernel_tophat[uint16_t], image, selem, mask, out, - shift_x, shift_y, 0, 0, 0, 0, max_bin) + _core(_kernel_tophat[dtype_t], image, selem, mask, out, + shift_x, shift_y, 0, 0, 0, 0, max_bin) def _noise_filter(dtype_t[:, ::1] image, char[:, ::1] selem, char[:, ::1] mask, - dtype_t[:, ::1] out, + dtype_t_out[:, ::1] out, char shift_x, char shift_y, Py_ssize_t max_bin): - if dtype_t is uint8_t: - _core[uint8_t](_kernel_noise_filter[uint8_t], image, selem, mask, out, - shift_x, shift_y, 0, 0, 0, 0, max_bin) - elif dtype_t is uint16_t: - _core[uint16_t](_kernel_noise_filter[uint16_t], image, selem, mask, out, - shift_x, shift_y, 0, 0, 0, 0, max_bin) + _core(_kernel_noise_filter[dtype_t], image, selem, mask, out, + shift_x, shift_y, 0, 0, 0, 0, max_bin) def _entropy(dtype_t[:, ::1] image, char[:, ::1] selem, char[:, ::1] mask, - dtype_t[:, ::1] out, + dtype_t_out[:, ::1] out, char shift_x, char shift_y, Py_ssize_t max_bin): - if dtype_t is uint8_t: - _core[uint8_t](_kernel_entropy[uint8_t], image, selem, mask, out, - shift_x, shift_y, 0, 0, 0, 0, max_bin) - elif dtype_t is uint16_t: - _core[uint16_t](_kernel_entropy[uint16_t], image, selem, mask, out, - shift_x, shift_y, 0, 0, 0, 0, max_bin) + _core(_kernel_entropy[dtype_t], image, selem, mask, out, + shift_x, shift_y, 0, 0, 0, 0, max_bin) def _otsu(dtype_t[:, ::1] image, char[:, ::1] selem, char[:, ::1] mask, - dtype_t[:, ::1] out, + dtype_t_out[:, ::1] out, char shift_x, char shift_y, Py_ssize_t max_bin): - if dtype_t is uint8_t: - _core[uint8_t](_kernel_otsu[uint8_t], image, selem, mask, out, - shift_x, shift_y, 0, 0, 0, 0, max_bin) - elif dtype_t is uint16_t: - _core[uint16_t](_kernel_otsu[uint16_t], image, selem, mask, out, - shift_x, shift_y, 0, 0, 0, 0, max_bin) + _core(_kernel_otsu[dtype_t], image, selem, mask, out, + shift_x, shift_y, 0, 0, 0, 0, max_bin) diff --git a/skimage/filter/rank/percentile.py b/skimage/filter/rank/percentile.py index e91e0d82..ff3b1559 100644 --- a/skimage/filter/rank/percentile.py +++ b/skimage/filter/rank/percentile.py @@ -10,7 +10,8 @@ described in [1]_. Input image can be 8-bit or 16-bit, for 16-bit input images, the number of histogram bins is determined from the maximum value present in the image. -Result image is 8 or 16-bit with respect to the input image. +Result image is 8-/16-bit or double with respect to the input image and the +rank filter operation. References ---------- @@ -33,9 +34,11 @@ __all__ = ['autolevel_percentile', 'gradient_percentile', 'threshold_percentile'] -def _apply(func, image, selem, out, mask, shift_x, shift_y, p0, p1): +def _apply(func, image, selem, out, mask, shift_x, shift_y, p0, p1, + out_dtype=None): - image, selem, out, mask, max_bin = _handle_input(image, selem, out, mask) + image, selem, out, mask, max_bin = _handle_input(image, selem, out, mask, + out_dtype) func(image, selem, shift_x=shift_x, shift_y=shift_y, mask=mask, out=out, max_bin=max_bin, p0=p0, p1=p1) diff --git a/skimage/filter/rank/percentile_cy.pyx b/skimage/filter/rank/percentile_cy.pyx index bb4419de..664985f9 100644 --- a/skimage/filter/rank/percentile_cy.pyx +++ b/skimage/filter/rank/percentile_cy.pyx @@ -4,13 +4,13 @@ #cython: wraparound=False cimport numpy as cnp -from .core_cy cimport uint8_t, uint16_t, dtype_t, _core, _min, _max +from .core_cy cimport dtype_t, dtype_t_out, _core, _min, _max -cdef inline dtype_t _kernel_autolevel(Py_ssize_t* histo, float pop, dtype_t g, - Py_ssize_t max_bin, Py_ssize_t mid_bin, - float p0, float p1, - Py_ssize_t s0, Py_ssize_t s1): +cdef inline float _kernel_autolevel(Py_ssize_t* histo, float pop, dtype_t g, + Py_ssize_t max_bin, Py_ssize_t mid_bin, + float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i, imin, imax, sum, delta @@ -31,18 +31,18 @@ cdef inline dtype_t _kernel_autolevel(Py_ssize_t* histo, float pop, dtype_t g, delta = imax - imin if delta > 0: - return ((max_bin - 1) * (_min(_max(imin, g), imax) - - imin) / delta) + return (max_bin - 1) * (_min(_max(imin, g), imax) + - imin) / delta else: - return (imax - imin) + return imax - imin else: - return (0) + return 0 -cdef inline dtype_t _kernel_gradient(Py_ssize_t* histo, float pop, dtype_t g, - Py_ssize_t max_bin, Py_ssize_t mid_bin, - float p0, float p1, - Py_ssize_t s0, Py_ssize_t s1): +cdef inline float _kernel_gradient(Py_ssize_t* histo, float pop, dtype_t g, + Py_ssize_t max_bin, Py_ssize_t mid_bin, + float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i, imin, imax, sum, delta @@ -61,15 +61,15 @@ cdef inline dtype_t _kernel_gradient(Py_ssize_t* histo, float pop, dtype_t g, imax = i break - return (imax - imin) + return imax - imin else: - return (0) + return 0 -cdef inline dtype_t _kernel_mean(Py_ssize_t* histo, float pop, dtype_t g, - Py_ssize_t max_bin, Py_ssize_t mid_bin, - float p0, float p1, - Py_ssize_t s0, Py_ssize_t s1): +cdef inline float _kernel_mean(Py_ssize_t* histo, float pop, dtype_t g, + Py_ssize_t max_bin, Py_ssize_t mid_bin, + float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i, sum, mean, n @@ -84,18 +84,19 @@ cdef inline dtype_t _kernel_mean(Py_ssize_t* histo, float pop, dtype_t g, mean += histo[i] * i if n > 0: - return (mean / n) + return mean / n else: - return (0) + return 0 else: - return (0) + return 0 -cdef inline dtype_t _kernel_subtract_mean(Py_ssize_t* histo, float pop, - dtype_t g, Py_ssize_t max_bin, - Py_ssize_t mid_bin, float p0, - float p1, Py_ssize_t s0, - Py_ssize_t s1): +cdef inline float _kernel_subtract_mean(Py_ssize_t* histo, float pop, + dtype_t g, + Py_ssize_t max_bin, + Py_ssize_t mid_bin, float p0, + float p1, Py_ssize_t s0, + Py_ssize_t s1): cdef Py_ssize_t i, sum, mean, n @@ -109,18 +110,19 @@ cdef inline dtype_t _kernel_subtract_mean(Py_ssize_t* histo, float pop, n += histo[i] mean += histo[i] * i if n > 0: - return ((g - (mean / n)) * .5 + mid_bin) + return (g - (mean / n)) * .5 + mid_bin else: - return (0) + return 0 else: - return (0) + return 0 -cdef inline dtype_t _kernel_enhance_contrast(Py_ssize_t* histo, float pop, - dtype_t g, Py_ssize_t max_bin, - Py_ssize_t mid_bin, float p0, - float p1, Py_ssize_t s0, - Py_ssize_t s1): +cdef inline float _kernel_enhance_contrast(Py_ssize_t* histo, float pop, + dtype_t g, + Py_ssize_t max_bin, + Py_ssize_t mid_bin, float p0, + float p1, Py_ssize_t s0, + Py_ssize_t s1): cdef Py_ssize_t i, imin, imax, sum, delta @@ -139,21 +141,21 @@ cdef inline dtype_t _kernel_enhance_contrast(Py_ssize_t* histo, float pop, imax = i break if g > imax: - return imax + return imax if g < imin: - return imin + return imin if imax - g < g - imin: - return imax + return imax else: - return imin + return imin else: - return (0) + return 0 -cdef inline dtype_t _kernel_percentile(Py_ssize_t* histo, float pop, dtype_t g, - Py_ssize_t max_bin, Py_ssize_t mid_bin, - float p0, float p1, - Py_ssize_t s0, Py_ssize_t s1): +cdef inline float _kernel_percentile(Py_ssize_t* histo, float pop, dtype_t g, + Py_ssize_t max_bin, Py_ssize_t mid_bin, + float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i cdef Py_ssize_t sum = 0 @@ -164,15 +166,15 @@ cdef inline dtype_t _kernel_percentile(Py_ssize_t* histo, float pop, dtype_t g, if sum >= p0 * pop: break - return (i) + return i else: - return (0) + return 0 -cdef inline dtype_t _kernel_pop(Py_ssize_t* histo, float pop, dtype_t g, - Py_ssize_t max_bin, Py_ssize_t mid_bin, - float p0, float p1, - Py_ssize_t s0, Py_ssize_t s1): +cdef inline float _kernel_pop(Py_ssize_t* histo, float pop, dtype_t g, + Py_ssize_t max_bin, Py_ssize_t mid_bin, + float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i, sum, n @@ -183,15 +185,15 @@ cdef inline dtype_t _kernel_pop(Py_ssize_t* histo, float pop, dtype_t g, sum += histo[i] if (sum >= p0 * pop) and (sum <= p1 * pop): n += histo[i] - return (n) + return n else: - return (0) + return 0 -cdef inline dtype_t _kernel_threshold(Py_ssize_t* histo, float pop, dtype_t g, - Py_ssize_t max_bin, Py_ssize_t mid_bin, - float p0, float p1, - Py_ssize_t s0, Py_ssize_t s1): +cdef inline float _kernel_threshold(Py_ssize_t* histo, float pop, dtype_t g, + Py_ssize_t max_bin, Py_ssize_t mid_bin, + float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef int i cdef Py_ssize_t sum = 0 @@ -202,124 +204,92 @@ cdef inline dtype_t _kernel_threshold(Py_ssize_t* histo, float pop, dtype_t g, if sum >= p0 * pop: break - return ((max_bin - 1) * (g >= i)) + return (max_bin - 1) * (g >= i) else: - return (0) + return 0 def _autolevel(dtype_t[:, ::1] image, - char[:, ::1] selem, - char[:, ::1] mask, - dtype_t[:, ::1] out, - char shift_x, char shift_y, float p0, float p1, - Py_ssize_t max_bin): + char[:, ::1] selem, + char[:, ::1] mask, + dtype_t_out[:, ::1] out, + char shift_x, char shift_y, float p0, float p1, + Py_ssize_t max_bin): - if dtype_t is uint8_t: - _core[uint8_t](_kernel_autolevel[uint8_t], image, selem, mask, out, - shift_x, shift_y, p0, p1, 0, 0, max_bin) - elif dtype_t is uint16_t: - _core[uint16_t](_kernel_autolevel[uint16_t], image, selem, mask, out, - shift_x, shift_y, p0, p1, 0, 0, max_bin) + _core(_kernel_autolevel[dtype_t], image, selem, mask, out, + shift_x, shift_y, p0, p1, 0, 0, max_bin) def _gradient(dtype_t[:, ::1] image, - char[:, ::1] selem, - char[:, ::1] mask, - dtype_t[:, ::1] out, - char shift_x, char shift_y, float p0, float p1, - Py_ssize_t max_bin): + char[:, ::1] selem, + char[:, ::1] mask, + dtype_t_out[:, ::1] out, + char shift_x, char shift_y, float p0, float p1, + Py_ssize_t max_bin): - if dtype_t is uint8_t: - _core[uint8_t](_kernel_gradient[uint8_t], image, selem, mask, out, - shift_x, shift_y, p0, p1, 0, 0, max_bin) - elif dtype_t is uint16_t: - _core[uint16_t](_kernel_gradient[uint16_t], image, selem, mask, out, - shift_x, shift_y, p0, p1, 0, 0, max_bin) + _core(_kernel_gradient[dtype_t], image, selem, mask, out, + shift_x, shift_y, p0, p1, 0, 0, max_bin) def _mean(dtype_t[:, ::1] image, - char[:, ::1] selem, - char[:, ::1] mask, - dtype_t[:, ::1] out, - char shift_x, char shift_y, float p0, float p1, - Py_ssize_t max_bin): + char[:, ::1] selem, + char[:, ::1] mask, + dtype_t_out[:, ::1] out, + char shift_x, char shift_y, float p0, float p1, + Py_ssize_t max_bin): - if dtype_t is uint8_t: - _core[uint8_t](_kernel_mean[uint8_t], image, selem, mask, out, - shift_x, shift_y, p0, p1, 0, 0, max_bin) - elif dtype_t is uint16_t: - _core[uint16_t](_kernel_mean[uint16_t], image, selem, mask, out, - shift_x, shift_y, p0, p1, 0, 0, max_bin) + _core(_kernel_mean[dtype_t], image, selem, mask, out, + shift_x, shift_y, p0, p1, 0, 0, max_bin) def _subtract_mean(dtype_t[:, ::1] image, char[:, ::1] selem, char[:, ::1] mask, - dtype_t[:, ::1] out, + dtype_t_out[:, ::1] out, char shift_x, char shift_y, float p0, float p1, Py_ssize_t max_bin): - if dtype_t is uint8_t: - _core[uint8_t](_kernel_subtract_mean[uint8_t], image, selem, mask, - out, shift_x, shift_y, p0, p1, 0, 0, max_bin) - elif dtype_t is uint16_t: - _core[uint16_t](_kernel_subtract_mean[uint16_t], image, selem, mask, - out, shift_x, shift_y, p0, p1, 0, 0, max_bin) + _core(_kernel_subtract_mean[dtype_t], image, selem, mask, + out, shift_x, shift_y, p0, p1, 0, 0, max_bin) def _enhance_contrast(dtype_t[:, ::1] image, - char[:, ::1] selem, - char[:, ::1] mask, - dtype_t[:, ::1] out, - char shift_x, char shift_y, float p0, float p1, - Py_ssize_t max_bin): + char[:, ::1] selem, + char[:, ::1] mask, + dtype_t_out[:, ::1] out, + char shift_x, char shift_y, float p0, float p1, + Py_ssize_t max_bin): - if dtype_t is uint8_t: - _core[uint8_t](_kernel_enhance_contrast[uint8_t], image, selem, mask, - out, shift_x, shift_y, p0, p1, 0, 0, max_bin) - elif dtype_t is uint16_t: - _core[uint16_t](_kernel_enhance_contrast[uint16_t], image, selem, mask, - out, shift_x, shift_y, p0, p1, 0, 0, max_bin) + _core(_kernel_enhance_contrast[dtype_t], image, selem, mask, + out, shift_x, shift_y, p0, p1, 0, 0, max_bin) def _percentile(dtype_t[:, ::1] image, - char[:, ::1] selem, - char[:, ::1] mask, - dtype_t[:, ::1] out, - char shift_x, char shift_y, float p0, Py_ssize_t max_bin): + char[:, ::1] selem, + char[:, ::1] mask, + dtype_t_out[:, ::1] out, + char shift_x, char shift_y, float p0, Py_ssize_t max_bin): - if dtype_t is uint8_t: - _core[uint8_t](_kernel_percentile[uint8_t], image, selem, mask, out, - shift_x, shift_y, p0, 1, 0, 0, max_bin) - elif dtype_t is uint16_t: - _core[uint16_t](_kernel_percentile[uint16_t], image, selem, mask, out, - shift_x, shift_y, p0, 1, 0, 0, max_bin) + _core(_kernel_percentile[dtype_t], image, selem, mask, out, + shift_x, shift_y, p0, 1, 0, 0, max_bin) def _pop(dtype_t[:, ::1] image, - char[:, ::1] selem, - char[:, ::1] mask, - dtype_t[:, ::1] out, - char shift_x, char shift_y, float p0, float p1, - Py_ssize_t max_bin): + char[:, ::1] selem, + char[:, ::1] mask, + dtype_t_out[:, ::1] out, + char shift_x, char shift_y, float p0, float p1, + Py_ssize_t max_bin): - if dtype_t is uint8_t: - _core[uint8_t](_kernel_pop[uint8_t], image, selem, mask, out, - shift_x, shift_y, p0, p1, 0, 0, max_bin) - elif dtype_t is uint16_t: - _core[uint16_t](_kernel_pop[uint16_t], image, selem, mask, out, - shift_x, shift_y, p0, p1, 0, 0, max_bin) + _core(_kernel_pop[dtype_t], image, selem, mask, out, + shift_x, shift_y, p0, p1, 0, 0, max_bin) def _threshold(dtype_t[:, ::1] image, - char[:, ::1] selem, - char[:, ::1] mask, - dtype_t[:, ::1] out, - char shift_x, char shift_y, float p0, Py_ssize_t max_bin): + char[:, ::1] selem, + char[:, ::1] mask, + dtype_t_out[:, ::1] out, + char shift_x, char shift_y, float p0, Py_ssize_t max_bin): - if dtype_t is uint8_t: - _core[uint8_t](_kernel_threshold[uint8_t], image, selem, mask, out, - shift_x, shift_y, p0, 1, 0, 0, max_bin) - elif dtype_t is uint16_t: - _core[uint16_t](_kernel_threshold[uint16_t], image, selem, mask, out, - shift_x, shift_y, p0, 1, 0, 0, max_bin) + _core(_kernel_threshold[dtype_t], image, selem, mask, out, + shift_x, shift_y, p0, 1, 0, 0, max_bin)