From d0415e6df475157705fd1ef2af69b16e4f7e38cc Mon Sep 17 00:00:00 2001 From: Stefan van der Walt Date: Fri, 2 Nov 2012 16:02:06 -0700 Subject: [PATCH 01/12] Update README to Markdown. --- README.rst => README.md | 5 ----- 1 file changed, 5 deletions(-) rename README.rst => README.md (91%) diff --git a/README.rst b/README.md similarity index 91% rename from README.rst rename to README.md index 508db396..64a7dfe9 100644 --- a/README.rst +++ b/README.md @@ -29,8 +29,3 @@ this path to your PYTHONPATH variable and compiling the extensions: License ------- Please read LICENSE.txt in this directory. - -Contact -------- -Stefan van der Walt - From 4a14a217b951c7c83b9c12f07dec52efc1dd42fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Sch=C3=B6nberger?= Date: Fri, 9 Nov 2012 19:39:30 +0100 Subject: [PATCH 02/12] Improve overall code style --- skimage/filter/rank/_core16.pxd | 23 +- skimage/filter/rank/_core16.pyx | 125 ++--- skimage/filter/rank/_core8.pxd | 27 +- skimage/filter/rank/_core8.pyx | 154 +++--- skimage/filter/rank/_crank16.pyx | 46 +- skimage/filter/rank/_crank16_bilateral.pyx | 6 +- skimage/filter/rank/_crank16_percentiles.pyx | 64 +-- skimage/filter/rank/_crank8.pyx | 65 +-- skimage/filter/rank/_crank8_percentiles.pyx | 36 +- skimage/filter/rank/bilateral_rank.pyx | 135 +++--- skimage/filter/rank/percentile_rank.pyx | 361 ++++++++------ skimage/filter/rank/rank.pyx | 475 +++++++++++-------- 12 files changed, 812 insertions(+), 705 deletions(-) diff --git a/skimage/filter/rank/_core16.pxd b/skimage/filter/rank/_core16.pxd index 9590e277..b236d982 100644 --- a/skimage/filter/rank/_core16.pxd +++ b/skimage/filter/rank/_core16.pxd @@ -1,18 +1,17 @@ cimport numpy as np -#--------------------------------------------------------------------------- -# 16 bit core kernel receives extra information about data bitdepth -#--------------------------------------------------------------------------- -# generic cdef functions cdef int int_max(int a, int b) cdef int int_min(int a, int b) -cdef _core16( - np.uint16_t kernel(Py_ssize_t * , float, np.uint16_t, Py_ssize_t, Py_ssize_t, Py_ssize_t, float, float, Py_ssize_t, Py_ssize_t), - np.ndarray[np.uint16_t, ndim=2] image, - np.ndarray[np.uint8_t, ndim=2] selem, - np.ndarray[np.uint8_t, ndim=2] mask, - np.ndarray[np.uint16_t, ndim=2] out, - char shift_x, char shift_y, Py_ssize_t bitdepth, - float p0, float p1, Py_ssize_t s0, Py_ssize_t s1) + +# 16 bit core kernel receives extra information about data bitdepth +cdef void _core16(np.uint16_t kernel(Py_ssize_t *, float, np.uint16_t, + Py_ssize_t, Py_ssize_t, Py_ssize_t, float, + float, Py_ssize_t, Py_ssize_t), + np.ndarray[np.uint16_t, ndim=2] image, + np.ndarray[np.uint8_t, ndim=2] selem, + np.ndarray[np.uint8_t, ndim=2] mask, + np.ndarray[np.uint16_t, ndim=2] out, + char shift_x, char shift_y, Py_ssize_t bitdepth, + float p0, float p1, Py_ssize_t s0, Py_ssize_t s1) diff --git a/skimage/filter/rank/_core16.pyx b/skimage/filter/rank/_core16.pyx index 4829792b..671a92fc 100644 --- a/skimage/filter/rank/_core16.pyx +++ b/skimage/filter/rank/_core16.pyx @@ -6,50 +6,40 @@ import numpy as np cimport numpy as np from libc.stdlib cimport malloc, free +from _core8 cimport is_in_mask -#--------------------------------------------------------------------------- -# 16 bit core kernel receives extra information about data bitdepth -#--------------------------------------------------------------------------- -# generic cdef functions cdef inline int int_max(int a, int b): return a if a >= b else b + + cdef inline int int_min(int a, int b): return a if a <= b else b -cdef inline void histogram_increment(Py_ssize_t * histo, float * pop, np.uint16_t value): + +cdef inline void histogram_increment(Py_ssize_t * histo, float * pop, + np.uint16_t value): histo[value] += 1 pop[0] += 1. -cdef inline void histogram_decrement(Py_ssize_t * histo, float * pop, np.uint16_t value): + +cdef inline void histogram_decrement(Py_ssize_t * histo, float * pop, + np.uint16_t value): histo[value] -= 1 pop[0] -= 1. -cdef inline np.uint8_t is_in_mask(Py_ssize_t rows, Py_ssize_t cols, Py_ssize_t r, Py_ssize_t c, np.uint8_t * mask): - """ returns 1 if given(r,c) coordinate are within the image frame ([0-rows],[0-cols]) and - inside the given mask - returns 0 otherwise - """ - if r < 0 or r > rows - 1 or c < 0 or c > cols - 1: - return 0 - else: - if mask[r * cols + c]: - return 1 - else: - return 0 - -cdef inline _core16( - np.uint16_t kernel(Py_ssize_t *, float, np.uint16_t, Py_ssize_t, Py_ssize_t, Py_ssize_t, float, float, Py_ssize_t, Py_ssize_t), - np.ndarray[np.uint16_t, ndim=2] image, - np.ndarray[np.uint8_t, ndim=2] selem, - np.ndarray[np.uint8_t, ndim=2] mask, - np.ndarray[np.uint16_t, ndim=2] out, - char shift_x, char shift_y, Py_ssize_t bitdepth, - float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): - """ Main loop, this function computes the histogram for each image point - - data is uint8 - - result is uint8 casted +cdef void _core16(np.uint16_t kernel(Py_ssize_t *, float, np.uint16_t, + Py_ssize_t, Py_ssize_t, Py_ssize_t, float, + float, Py_ssize_t, Py_ssize_t), + np.ndarray[np.uint16_t, ndim=2] image, + np.ndarray[np.uint8_t, ndim=2] selem, + np.ndarray[np.uint8_t, ndim=2] mask, + np.ndarray[np.uint16_t, ndim=2] out, + char shift_x, char shift_y, Py_ssize_t bitdepth, + float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): + """Compute histogram for each pixel neighborhood, apply kernel function and + use kernel function return value for output image. """ cdef Py_ssize_t rows = image.shape[0] @@ -71,35 +61,20 @@ cdef inline _core16( midbin_list = [0, 0, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048] #set maxbin and midbin - cdef Py_ssize_t maxbin = maxbin_list[bitdepth], midbin = midbin_list[bitdepth] + cdef Py_ssize_t maxbin = maxbin_list[bitdepth] + cdef Py_ssize_t midbin = midbin_list[bitdepth] assert (image < maxbin).all() - image = np.ascontiguousarray(image) - - if mask is None: - mask = np.ones((rows, cols), dtype=np.uint8) - else: - mask = np.ascontiguousarray(mask) - - if image is out: - raise NotImplementedError("Cannot perform rank operation in place.") - - if out is None: - out = np.zeros((rows, cols), dtype=np.uint16) - else: - out = np.ascontiguousarray(out) - - mask = np.ascontiguousarray(mask) - # define pointers to the data - cdef np.uint16_t * out_data = out.data - cdef np.uint16_t * image_data = image.data - cdef np.uint8_t * mask_data = mask.data + cdef np.uint16_t * out_data = out.data + cdef np.uint16_t * image_data = image.data + cdef np.uint8_t * mask_data = mask.data # define local variable types cdef Py_ssize_t r, c, rr, cc, s, value, local_max, i, even_row - cdef float pop # number of pixels actually inside the neighborhood (float) + # number of pixels actually inside the neighborhood (float) + cdef float pop # allocate memory with malloc cdef Py_ssize_t max_se = srows * scols @@ -108,24 +83,22 @@ cdef inline _core16( cdef Py_ssize_t num_se_n, num_se_s, num_se_e, num_se_w # the current local histogram distribution - cdef Py_ssize_t * histo = malloc(maxbin * sizeof(Py_ssize_t)) + cdef Py_ssize_t * histo = malloc(maxbin * sizeof(Py_ssize_t)) - # these lists contain the relative pixel row and column for each of the 4 attack borders - # east, west, north and south - # e.g. se_e_r lists the rows of the east structuring element border - - cdef Py_ssize_t * se_e_r = malloc(max_se * sizeof(Py_ssize_t)) - cdef Py_ssize_t * se_e_c = malloc(max_se * sizeof(Py_ssize_t)) - cdef Py_ssize_t * se_w_r = malloc(max_se * sizeof(Py_ssize_t)) - cdef Py_ssize_t * se_w_c = malloc(max_se * sizeof(Py_ssize_t)) - cdef Py_ssize_t * se_n_r = malloc(max_se * sizeof(Py_ssize_t)) - cdef Py_ssize_t * se_n_c = malloc(max_se * sizeof(Py_ssize_t)) - cdef Py_ssize_t * se_s_r = malloc(max_se * sizeof(Py_ssize_t)) - cdef Py_ssize_t * se_s_c = malloc(max_se * sizeof(Py_ssize_t)) + # these lists contain the relative pixel row and column for each of the 4 + # attack borders east, west, north and south e.g. se_e_r lists the rows of + # the east structuring element border + cdef Py_ssize_t * se_e_r = malloc(max_se * sizeof(Py_ssize_t)) + cdef Py_ssize_t * se_e_c = malloc(max_se * sizeof(Py_ssize_t)) + cdef Py_ssize_t * se_w_r = malloc(max_se * sizeof(Py_ssize_t)) + cdef Py_ssize_t * se_w_c = malloc(max_se * sizeof(Py_ssize_t)) + cdef Py_ssize_t * se_n_r = malloc(max_se * sizeof(Py_ssize_t)) + cdef Py_ssize_t * se_n_c = malloc(max_se * sizeof(Py_ssize_t)) + cdef Py_ssize_t * se_s_r = malloc(max_se * sizeof(Py_ssize_t)) + cdef Py_ssize_t * se_s_c = malloc(max_se * sizeof(Py_ssize_t)) # build attack and release borders # by using difference along axis - t = np.hstack((selem, np.zeros((selem.shape[0], 1)))) t_e = np.diff(t, axis=1) == -1 @@ -171,7 +144,7 @@ cdef inline _core16( cc = c - centre_c if selem[r, c]: if is_in_mask(rows, cols, rr, cc, mask_data): - histogram_increment(histo, & pop, image_data[rr * cols + cc]) + histogram_increment(histo, &pop, image_data[rr * cols + cc]) r = 0 c = 0 @@ -189,13 +162,13 @@ cdef inline _core16( rr = r + se_e_r[s] cc = c + se_e_c[s] if is_in_mask(rows, cols, rr, cc, mask_data): - histogram_increment(histo, & pop, image_data[rr * cols + cc]) + histogram_increment(histo, &pop, image_data[rr * cols + cc]) for s in range(num_se_w): rr = r + se_w_r[s] cc = c + se_w_c[s] - 1 if is_in_mask(rows, cols, rr, cc, mask_data): - histogram_decrement(histo, & pop, image_data[rr * cols + cc]) + histogram_decrement(histo, &pop, image_data[rr * cols + cc]) # kernel ------------------------------------------- out_data[r * cols + c] = kernel( @@ -212,13 +185,13 @@ cdef inline _core16( rr = r + se_s_r[s] cc = c + se_s_c[s] if is_in_mask(rows, cols, rr, cc, mask_data): - histogram_increment(histo, & pop, image_data[rr * cols + cc]) + histogram_increment(histo, &pop, image_data[rr * cols + cc]) for s in range(num_se_n): rr = r + se_n_r[s] - 1 cc = c + se_n_c[s] if is_in_mask(rows, cols, rr, cc, mask_data): - histogram_decrement(histo, & pop, image_data[rr * cols + cc]) + histogram_decrement(histo, &pop, image_data[rr * cols + cc]) # kernel ------------------------------------------- out_data[r * cols + c] = kernel(histo, pop, image_data[r * cols + c], @@ -231,13 +204,13 @@ cdef inline _core16( rr = r + se_w_r[s] cc = c + se_w_c[s] if is_in_mask(rows, cols, rr, cc, mask_data): - histogram_increment(histo, & pop, image_data[rr * cols + cc]) + histogram_increment(histo, &pop, image_data[rr * cols + cc]) for s in range(num_se_e): rr = r + se_e_r[s] cc = c + se_e_c[s] + 1 if is_in_mask(rows, cols, rr, cc, mask_data): - histogram_decrement(histo, & pop, image_data[rr * cols + cc]) + histogram_decrement(histo, &pop, image_data[rr * cols + cc]) # kernel ------------------------------------------- out_data[r * cols + c] = kernel( @@ -254,13 +227,13 @@ cdef inline _core16( rr = r + se_s_r[s] cc = c + se_s_c[s] if is_in_mask(rows, cols, rr, cc, mask_data): - histogram_increment(histo, & pop, image_data[rr * cols + cc]) + histogram_increment(histo, &pop, image_data[rr * cols + cc]) for s in range(num_se_n): rr = r + se_n_r[s] - 1 cc = c + se_n_c[s] if is_in_mask(rows, cols, rr, cc, mask_data): - histogram_decrement(histo, & pop, image_data[rr * cols + cc]) + histogram_decrement(histo, &pop, image_data[rr * cols + cc]) # kernel ------------------------------------------- out_data[r * cols + c] = kernel(histo, pop, image_data[r * cols + c], @@ -279,5 +252,3 @@ cdef inline _core16( free(se_s_c) free(histo) - - return out diff --git a/skimage/filter/rank/_core8.pxd b/skimage/filter/rank/_core8.pxd index 9f898faa..d724c417 100644 --- a/skimage/filter/rank/_core8.pxd +++ b/skimage/filter/rank/_core8.pxd @@ -1,17 +1,22 @@ cimport numpy as np -# generic cdef functions + cdef np.uint8_t uint8_max(np.uint8_t a, np.uint8_t b) cdef np.uint8_t uint8_min(np.uint8_t a, np.uint8_t b) -#--------------------------------------------------------------------------- -# 8 bit core kernel receives extra information about data inferior and superior percentiles -#--------------------------------------------------------------------------- -cdef _core8( - np.uint8_t kernel(Py_ssize_t *, float, np.uint8_t, float, float, Py_ssize_t, Py_ssize_t), - np.ndarray[np.uint8_t, ndim=2] image, - np.ndarray[np.uint8_t, ndim=2] selem, - np.ndarray[np.uint8_t, ndim=2] mask, - np.ndarray[np.uint8_t, ndim=2] out, - char shift_x, char shift_y, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1) +cdef np.uint8_t is_in_mask(Py_ssize_t rows, Py_ssize_t cols, + Py_ssize_t r, Py_ssize_t c, + np.uint8_t * mask) + + +# 8 bit core kernel receives extra information about data inferior and superior +# percentiles +cdef void _core8(np.uint8_t kernel(Py_ssize_t *, float, np.uint8_t, float, + float, Py_ssize_t, Py_ssize_t), + np.ndarray[np.uint8_t, ndim=2] image, + np.ndarray[np.uint8_t, ndim=2] selem, + np.ndarray[np.uint8_t, ndim=2] mask, + np.ndarray[np.uint8_t, ndim=2] 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/_core8.pyx b/skimage/filter/rank/_core8.pyx index 9955a1e1..17e5f64e 100644 --- a/skimage/filter/rank/_core8.pyx +++ b/skimage/filter/rank/_core8.pyx @@ -7,30 +7,31 @@ import numpy as np cimport numpy as np from libc.stdlib cimport malloc, free -# generic cdef functions + cdef inline np.uint8_t uint8_max(np.uint8_t a, np.uint8_t b): return a if a >= b else b + + cdef inline np.uint8_t uint8_min(np.uint8_t a, np.uint8_t b): return a if a <= b else b -#--------------------------------------------------------------------------- -# 8 bit core kernel -#--------------------------------------------------------------------------- - -cdef inline void histogram_increment(Py_ssize_t * histo, float * pop, np.uint8_t value): +cdef inline void histogram_increment(Py_ssize_t * histo, float * pop, + np.uint8_t value): histo[value] += 1 pop[0] += 1. -cdef inline void histogram_decrement(Py_ssize_t * histo, float * pop, np.uint8_t value): + +cdef inline void histogram_decrement(Py_ssize_t * histo, float * pop, + np.uint8_t value): histo[value] -= 1 pop[0] -= 1. -cdef inline np.uint8_t is_in_mask(Py_ssize_t rows, Py_ssize_t cols, Py_ssize_t r, Py_ssize_t c, np.uint8_t * mask): - """ returns 1 if given(r,c) coordinate are within the image frame ([0-rows],[0-cols]) and - inside the given mask - returns 0 otherwise - """ + +cdef inline np.uint8_t is_in_mask(Py_ssize_t rows, Py_ssize_t cols, + Py_ssize_t r, Py_ssize_t c, + np.uint8_t * mask): + """Check whether given coordinate is within image and mask is true.""" if r < 0 or r > rows - 1 or c < 0 or c > cols - 1: return 0 else: @@ -39,16 +40,17 @@ cdef inline np.uint8_t is_in_mask(Py_ssize_t rows, Py_ssize_t cols, Py_ssize_t r else: return 0 -cdef inline _core8( - np.uint8_t kernel(Py_ssize_t * , float, np.uint8_t, float, float, Py_ssize_t, Py_ssize_t), - np.ndarray[np.uint8_t, ndim=2] image, - np.ndarray[np.uint8_t, ndim=2] selem, - np.ndarray[np.uint8_t, ndim=2] mask, - np.ndarray[np.uint8_t, ndim=2] out, - char shift_x, char shift_y, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): - """ Main loop, this function computes the histogram for each image point - - data is uint8 - - result is uint8 casted + +cdef void _core8(np.uint8_t kernel(Py_ssize_t *, float, np.uint8_t, float, + float, Py_ssize_t, Py_ssize_t), + np.ndarray[np.uint8_t, ndim=2] image, + np.ndarray[np.uint8_t, ndim=2] selem, + np.ndarray[np.uint8_t, ndim=2] mask, + np.ndarray[np.uint8_t, ndim=2] out, + char shift_x, char shift_y, float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): + """Compute histogram for each pixel neighborhood, apply kernel function and + use kernel function return value for output image. """ cdef Py_ssize_t rows = image.shape[0] @@ -65,28 +67,11 @@ cdef inline _core8( assert centre_r < srows assert centre_c < scols - image = np.ascontiguousarray(image) - - if mask is None: - mask = np.ones((rows, cols), dtype=np.uint8) - else: - mask = np.ascontiguousarray(mask) - - if image is out: - raise NotImplementedError("Cannot perform rank operation in place.") - - if out is None: - out = np.zeros((rows, cols), dtype=np.uint8) - else: - out = np.ascontiguousarray(out) - - mask = np.ascontiguousarray(mask) - # define pointers to the data - cdef np.uint8_t * out_data = out.data - cdef np.uint8_t * image_data = image.data - cdef np.uint8_t * mask_data = mask.data + cdef np.uint8_t * out_data = out.data + cdef np.uint8_t * image_data = image.data + cdef np.uint8_t * mask_data = mask.data # define local variable types cdef Py_ssize_t r, c, rr, cc, s, value, local_max, i, even_row @@ -101,24 +86,22 @@ cdef inline _core8( cdef Py_ssize_t num_se_n, num_se_s, num_se_e, num_se_w # the current local histogram distribution - cdef Py_ssize_t * histo = malloc(256 * sizeof(Py_ssize_t)) + cdef Py_ssize_t * histo = malloc(256 * sizeof(Py_ssize_t)) - # these lists contain the relative pixel row and column for each of the 4 attack borders - # east, west, north and south - # e.g. se_e_r lists the rows of the east structuring element border - - cdef Py_ssize_t * se_e_r = malloc(max_se * sizeof(Py_ssize_t)) - cdef Py_ssize_t * se_e_c = malloc(max_se * sizeof(Py_ssize_t)) - cdef Py_ssize_t * se_w_r = malloc(max_se * sizeof(Py_ssize_t)) - cdef Py_ssize_t * se_w_c = malloc(max_se * sizeof(Py_ssize_t)) - cdef Py_ssize_t * se_n_r = malloc(max_se * sizeof(Py_ssize_t)) - cdef Py_ssize_t * se_n_c = malloc(max_se * sizeof(Py_ssize_t)) - cdef Py_ssize_t * se_s_r = malloc(max_se * sizeof(Py_ssize_t)) - cdef Py_ssize_t * se_s_c = malloc(max_se * sizeof(Py_ssize_t)) + # these lists contain the relative pixel row and column for each of the 4 + # attack borders east, west, north and south e.g. se_e_r lists the rows of + # the east structuring element border + cdef Py_ssize_t * se_e_r = malloc(max_se * sizeof(Py_ssize_t)) + cdef Py_ssize_t * se_e_c = malloc(max_se * sizeof(Py_ssize_t)) + cdef Py_ssize_t * se_w_r = malloc(max_se * sizeof(Py_ssize_t)) + cdef Py_ssize_t * se_w_c = malloc(max_se * sizeof(Py_ssize_t)) + cdef Py_ssize_t * se_n_r = malloc(max_se * sizeof(Py_ssize_t)) + cdef Py_ssize_t * se_n_c = malloc(max_se * sizeof(Py_ssize_t)) + cdef Py_ssize_t * se_s_r = malloc(max_se * sizeof(Py_ssize_t)) + cdef Py_ssize_t * se_s_c = malloc(max_se * sizeof(Py_ssize_t)) # build attack and release borders # by using difference along axis - t = np.hstack((selem, np.zeros((selem.shape[0], 1)))) t_e = np.diff(t, axis=1) == -1 @@ -152,7 +135,8 @@ cdef inline _core8( se_s_c[num_se_s] = c - centre_c num_se_s += 1 - # initial population and histogram (kernel is centered on the first row and column) + # initial population and histogram (kernel is centered on the first row and + # column) for i in range(256): histo[i] = 0 @@ -164,14 +148,14 @@ cdef inline _core8( cc = c - centre_c if selem[r, c]: if is_in_mask(rows, cols, rr, cc, mask_data): - histogram_increment(histo, & pop, image_data[rr * cols + cc]) + histogram_increment(histo, &pop, image_data[rr * cols + cc]) r = 0 c = 0 - # kernel -------------------------------------------------------------------- - out_data[r * cols + c] = kernel(histo, pop, image_data[r * cols + - c], p0, p1, s0, s1) - # kernel -------------------------------------------------------------------- + # kernel ------------------------------------------------------------------- + out_data[r * cols + c] = kernel(histo, pop, image_data[r * cols + c], + p0, p1, s0, s1) + # kernel ------------------------------------------------------------------- # main loop r = 0 @@ -182,18 +166,18 @@ cdef inline _core8( rr = r + se_e_r[s] cc = c + se_e_c[s] if is_in_mask(rows, cols, rr, cc, mask_data): - histogram_increment(histo, & pop, image_data[rr * cols + cc]) + histogram_increment(histo, &pop, image_data[rr * cols + cc]) for s in range(num_se_w): rr = r + se_w_r[s] cc = c + se_w_c[s] - 1 if is_in_mask(rows, cols, rr, cc, mask_data): - histogram_decrement(histo, & pop, image_data[rr * cols + cc]) + histogram_decrement(histo, &pop, image_data[rr * cols + cc]) - # kernel -------------------------------------------------------------------- - out_data[r * cols + c] = kernel( - histo, pop, image_data[r * cols + c], p0, p1, s0, s1) - # kernel -------------------------------------------------------------------- + # kernel ----------------------------------------------------------- + out_data[r * cols + c] = \ + kernel(histo, pop, image_data[r * cols + c], p0, p1, s0, s1) + # kernel ----------------------------------------------------------- r += 1 # pass to the next row if r >= rows: @@ -204,18 +188,18 @@ cdef inline _core8( rr = r + se_s_r[s] cc = c + se_s_c[s] if is_in_mask(rows, cols, rr, cc, mask_data): - histogram_increment(histo, & pop, image_data[rr * cols + cc]) + histogram_increment(histo, &pop, image_data[rr * cols + cc]) for s in range(num_se_n): rr = r + se_n_r[s] - 1 cc = c + se_n_c[s] if is_in_mask(rows, cols, rr, cc, mask_data): - histogram_decrement(histo, & pop, image_data[rr * cols + cc]) + histogram_decrement(histo, &pop, image_data[rr * cols + cc]) - # kernel -------------------------------------------------------------------- - out_data[r * cols + c] = kernel(histo, pop, image_data[r * - cols + c], p0, p1, s0, s1) - # kernel -------------------------------------------------------------------- + # kernel --------------------------------------------------------------- + out_data[r * cols + c] = kernel(histo, pop, image_data[r * cols + c], + p0, p1, s0, s1) + # kernel --------------------------------------------------------------- # ---> east to west for c in range(cols - 2, -1, -1): @@ -223,18 +207,18 @@ cdef inline _core8( rr = r + se_w_r[s] cc = c + se_w_c[s] if is_in_mask(rows, cols, rr, cc, mask_data): - histogram_increment(histo, & pop, image_data[rr * cols + cc]) + histogram_increment(histo, &pop, image_data[rr * cols + cc]) for s in range(num_se_e): rr = r + se_e_r[s] cc = c + se_e_c[s] + 1 if is_in_mask(rows, cols, rr, cc, mask_data): - histogram_decrement(histo, & pop, image_data[rr * cols + cc]) + histogram_decrement(histo, &pop, image_data[rr * cols + cc]) - # kernel -------------------------------------------------------------------- + # kernel ----------------------------------------------------------- out_data[r * cols + c] = kernel( histo, pop, image_data[r * cols + c], p0, p1, s0, s1) - # kernel -------------------------------------------------------------------- + # kernel ----------------------------------------------------------- r += 1 # pass to the next row if r >= rows: @@ -245,18 +229,18 @@ cdef inline _core8( rr = r + se_s_r[s] cc = c + se_s_c[s] if is_in_mask(rows, cols, rr, cc, mask_data): - histogram_increment(histo, & pop, image_data[rr * cols + cc]) + histogram_increment(histo, &pop, image_data[rr * cols + cc]) for s in range(num_se_n): rr = r + se_n_r[s] - 1 cc = c + se_n_c[s] if is_in_mask(rows, cols, rr, cc, mask_data): - histogram_decrement(histo, & pop, image_data[rr * cols + cc]) + histogram_decrement(histo, &pop, image_data[rr * cols + cc]) - # kernel -------------------------------------------------------------------- - out_data[r * cols + c] = kernel(histo, pop, image_data[r * - cols + c], p0, p1, s0, s1) - # kernel -------------------------------------------------------------------- + # kernel --------------------------------------------------------------- + out_data[r * cols + c] = kernel(histo, pop, image_data[r * cols + c], + p0, p1, s0, s1) + # kernel --------------------------------------------------------------- # release memory allocated by malloc @@ -270,5 +254,3 @@ cdef inline _core8( free(se_s_c) free(histo) - - return out diff --git a/skimage/filter/rank/_crank16.pyx b/skimage/filter/rank/_crank16.pyx index 73e8e0bd..ab5b6015 100644 --- a/skimage/filter/rank/_crank16.pyx +++ b/skimage/filter/rank/_crank16.pyx @@ -240,6 +240,7 @@ cdef inline np.uint16_t kernel_entropy( return < np.uint16_t > e*1000 + # ----------------------------------------------------------------- # python wrappers # ----------------------------------------------------------------- @@ -250,7 +251,8 @@ def autolevel(np.ndarray[np.uint16_t, ndim=2] image, np.ndarray[np.uint8_t, ndim=2] mask=None, np.ndarray[np.uint16_t, ndim=2] out=None, char shift_x=0, char shift_y=0, Py_ssize_t bitdepth=8): - return _core16(kernel_autolevel, image, selem, mask, out, shift_x, shift_y, bitdepth, .0, .0, < Py_ssize_t > 0, < Py_ssize_t > 0) + _core16(kernel_autolevel, image, selem, mask, out, shift_x, shift_y, + bitdepth, 0, 0, 0, 0) def bottomhat(np.ndarray[np.uint16_t, ndim=2] image, @@ -258,7 +260,8 @@ def bottomhat(np.ndarray[np.uint16_t, ndim=2] image, np.ndarray[np.uint8_t, ndim=2] mask=None, np.ndarray[np.uint16_t, ndim=2] out=None, char shift_x=0, char shift_y=0, Py_ssize_t bitdepth=8): - return _core16(kernel_bottomhat, image, selem, mask, out, shift_x, shift_y, bitdepth, .0, .0, < Py_ssize_t > 0, < Py_ssize_t > 0) + _core16(kernel_bottomhat, image, selem, mask, out, shift_x, shift_y, + bitdepth, 0, 0, 0, 0) def equalize(np.ndarray[np.uint16_t, ndim=2] image, @@ -266,7 +269,8 @@ def equalize(np.ndarray[np.uint16_t, ndim=2] image, np.ndarray[np.uint8_t, ndim=2] mask=None, np.ndarray[np.uint16_t, ndim=2] out=None, char shift_x=0, char shift_y=0, Py_ssize_t bitdepth=8): - return _core16(kernel_equalize, image, selem, mask, out, shift_x, shift_y, bitdepth, .0, .0, < Py_ssize_t > 0, < Py_ssize_t > 0) + _core16(kernel_equalize, image, selem, mask, out, shift_x, shift_y, + bitdepth, 0, 0, 0, 0) def gradient(np.ndarray[np.uint16_t, ndim=2] image, @@ -274,7 +278,8 @@ def gradient(np.ndarray[np.uint16_t, ndim=2] image, np.ndarray[np.uint8_t, ndim=2] mask=None, np.ndarray[np.uint16_t, ndim=2] out=None, char shift_x=0, char shift_y=0, Py_ssize_t bitdepth=8): - return _core16(kernel_gradient, image, selem, mask, out, shift_x, shift_y, bitdepth, .0, .0, < Py_ssize_t > 0, < Py_ssize_t > 0) + _core16(kernel_gradient, image, selem, mask, out, shift_x, shift_y, + bitdepth, 0, 0, 0, 0) def maximum(np.ndarray[np.uint16_t, ndim=2] image, @@ -282,7 +287,8 @@ def maximum(np.ndarray[np.uint16_t, ndim=2] image, np.ndarray[np.uint8_t, ndim=2] mask=None, np.ndarray[np.uint16_t, ndim=2] out=None, char shift_x=0, char shift_y=0, Py_ssize_t bitdepth=8): - return _core16(kernel_maximum, image, selem, mask, out, shift_x, shift_y, bitdepth, .0, .0, < Py_ssize_t > 0, < Py_ssize_t > 0) + _core16(kernel_maximum, image, selem, mask, out, shift_x, shift_y, + bitdepth, 0, 0, 0, 0) def mean(np.ndarray[np.uint16_t, ndim=2] image, @@ -290,7 +296,8 @@ def mean(np.ndarray[np.uint16_t, ndim=2] image, np.ndarray[np.uint8_t, ndim=2] mask=None, np.ndarray[np.uint16_t, ndim=2] out=None, char shift_x=0, char shift_y=0, Py_ssize_t bitdepth=8): - return _core16(kernel_mean, image, selem, mask, out, shift_x, shift_y, bitdepth, .0, .0, < Py_ssize_t > 0, < Py_ssize_t > 0) + _core16(kernel_mean, image, selem, mask, out, shift_x, shift_y, + bitdepth, 0, 0, 0, 0) def meansubstraction(np.ndarray[np.uint16_t, ndim=2] image, @@ -298,7 +305,8 @@ def meansubstraction(np.ndarray[np.uint16_t, ndim=2] image, np.ndarray[np.uint8_t, ndim=2] mask=None, np.ndarray[np.uint16_t, ndim=2] out=None, char shift_x=0, char shift_y=0, Py_ssize_t bitdepth=8): - return _core16(kernel_meansubstraction, image, selem, mask, out, shift_x, shift_y, bitdepth, .0, .0, < Py_ssize_t > 0, < Py_ssize_t > 0) + _core16(kernel_meansubstraction, image, selem, mask, out, shift_x, shift_y, + bitdepth, 0, 0, 0, 0) def median(np.ndarray[np.uint16_t, ndim=2] image, @@ -306,7 +314,8 @@ def median(np.ndarray[np.uint16_t, ndim=2] image, np.ndarray[np.uint8_t, ndim=2] mask=None, np.ndarray[np.uint16_t, ndim=2] out=None, char shift_x=0, char shift_y=0, Py_ssize_t bitdepth=8): - return _core16(kernel_median, image, selem, mask, out, shift_x, shift_y, bitdepth, .0, .0, < Py_ssize_t > 0, < Py_ssize_t > 0) + _core16(kernel_median, image, selem, mask, out, shift_x, shift_y, + bitdepth, 0, 0, 0, 0) def minimum(np.ndarray[np.uint16_t, ndim=2] image, @@ -314,7 +323,8 @@ def minimum(np.ndarray[np.uint16_t, ndim=2] image, np.ndarray[np.uint8_t, ndim=2] mask=None, np.ndarray[np.uint16_t, ndim=2] out=None, char shift_x=0, char shift_y=0, Py_ssize_t bitdepth=8): - return _core16(kernel_minimum, image, selem, mask, out, shift_x, shift_y, bitdepth, .0, .0, < Py_ssize_t > 0, < Py_ssize_t > 0) + _core16(kernel_minimum, image, selem, mask, out, shift_x, shift_y, + bitdepth, 0, 0, 0, 0) def morph_contr_enh(np.ndarray[np.uint16_t, ndim=2] image, @@ -322,7 +332,8 @@ def morph_contr_enh(np.ndarray[np.uint16_t, ndim=2] image, np.ndarray[np.uint8_t, ndim=2] mask=None, np.ndarray[np.uint16_t, ndim=2] out=None, char shift_x=0, char shift_y=0, Py_ssize_t bitdepth=8): - return _core16(kernel_morph_contr_enh, image, selem, mask, out, shift_x, shift_y, bitdepth, .0, .0, < Py_ssize_t > 0, < Py_ssize_t > 0) + _core16(kernel_morph_contr_enh, image, selem, mask, out, shift_x, shift_y, + bitdepth, 0, 0, 0, 0) def modal(np.ndarray[np.uint16_t, ndim=2] image, @@ -330,7 +341,8 @@ def modal(np.ndarray[np.uint16_t, ndim=2] image, np.ndarray[np.uint8_t, ndim=2] mask=None, np.ndarray[np.uint16_t, ndim=2] out=None, char shift_x=0, char shift_y=0, Py_ssize_t bitdepth=8): - return _core16(kernel_modal, image, selem, mask, out, shift_x, shift_y, bitdepth, .0, .0, < Py_ssize_t > 0, < Py_ssize_t > 0) + _core16(kernel_modal, image, selem, mask, out, shift_x, shift_y, + bitdepth, 0, 0, 0, 0) def pop(np.ndarray[np.uint16_t, ndim=2] image, @@ -338,7 +350,8 @@ def pop(np.ndarray[np.uint16_t, ndim=2] image, np.ndarray[np.uint8_t, ndim=2] mask=None, np.ndarray[np.uint16_t, ndim=2] out=None, char shift_x=0, char shift_y=0, Py_ssize_t bitdepth=8): - return _core16(kernel_pop, image, selem, mask, out, shift_x, shift_y, bitdepth, .0, .0, < Py_ssize_t > 0, < Py_ssize_t > 0) + _core16(kernel_pop, image, selem, mask, out, shift_x, shift_y, + bitdepth, 0, 0, 0, 0) def threshold(np.ndarray[np.uint16_t, ndim=2] image, @@ -346,7 +359,8 @@ def threshold(np.ndarray[np.uint16_t, ndim=2] image, np.ndarray[np.uint8_t, ndim=2] mask=None, np.ndarray[np.uint16_t, ndim=2] out=None, char shift_x=0, char shift_y=0, Py_ssize_t bitdepth=8): - return _core16(kernel_threshold, image, selem, mask, out, shift_x, shift_y, bitdepth, .0, .0, < Py_ssize_t > 0, < Py_ssize_t > 0) + _core16(kernel_threshold, image, selem, mask, out, shift_x, shift_y, + bitdepth, 0, 0, 0, 0) def tophat(np.ndarray[np.uint16_t, ndim=2] image, @@ -354,11 +368,13 @@ def tophat(np.ndarray[np.uint16_t, ndim=2] image, np.ndarray[np.uint8_t, ndim=2] mask=None, np.ndarray[np.uint16_t, ndim=2] out=None, char shift_x=0, char shift_y=0, Py_ssize_t bitdepth=8): - return _core16(kernel_tophat, image, selem, mask, out, shift_x, shift_y, bitdepth, .0, .0, < Py_ssize_t > 0, < Py_ssize_t > 0) + _core16(kernel_tophat, image, selem, mask, out, shift_x, shift_y, + bitdepth, 0, 0, 0, 0) def entropy(np.ndarray[np.uint16_t, ndim=2] image, np.ndarray[np.uint8_t, ndim=2] selem, np.ndarray[np.uint8_t, ndim=2] mask=None, np.ndarray[np.uint16_t, ndim=2] out=None, char shift_x=0, char shift_y=0, Py_ssize_t bitdepth=8): - return _core16(kernel_entropy, image, selem, mask, out, shift_x, shift_y, bitdepth, .0, .0, < Py_ssize_t > 0, < Py_ssize_t > 0) + _core16(kernel_entropy, image, selem, mask, out, shift_x, shift_y, + bitdepth, 0, 0, 0, 0) diff --git a/skimage/filter/rank/_crank16_bilateral.pyx b/skimage/filter/rank/_crank16_bilateral.pyx index c013b779..cf68115e 100644 --- a/skimage/filter/rank/_crank16_bilateral.pyx +++ b/skimage/filter/rank/_crank16_bilateral.pyx @@ -59,7 +59,8 @@ def mean(np.ndarray[np.uint16_t, ndim=2] image, char shift_x=0, char shift_y=0, int bitdepth=8, int s0=1, int s1=1): """average gray level (clipped on uint8) """ - return _core16(kernel_mean, image, selem, mask, out, shift_x, shift_y, bitdepth, 0., 0., s0, s1) + _core16(kernel_mean, image, selem, mask, out, shift_x, shift_y, + bitdepth, 0., 0., s0, s1) def pop(np.ndarray[np.uint16_t, ndim=2] image, @@ -69,4 +70,5 @@ def pop(np.ndarray[np.uint16_t, ndim=2] image, char shift_x=0, char shift_y=0, int bitdepth=8, int s0=1, int s1=1): """returns the number of actual pixels of the structuring element inside the mask """ - return _core16(kernel_pop, image, selem, mask, out, shift_x, shift_y, bitdepth, .0, .0, s0, s1) + _core16(kernel_pop, image, selem, mask, out, shift_x, shift_y, + bitdepth, .0, .0, s0, s1) diff --git a/skimage/filter/rank/_crank16_percentiles.pyx b/skimage/filter/rank/_crank16_percentiles.pyx index 0d37b77c..3b50c86c 100644 --- a/skimage/filter/rank/_crank16_percentiles.pyx +++ b/skimage/filter/rank/_crank16_percentiles.pyx @@ -205,93 +205,93 @@ def autolevel(np.ndarray[np.uint16_t, ndim=2] image, np.ndarray[np.uint8_t, ndim=2] selem, np.ndarray[np.uint8_t, ndim=2] mask=None, np.ndarray[np.uint16_t, ndim=2] out=None, - char shift_x=0, char shift_y=0, int bitdepth=8, float p0=0., float p1=0.): + char shift_x=0, char shift_y=0, int bitdepth=8, + float p0=0., float p1=0.): """bottom hat """ - return _core16( - kernel_autolevel, image, selem, mask, out, shift_x, shift_y, bitdepth, p0, p1, - < Py_ssize_t > 0, < Py_ssize_t > 0) + _core16(kernel_autolevel, image, selem, mask, out, shift_x, shift_y, + bitdepth, p0, p1, 0, 0) def gradient(np.ndarray[np.uint16_t, ndim=2] image, np.ndarray[np.uint8_t, ndim=2] selem, np.ndarray[np.uint8_t, ndim=2] mask=None, np.ndarray[np.uint16_t, ndim=2] out=None, - char shift_x=0, char shift_y=0, int bitdepth=8, float p0=0., float p1=0.): + char shift_x=0, char shift_y=0, int bitdepth=8, + float p0=0., float p1=0.): """return p0,p1 percentile gradient """ - return _core16( - kernel_gradient, image, selem, mask, out, shift_x, shift_y, bitdepth, p0, p1, < Py_ssize_t > 0, - < Py_ssize_t > 0) + _core16(kernel_gradient, image, selem, mask, out, shift_x, shift_y, + bitdepth, p0, p1, 0, 0) def mean(np.ndarray[np.uint16_t, ndim=2] image, np.ndarray[np.uint8_t, ndim=2] selem, np.ndarray[np.uint8_t, ndim=2] mask=None, np.ndarray[np.uint16_t, ndim=2] out=None, - char shift_x=0, char shift_y=0, int bitdepth=8, float p0=0., float p1=0.): + char shift_x=0, char shift_y=0, int bitdepth=8, + float p0=0., float p1=0.): """return mean between [p0 and p1] percentiles """ - return _core16( - kernel_mean, image, selem, mask, out, shift_x, shift_y, bitdepth, p0, p1, < Py_ssize_t > 0, - < Py_ssize_t > 0) + _core16(kernel_mean, image, selem, mask, out, shift_x, shift_y, + bitdepth, p0, p1, 0, 0) def mean_substraction(np.ndarray[np.uint16_t, ndim=2] image, np.ndarray[np.uint8_t, ndim=2] selem, np.ndarray[np.uint8_t, ndim=2] mask=None, np.ndarray[np.uint16_t, ndim=2] out=None, - char shift_x=0, char shift_y=0, int bitdepth=8, float p0=0., float p1=0.): + char shift_x=0, char shift_y=0, int bitdepth=8, + float p0=0., float p1=0.): """return original - mean between [p0 and p1] percentiles *.5 +127 """ - return _core16( - kernel_mean_substraction, image, selem, mask, out, shift_x, shift_y, bitdepth, p0, p1, - < Py_ssize_t > 0, < Py_ssize_t > 0) + _core16(kernel_mean_substraction, image, selem, mask, out, shift_x, shift_y, + bitdepth, p0, p1, 0, 0) def morph_contr_enh(np.ndarray[np.uint16_t, ndim=2] image, np.ndarray[np.uint8_t, ndim=2] selem, np.ndarray[np.uint8_t, ndim=2] mask=None, np.ndarray[np.uint16_t, ndim=2] out=None, - char shift_x=0, char shift_y=0, int bitdepth=8, float p0=0., float p1=0.): + char shift_x=0, char shift_y=0, int bitdepth=8, + float p0=0., float p1=0.): """reforce contrast using percentiles """ - return _core16( - kernel_morph_contr_enh, image, selem, mask, out, shift_x, shift_y, bitdepth, p0, p1, - < Py_ssize_t > 0, < Py_ssize_t > 0) + _core16(kernel_morph_contr_enh, image, selem, mask, out, shift_x, shift_y, + bitdepth, p0, p1, 0, 0) def percentile(np.ndarray[np.uint16_t, ndim=2] image, np.ndarray[np.uint8_t, ndim=2] selem, np.ndarray[np.uint8_t, ndim=2] mask=None, np.ndarray[np.uint16_t, ndim=2] out=None, - char shift_x=0, char shift_y=0, int bitdepth=8, float p0=0., float p1=0.): + char shift_x=0, char shift_y=0, int bitdepth=8, + float p0=0., float p1=0.): """return p0 percentile """ - return _core16( - kernel_percentile, image, selem, mask, out, shift_x, shift_y, bitdepth, p0, p1, - < Py_ssize_t > 0, < Py_ssize_t > 0) + _core16(kernel_percentile, image, selem, mask, out, shift_x, shift_y, + bitdepth, p0, p1, 0, 0) def pop(np.ndarray[np.uint16_t, ndim=2] image, np.ndarray[np.uint8_t, ndim=2] selem, np.ndarray[np.uint8_t, ndim=2] mask=None, np.ndarray[np.uint16_t, ndim=2] out=None, - char shift_x=0, char shift_y=0, int bitdepth=8, float p0=0., float p1=0.): + char shift_x=0, char shift_y=0, int bitdepth=8, + float p0=0., float p1=0.): """return nb of pixels between [p0 and p1] """ - return _core16( - kernel_pop, image, selem, mask, out, shift_x, shift_y, bitdepth, p0, p1, - < Py_ssize_t > 0, < Py_ssize_t > 0) + _core16(kernel_pop, image, selem, mask, out, shift_x, shift_y, + bitdepth, p0, p1, 0, 0) def threshold(np.ndarray[np.uint16_t, ndim=2] image, np.ndarray[np.uint8_t, ndim=2] selem, np.ndarray[np.uint8_t, ndim=2] mask=None, np.ndarray[np.uint16_t, ndim=2] out=None, - char shift_x=0, char shift_y=0, int bitdepth=8, float p0=0., float p1=0.): + char shift_x=0, char shift_y=0, int bitdepth=8, + float p0=0., float p1=0.): """return (maxbin-1) if g > percentile p0 """ - return _core16( - kernel_threshold, image, selem, mask, out, shift_x, shift_y, bitdepth, p0, p1, - < Py_ssize_t > 0, < Py_ssize_t > 0) + _core16(kernel_threshold, image, selem, mask, out, shift_x, shift_y, + bitdepth, p0, p1, 0, 0) diff --git a/skimage/filter/rank/_crank8.pyx b/skimage/filter/rank/_crank8.pyx index 4efd2bb0..5b2cba01 100644 --- a/skimage/filter/rank/_crank8.pyx +++ b/skimage/filter/rank/_crank8.pyx @@ -315,9 +315,8 @@ def autolevel(np.ndarray[np.uint8_t, ndim=2] image, np.ndarray[np.uint8_t, ndim=2] mask=None, np.ndarray[np.uint8_t, ndim=2] out=None, char shift_x=0, char shift_y=0): - return _core8( - kernel_autolevel, image, selem, mask, out, shift_x, shift_y, .0, .0, < Py_ssize_t > 0, - < Py_ssize_t > 0) + _core8(kernel_autolevel, image, selem, mask, out, shift_x, shift_y, + 0, 0, 0, 0) def bottomhat(np.ndarray[np.uint8_t, ndim=2] image, @@ -325,9 +324,8 @@ def bottomhat(np.ndarray[np.uint8_t, ndim=2] image, np.ndarray[np.uint8_t, ndim=2] mask=None, np.ndarray[np.uint8_t, ndim=2] out=None, char shift_x=0, char shift_y=0): - return _core8( - kernel_bottomhat, image, selem, mask, out, shift_x, shift_y, .0, .0, < Py_ssize_t > 0, - < Py_ssize_t > 0) + _core8(kernel_bottomhat, image, selem, mask, out, shift_x, shift_y, + 0, 0, 0, 0) def equalize(np.ndarray[np.uint8_t, ndim=2] image, @@ -335,9 +333,8 @@ def equalize(np.ndarray[np.uint8_t, ndim=2] image, np.ndarray[np.uint8_t, ndim=2] mask=None, np.ndarray[np.uint8_t, ndim=2] out=None, char shift_x=0, char shift_y=0): - return _core8( - kernel_equalize, image, selem, mask, out, shift_x, shift_y, .0, .0, < Py_ssize_t > 0, - < Py_ssize_t > 0) + _core8(kernel_equalize, image, selem, mask, out, shift_x, shift_y, + 0, 0, 0, 0) def gradient(np.ndarray[np.uint8_t, ndim=2] image, @@ -345,9 +342,8 @@ def gradient(np.ndarray[np.uint8_t, ndim=2] image, np.ndarray[np.uint8_t, ndim=2] mask=None, np.ndarray[np.uint8_t, ndim=2] out=None, char shift_x=0, char shift_y=0): - return _core8( - kernel_gradient, image, selem, mask, out, shift_x, shift_y, .0, .0, < Py_ssize_t > 0, - < Py_ssize_t > 0) + _core8(kernel_gradient, image, selem, mask, out, shift_x, shift_y, + 0, 0, 0, 0) def maximum(np.ndarray[np.uint8_t, ndim=2] image, @@ -355,7 +351,8 @@ def maximum(np.ndarray[np.uint8_t, ndim=2] image, np.ndarray[np.uint8_t, ndim=2] mask=None, np.ndarray[np.uint8_t, ndim=2] out=None, char shift_x=0, char shift_y=0): - return _core8(kernel_maximum, image, selem, mask, out, shift_x, shift_y, .0, .0, < Py_ssize_t > 0, < Py_ssize_t > 0) + _core8(kernel_maximum, image, selem, mask, out, shift_x, shift_y, + 0, 0, 0, 0) def mean(np.ndarray[np.uint8_t, ndim=2] image, @@ -363,7 +360,8 @@ def mean(np.ndarray[np.uint8_t, ndim=2] image, np.ndarray[np.uint8_t, ndim=2] mask=None, np.ndarray[np.uint8_t, ndim=2] out=None, char shift_x=0, char shift_y=0): - return _core8(kernel_mean, image, selem, mask, out, shift_x, shift_y, .0, .0, < Py_ssize_t > 0, < Py_ssize_t > 0) + _core8(kernel_mean, image, selem, mask, out, shift_x, shift_y, + 0, 0, 0, 0) def meansubstraction(np.ndarray[np.uint8_t, ndim=2] image, @@ -371,9 +369,8 @@ def meansubstraction(np.ndarray[np.uint8_t, ndim=2] image, np.ndarray[np.uint8_t, ndim=2] mask=None, np.ndarray[np.uint8_t, ndim=2] out=None, char shift_x=0, char shift_y=0): - return _core8( - kernel_meansubstraction, image, selem, mask, out, shift_x, shift_y, .0, .0, < Py_ssize_t > 0, - < Py_ssize_t > 0) + _core8(kernel_meansubstraction, image, selem, mask, out, shift_x, shift_y, + 0, 0, 0, 0) def median(np.ndarray[np.uint8_t, ndim=2] image, @@ -381,7 +378,8 @@ def median(np.ndarray[np.uint8_t, ndim=2] image, np.ndarray[np.uint8_t, ndim=2] mask=None, np.ndarray[np.uint8_t, ndim=2] out=None, char shift_x=0, char shift_y=0): - return _core8(kernel_median, image, selem, mask, out, shift_x, shift_y, .0, .0, < Py_ssize_t > 0, < Py_ssize_t > 0) + _core8(kernel_median, image, selem, mask, out, shift_x, shift_y, + 0, 0, 0, 0) def minimum(np.ndarray[np.uint8_t, ndim=2] image, @@ -389,7 +387,8 @@ def minimum(np.ndarray[np.uint8_t, ndim=2] image, np.ndarray[np.uint8_t, ndim=2] mask=None, np.ndarray[np.uint8_t, ndim=2] out=None, char shift_x=0, char shift_y=0): - return _core8(kernel_minimum, image, selem, mask, out, shift_x, shift_y, .0, .0, < Py_ssize_t > 0, < Py_ssize_t > 0) + _core8(kernel_minimum, image, selem, mask, out, shift_x, shift_y, + 0, 0, 0, 0) def morph_contr_enh(np.ndarray[np.uint8_t, ndim=2] image, @@ -397,9 +396,8 @@ def morph_contr_enh(np.ndarray[np.uint8_t, ndim=2] image, np.ndarray[np.uint8_t, ndim=2] mask=None, np.ndarray[np.uint8_t, ndim=2] out=None, char shift_x=0, char shift_y=0): - return _core8( - kernel_morph_contr_enh, image, selem, mask, out, shift_x, shift_y, .0, .0, < Py_ssize_t > 0, - < Py_ssize_t > 0) + _core8(kernel_morph_contr_enh, image, selem, mask, out, shift_x, shift_y, + 0, 0, 0, 0) def modal(np.ndarray[np.uint8_t, ndim=2] image, @@ -407,7 +405,8 @@ def modal(np.ndarray[np.uint8_t, ndim=2] image, np.ndarray[np.uint8_t, ndim=2] mask=None, np.ndarray[np.uint8_t, ndim=2] out=None, char shift_x=0, char shift_y=0): - return _core8(kernel_modal, image, selem, mask, out, shift_x, shift_y, .0, .0, < Py_ssize_t > 0, < Py_ssize_t > 0) + _core8(kernel_modal, image, selem, mask, out, shift_x, shift_y, + 0, 0, 0, 0) def pop(np.ndarray[np.uint8_t, ndim=2] image, @@ -415,7 +414,8 @@ def pop(np.ndarray[np.uint8_t, ndim=2] image, np.ndarray[np.uint8_t, ndim=2] mask=None, np.ndarray[np.uint8_t, ndim=2] out=None, char shift_x=0, char shift_y=0): - return _core8(kernel_pop, image, selem, mask, out, shift_x, shift_y, .0, .0, < Py_ssize_t > 0, < Py_ssize_t > 0) + _core8(kernel_pop, image, selem, mask, out, shift_x, shift_y, + 0, 0, 0, 0) def threshold(np.ndarray[np.uint8_t, ndim=2] image, @@ -423,9 +423,8 @@ def threshold(np.ndarray[np.uint8_t, ndim=2] image, np.ndarray[np.uint8_t, ndim=2] mask=None, np.ndarray[np.uint8_t, ndim=2] out=None, char shift_x=0, char shift_y=0): - return _core8( - kernel_threshold, image, selem, mask, out, shift_x, shift_y, .0, .0, < Py_ssize_t > 0, - < Py_ssize_t > 0) + _core8(kernel_threshold, image, selem, mask, out, shift_x, shift_y, 0, 0, + 0, 0) def tophat(np.ndarray[np.uint8_t, ndim=2] image, @@ -433,7 +432,8 @@ def tophat(np.ndarray[np.uint8_t, ndim=2] image, np.ndarray[np.uint8_t, ndim=2] mask=None, np.ndarray[np.uint8_t, ndim=2] out=None, char shift_x=0, char shift_y=0): - return _core8(kernel_tophat, image, selem, mask, out, shift_x, shift_y, .0, .0, < Py_ssize_t > 0, < Py_ssize_t > 0) + _core8(kernel_tophat, image, selem, mask, out, shift_x, shift_y, + 0, 0, 0, 0) def noise_filter(np.ndarray[np.uint8_t, ndim=2] image, @@ -441,18 +441,21 @@ def noise_filter(np.ndarray[np.uint8_t, ndim=2] image, np.ndarray[np.uint8_t, ndim=2] mask=None, np.ndarray[np.uint8_t, ndim=2] out=None, char shift_x=0, char shift_y=0): - return _core8(kernel_noise_filter, image, selem, mask, out, shift_x, shift_y, .0, .0, < Py_ssize_t > 0, < Py_ssize_t > 0) + _core8(kernel_noise_filter, image, selem, mask, out, shift_x, shift_y, + 0, 0, 0, 0) def entropy(np.ndarray[np.uint8_t, ndim=2] image, np.ndarray[np.uint8_t, ndim=2] selem, np.ndarray[np.uint8_t, ndim=2] mask=None, np.ndarray[np.uint8_t, ndim=2] out=None, char shift_x=0, char shift_y=0): - return _core8(kernel_entropy, image, selem, mask, out, shift_x, shift_y, .0, .0, < Py_ssize_t > 0, < Py_ssize_t > 0) + _core8(kernel_entropy, image, selem, mask, out, shift_x, shift_y, + 0, 0, 0, 0) def otsu(np.ndarray[np.uint8_t, ndim=2] image, np.ndarray[np.uint8_t, ndim=2] selem, np.ndarray[np.uint8_t, ndim=2] mask=None, np.ndarray[np.uint8_t, ndim=2] out=None, char shift_x=0, char shift_y=0): - return _core8(kernel_otsu, image, selem, mask, out, shift_x, shift_y, .0, .0, < Py_ssize_t > 0, < Py_ssize_t > 0) + _core8(kernel_otsu, image, selem, mask, out, shift_x, shift_y, + 0, 0, 0, 0) diff --git a/skimage/filter/rank/_crank8_percentiles.pyx b/skimage/filter/rank/_crank8_percentiles.pyx index 618a6452..636295fd 100644 --- a/skimage/filter/rank/_crank8_percentiles.pyx +++ b/skimage/filter/rank/_crank8_percentiles.pyx @@ -201,9 +201,8 @@ def autolevel(np.ndarray[np.uint8_t, ndim=2] image, char shift_x=0, char shift_y=0, float p0=0., float p1=0.): """autolevel """ - return _core8( - kernel_autolevel, image, selem, mask, out, shift_x, shift_y, p0, p1, < Py_ssize_t > 0, - < Py_ssize_t > 0) + _core8(kernel_autolevel, image, selem, mask, out, shift_x, shift_y, p0, p1, + 0, 0) def gradient(np.ndarray[np.uint8_t, ndim=2] image, @@ -213,9 +212,8 @@ def gradient(np.ndarray[np.uint8_t, ndim=2] image, char shift_x=0, char shift_y=0, float p0=0., float p1=0.): """return p0,p1 percentile gradient """ - return _core8( - kernel_gradient, image, selem, mask, out, shift_x, shift_y, p0, p1, < Py_ssize_t > 0, - < Py_ssize_t > 0) + _core8(kernel_gradient, image, selem, mask, out, shift_x, shift_y, p0, p1, + 0, 0) def mean(np.ndarray[np.uint8_t, ndim=2] image, @@ -225,7 +223,8 @@ def mean(np.ndarray[np.uint8_t, ndim=2] image, char shift_x=0, char shift_y=0, float p0=0., float p1=0.): """return mean between [p0 and p1] percentiles """ - return _core8(kernel_mean, image, selem, mask, out, shift_x, shift_y, p0, p1, < Py_ssize_t > 0, < Py_ssize_t > 0) + _core8(kernel_mean, image, selem, mask, out, shift_x, shift_y, p0, p1, + 0, 0) def mean_substraction(np.ndarray[np.uint8_t, ndim=2] image, @@ -235,9 +234,8 @@ def mean_substraction(np.ndarray[np.uint8_t, ndim=2] image, char shift_x=0, char shift_y=0, float p0=0., float p1=0.): """return original - mean between [p0 and p1] percentiles *.5 +127 """ - return _core8( - kernel_mean_substraction, image, selem, mask, out, shift_x, shift_y, p0, p1, < Py_ssize_t > 0, - < Py_ssize_t > 0) + _core8(kernel_mean_substraction, image, selem, mask, out, shift_x, shift_y, + p0, p1, 0, 0) def morph_contr_enh(np.ndarray[np.uint8_t, ndim=2] image, @@ -247,9 +245,8 @@ def morph_contr_enh(np.ndarray[np.uint8_t, ndim=2] image, char shift_x=0, char shift_y=0, float p0=0., float p1=0.): """reforce contrast using percentiles """ - return _core8( - kernel_morph_contr_enh, image, selem, mask, out, shift_x, shift_y, p0, p1, < Py_ssize_t > 0, - < Py_ssize_t > 0) + _core8(kernel_morph_contr_enh, image, selem, mask, out, shift_x, shift_y, + p0, p1, 0, 0) def percentile(np.ndarray[np.uint8_t, ndim=2] image, @@ -259,9 +256,8 @@ def percentile(np.ndarray[np.uint8_t, ndim=2] image, char shift_x=0, char shift_y=0, float p0=0., float p1=0.): """return p0 percentile """ - return _core8( - kernel_percentile, image, selem, mask, out, shift_x, shift_y, p0, p1, < Py_ssize_t > 0, - < Py_ssize_t > 0) + _core8(kernel_percentile, image, selem, mask, out, shift_x, shift_y, + p0, p1, 0, 0) def pop(np.ndarray[np.uint8_t, ndim=2] image, @@ -271,7 +267,8 @@ def pop(np.ndarray[np.uint8_t, ndim=2] image, char shift_x=0, char shift_y=0, float p0=0., float p1=0.): """return nb of pixels between [p0 and p1] """ - return _core8(kernel_pop, image, selem, mask, out, shift_x, shift_y, p0, p1, < Py_ssize_t > 0, < Py_ssize_t > 0) + _core8(kernel_pop, image, selem, mask, out, shift_x, shift_y, p0, p1, + 0, 0) def threshold(np.ndarray[np.uint8_t, ndim=2] image, @@ -281,6 +278,5 @@ def threshold(np.ndarray[np.uint8_t, ndim=2] image, char shift_x=0, char shift_y=0, float p0=0., float p1=0.): """return 255 if g > percentile p0 """ - return _core8( - kernel_threshold, image, selem, mask, out, shift_x, shift_y, p0, p1, < Py_ssize_t > 0, - < Py_ssize_t > 0) + _core8(kernel_threshold, image, selem, mask, out, shift_x, shift_y, p0, p1, + 0, 0) diff --git a/skimage/filter/rank/bilateral_rank.pyx b/skimage/filter/rank/bilateral_rank.pyx index f181735b..39afa71a 100644 --- a/skimage/filter/rank/bilateral_rank.pyx +++ b/skimage/filter/rank/bilateral_rank.pyx @@ -1,31 +1,31 @@ -"""bilateral_rank.py - approximate bilateral rankfilter for local (custom kernel) mean +"""Approximate bilateral rankfilter for local (custom kernel) mean. -The local histogram is computed using a sliding window similar to the method described in +The local histogram is computed using a sliding window similar to the method +described in: -Reference: Huang, T. ,Yang, G. ; Tang, G.. "A fast two-dimensional median filtering algorithm", -IEEE Transactions on Acoustics, Speech and Signal Processing, Feb 1979. Volume: 27 , Issue: 1, Page(s): 13 - 18. +Reference: Huang, T. ,Yang, G. ; Tang, G.. "A fast two-dimensional median +filtering algorithm", IEEE Transactions on Acoustics, Speech and Signal +Processing, Feb 1979. Volume: 27 , Issue: 1, Page(s): 13 - 18. -input image can be 8 bit or 16 bit with a value < 4096 (i.e. 12 bit), -8 bit images are casted in 16 bit -the number of histogram bins is determined from the maximum value present in the image +Input image can be 8 bit or 16 bit with a value < 4096 (i.e. 12 bit), 8 bit +images are casted in 16 bit the number of histogram bins is determined from the +maximum value present in the image. The pixel neighborhood is defined by: * the given structuring element - * an interval [g-s0,g+s1] in gray level around g the processed pixel gray level -The kernel is flat (i.e. each pixel belonging to the neighborhood contributes equally) +The kernel is flat (i.e. each pixel belonging to the neighborhood contributes +equally). -result image is 16 bit with respect to the input image +Result image is 16 bit with respect to the input image. """ -from skimage import img_as_ubyte - import numpy as np +from skimage import img_as_ubyte from skimage.filter.rank import _crank16_bilateral - from skimage.filter.rank.generic import find_bitdepth @@ -34,52 +34,74 @@ __all__ = ['bilateral_mean', 'bilateral_pop'] def _apply(func8, func16, image, selem, out, mask, shift_x, shift_y, s0, s1): selem = img_as_ubyte(selem) - if mask is not None: - mask = img_as_ubyte(mask) - if image.dtype == np.uint8: - image = image.astype(np.uint16) - elif image.dtype == np.uint16: - pass + image = np.ascontiguousarray(image) + + if mask is None: + mask = np.ones(image.shape, dtype=np.uint8) else: - raise TypeError("only uint8 and uint16 image supported!") - bitdepth = find_bitdepth(image) - if bitdepth > 11: - raise ValueError("only uint16 <4096 image (12bit) supported!") - return func16( - image, selem, shift_x=shift_x, shift_y=shift_y, mask=mask, bitdepth=bitdepth + 1, out=out, - s0=s0, s1=s1) + mask = np.ascontiguousarray(mask) + mask = img_as_ubyte(mask) + if image is out: + raise NotImplementedError("Cannot perform rank operation in place.") + + mask = np.ascontiguousarray(mask) + if image.dtype == np.uint8: + if func8 is None: + raise TypeError("Not implemented for uint8 image.") + if out is None: + out = np.zeros(image.shape, dtype=np.uint8) + func8(image, selem, shift_x=shift_x, shift_y=shift_y, + mask=mask, out=out, s0=s0, s1=s1) + elif image.dtype == np.uint16: + if func16 is None: + raise TypeError("Not implemented for uint16 image.") + if out is None: + out = np.zeros(image.shape, dtype=np.uint16) + bitdepth = find_bitdepth(image) + if bitdepth > 11: + raise ValueError("Only uint16 <4096 image (12bit) supported.") + func16(image, selem, shift_x=shift_x, shift_y=shift_y, mask=mask, + bitdepth=bitdepth + 1, out=out, s0=s0, s1=s1) + else: + raise TypeError("Only uint8 and uint16 image supported.") + + return out -def bilateral_mean(image, selem, out=None, mask=None, shift_x=False, shift_y=False, s0=10, s1=10): +def bilateral_mean(image, selem, out=None, mask=None, shift_x=False, + shift_y=False, s0=10, s1=10): """Apply a flat kernel bilateral filter. This is an edge-preserving and noise reducing denoising filter. It averages pixels based on their spatial closeness and radiometric similarity. - Spatial closeness is measured by considering only the local pixel neighborhood given by a - structuring element (selem). + Spatial closeness is measured by considering only the local pixel + neighborhood given by a structuring element (selem). - Radiometric similarity is defined by the gray level interval [g-s0,g+s1] where g is the current pixel gray level. - Only pixels belonging to the structuring element AND having a gray level inside this interval are averaged. - Return greyscale local bilateral_mean of an image. + Radiometric similarity is defined by the gray level interval [g-s0,g+s1] + where g is the current pixel gray level. Only pixels belonging to the + structuring element AND having a gray level inside this interval are + averaged. Return greyscale local bilateral_mean of an image. Parameters ---------- image : ndarray - Image array (uint8 array or uint16). If image is uint16, as the algorithm uses max. 12bit histogram, - an exception will be raised if image has a value > 4095 + Image array (uint8 array or uint16). If image is uint16, as the + algorithm uses max. 12bit histogram, an exception will be raised if + image has a value > 4095 selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray If None, a new array will be allocated. mask : ndarray (uint8) - Mask array that defines (>0) area of the image included in the local neighborhood. - If None, the complete image is used (default). + Mask array that defines (>0) area of the image included in the local + neighborhood. If None, the complete image is used (default). shift_x, shift_y : (int) - Offset added to the structuring element center point. - Shift is bounded to the structuring element sizes (center must be inside the given structuring element). + Offset added to the structuring element center point. Shift is bounded + to the structuring element sizes (center must be inside the given + structuring element). s0, s1 : int - define the [s0,s1] interval to be considered for computing the value. + define the [s0, s1] interval to be considered for computing the value. Returns ------- @@ -108,32 +130,35 @@ def bilateral_mean(image, selem, out=None, mask=None, shift_x=False, shift_y=Fal >>> bilat_ima = bilateral_mean(ima, disk(20), s0=10,s1=10) """ - return _apply( - None, _crank16_bilateral.mean, image, selem, out=out, mask=mask, shift_x=shift_x, shift_y=shift_y, - s0=s0, s1=s1) + return _apply(None, _crank16_bilateral.mean, image, selem, out=out, + mask=mask, shift_x=shift_x, shift_y=shift_y, s0=s0, s1=s1) -def bilateral_pop(image, selem, out=None, mask=None, shift_x=False, shift_y=False, s0=10, s1=10): - """Return the number (population) of pixels actually inside the bilateral neighborhood, - i.e. being inside the structuring element AND having a gray level inside the interval [g-s0,g+s1]. +def bilateral_pop(image, selem, out=None, mask=None, shift_x=False, + shift_y=False, s0=10, s1=10): + """Return the number (population) of pixels actually inside the bilateral + neighborhood, i.e. being inside the structuring element AND having a gray + level inside the interval [g-s0, g+s1]. Parameters ---------- image : ndarray - Image array (uint8 array or uint16). If image is uint16, as the algorithm uses max. 12bit histogram, - an exception will be raised if image has a value > 4095 + Image array (uint8 array or uint16). If image is uint16, as the + algorithm uses max. 12bit histogram, an exception will be raised if + image has a value > 4095 selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray If None, a new array will be allocated. mask : ndarray (uint8) - Mask array that defines (>0) area of the image included in the local neighborhood. - If None, the complete image is used (default). + Mask array that defines (>0) area of the image included in the local + neighborhood. If None, the complete image is used (default). shift_x, shift_y : (int) - Offset added to the structuring element center point. - Shift is bounded to the structuring element sizes (center must be inside the given structuring element). + Offset added to the structuring element center point. Shift is bounded + to the structuring element sizes (center must be inside the given + structuring element). s0, s1 : int - define the [s0,s1] interval to be considered for computing the value. + define the [s0, s1] interval to be considered for computing the value. Returns ------- @@ -159,7 +184,5 @@ def bilateral_pop(image, selem, out=None, mask=None, shift_x=False, shift_y=Fals """ - return _apply( - None, _crank16_bilateral.pop, image, selem, out=out, mask=mask, shift_x=shift_x, shift_y=shift_y, - s0=s0, s1=s1) - + return _apply(None, _crank16_bilateral.pop, image, selem, out=out, + mask=mask, shift_x=shift_x, shift_y=shift_y, s0=s0, s1=s1) diff --git a/skimage/filter/rank/percentile_rank.pyx b/skimage/filter/rank/percentile_rank.pyx index 1bd89eb8..c5a5a594 100644 --- a/skimage/filter/rank/percentile_rank.pyx +++ b/skimage/filter/rank/percentile_rank.pyx @@ -1,337 +1,390 @@ -"""percentile_rank.py - inferior and superior ranks, provided by the user, are passed to the kernel function -to provide a softer version of the rank filters. E.g. percentile_autolevel will stretch image levels between -percentile [p0,p1] instead of using [min,max]. It means that isolate bright or dark pixels will not produce halos. +"""Inferior and superior ranks, provided by the user, are passed to the kernel +function to provide a softer version of the rank filters. E.g. +percentile_autolevel will stretch image levels between percentile [p0, p1] +instead of using [min,max]. It means that isolate bright or dark pixels will not +produce halos. -The local histogram is computed using a sliding window similar to the method described in +The local histogram is computed using a sliding window similar to the method +described in: -Reference: Huang, T. ,Yang, G. ; Tang, G.. "A fast two-dimensional median filtering algorithm", -IEEE Transactions on Acoustics, Speech and Signal Processing, Feb 1979. Volume: 27 , Issue: 1, Page(s): 13 - 18. +Reference: Huang, T. ,Yang, G. ; Tang, G.. "A fast two-dimensional median +filtering algorithm", IEEE Transactions on Acoustics, Speech and Signal +Processing, Feb 1979. Volume: 27 , Issue: 1, Page(s): 13 - 18. -input image can be 8 bit or 16 bit with a value < 4096 (i.e. 12 bit), -for 16 bit input images, the number of histogram bins is determined from the maximum value present in the image +Input image can be 8 bit or 16 bit with a value < 4096 (i.e. 12 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 or 16 bit with respect to the input image. """ -from skimage import img_as_ubyte import numpy as np - +from skimage import img_as_ubyte from skimage.filter.rank.generic import find_bitdepth from skimage.filter.rank import _crank16_percentiles, _crank8_percentiles + __all__ = ['percentile_autolevel', 'percentile_gradient', 'percentile_mean', 'percentile_mean_substraction', - 'percentile_morph_contr_enh', 'percentile', 'percentile_pop', 'percentile_threshold'] + 'percentile_morph_contr_enh', 'percentile', 'percentile_pop', + 'percentile_threshold'] def _apply(func8, func16, image, selem, out, mask, shift_x, shift_y, p0, p1): selem = img_as_ubyte(selem) - if mask is not None: + image = np.ascontiguousarray(image) + + if mask is None: + mask = np.ones(image.shape, dtype=np.uint8) + else: + mask = np.ascontiguousarray(mask) mask = img_as_ubyte(mask) + if image is out: + raise NotImplementedError("Cannot perform rank operation in place.") + + mask = np.ascontiguousarray(mask) if image.dtype == np.uint8: - return func8(image, selem, shift_x=shift_x, shift_y=shift_y, mask=mask, out=out, p0=p0, p1=p1) + if func8 is None: + raise TypeError("Not implemented for uint8 image.") + if out is None: + out = np.zeros(image.shape, dtype=np.uint8) + func8(image, selem, shift_x=shift_x, shift_y=shift_y, + mask=mask, out=out, p0=p0, p1=p1) elif image.dtype == np.uint16: + if func16 is None: + raise TypeError("Not implemented for uint16 image.") + if out is None: + out = np.zeros(image.shape, dtype=np.uint16) bitdepth = find_bitdepth(image) if bitdepth > 11: - raise ValueError("only uint16 <4096 image (12bit) supported!") - return func16( - image, selem, shift_x=shift_x, shift_y=shift_y, mask=mask, bitdepth=bitdepth + 1, out=out, - p0=p0, p1=p1) + raise ValueError("Only uint16 <4096 image (12bit) supported.") + func16(image, selem, shift_x=shift_x, shift_y=shift_y, mask=mask, + bitdepth=bitdepth + 1, out=out, p0=p0, p1=p1) else: - raise TypeError("only uint8 and uint16 image supported!") + raise TypeError("Only uint8 and uint16 image supported.") + + return out -def percentile_autolevel(image, selem, out=None, mask=None, shift_x=False, shift_y=False, p0=.0, p1=1.): +def percentile_autolevel(image, selem, out=None, mask=None, shift_x=False, + shift_y=False, p0=.0, p1=1.): """Return greyscale local autolevel of an image. - Autolevel is computed on the given structuring element. Only levels between percentiles [p0,p1] ,are used. + Autolevel is computed on the given structuring element. Only levels between + percentiles [p0, p1] are used. Parameters ---------- image : ndarray - Image array (uint8 array or uint16). If image is uint16, as the algorithm uses max. 12bit histogram, - an exception will be raised if image has a value > 4095 + Image array (uint8 array or uint16). If image is uint16, as the + algorithm uses max. 12bit histogram, an exception will be raised if + image has a value > 4095. selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray If None, a new array will be allocated. mask : ndarray (uint8) - Mask array that defines (>0) area of the image included in the local neighborhood. - If None, the complete image is used (default). - shift_x, shift_y : (int) - Offset added to the structuring element center point. - Shift is bounded to the structuring element sizes (center must be inside the given structuring element). - p0, p1 : float in [0.,...,1.] - define the [p0,p1] percentile interval to be considered for computing the value. + Mask array that defines (>0) area of the image included in the local + neighborhood. If None, the complete image is used (default). + shift_x, shift_y : int + Offset added to the structuring element center point. Shift is bounded + to the structuring element sizes (center must be inside the given + structuring element). + p0, p1 : float in [0, ..., 1] + Define the [p0, p1] percentile interval to be considered for computing + the value. Returns ------- - local autolevel : uint8 array or uint16 array depending on input image + local autolevel : uint8 array or uint16 The result of the local autolevel. - """ - return _apply( - _crank8_percentiles.autolevel, _crank16_percentiles.autolevel, image, selem, out=out, mask=mask, - shift_x=shift_x, shift_y=shift_y, p0=p0, p1=p1) + return _apply(_crank8_percentiles.autolevel, _crank16_percentiles.autolevel, + image, selem, out=out, mask=mask, shift_x=shift_x, + shift_y=shift_y, p0=p0, p1=p1) -def percentile_gradient(image, selem, out=None, mask=None, shift_x=False, shift_y=False, p0=.0, p1=1.): +def percentile_gradient(image, selem, out=None, mask=None, shift_x=False, + shift_y=False, p0=.0, p1=1.): """Return greyscale local percentile_gradient of an image. - percentile_gradient is computed on the given structuring element. Only levels between percentiles [p0,p1] ,are used. + percentile_gradient is computed on the given structuring element. Only + levels between percentiles [p0, p1] are used. Parameters ---------- image : ndarray - Image array (uint8 array or uint16). If image is uint16, as the algorithm uses max. 12bit histogram, - an exception will be raised if image has a value > 4095 + Image array (uint8 array or uint16). If image is uint16, as the + algorithm uses max. 12bit histogram, an exception will be raised if + image has a value > 4095. selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray If None, a new array will be allocated. mask : ndarray (uint8) - Mask array that defines (>0) area of the image included in the local neighborhood. - If None, the complete image is used (default). - shift_x, shift_y : (int) - Offset added to the structuring element center point. - Shift is bounded to the structuring element sizes (center must be inside the given structuring element). - p0, p1 : float in [0.,...,1.] - define the [p0,p1] percentile interval to be considered for computing the value. + Mask array that defines (>0) area of the image included in the local + neighborhood. If None, the complete image is used (default). + shift_x, shift_y : int + Offset added to the structuring element center point. Shift is bounded + to the structuring element sizes (center must be inside the given + structuring element). + p0, p1 : float in [0, ..., 1] + Define the [p0, p1] percentile interval to be considered for computing + the value. Returns ------- - local percentile_gradient : uint8 array or uint16 array depending on input image + local percentile_gradient : uint8 array or uint16 The result of the local percentile_gradient. - - """ - return _apply( - _crank8_percentiles.gradient, _crank16_percentiles.gradient, image, selem, out=out, mask=mask, - shift_x=shift_x, shift_y=shift_y, p0=p0, p1=p1) + return _apply(_crank8_percentiles.gradient, _crank16_percentiles.gradient, + image, selem, out=out, mask=mask, shift_x=shift_x, + shift_y=shift_y, p0=p0, p1=p1) -def percentile_mean(image, selem, out=None, mask=None, shift_x=False, shift_y=False, p0=.0, p1=1.): +def percentile_mean(image, selem, out=None, mask=None, shift_x=False, + shift_y=False, p0=.0, p1=1.): """Return greyscale local mean of an image. - Mean is computed on the given structuring element. Only levels between percentiles [p0,p1] ,are used. + Mean is computed on the given structuring element. Only levels between + percentiles [p0, p1] are used. Parameters ---------- image : ndarray - Image array (uint8 array or uint16). If image is uint16, as the algorithm uses max. 12bit histogram, - an exception will be raised if image has a value > 4095 + Image array (uint8 array or uint16). If image is uint16, as the + algorithm uses max. 12bit histogram, an exception will be raised if + image has a value > 4095. selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray If None, a new array will be allocated. mask : ndarray (uint8) - Mask array that defines (>0) area of the image included in the local neighborhood. - If None, the complete image is used (default). - shift_x, shift_y : (int) - Offset added to the structuring element center point. - Shift is bounded to the structuring element sizes (center must be inside the given structuring element). - p0, p1 : float in [0.,...,1.] - define the [p0,p1] percentile interval to be considered for computing the value. + Mask array that defines (>0) area of the image included in the local + neighborhood. If None, the complete image is used (default). + shift_x, shift_y : int + Offset added to the structuring element center point. Shift is bounded + to the structuring element sizes (center must be inside the given + structuring element). + p0, p1 : float in [0, ..., 1] + Define the [p0, p1] percentile interval to be considered for computing + the value. Returns ------- - local mean : uint8 array or uint16 array depending on input image + local mean : uint8 array or uint16 The result of the local mean. - """ - return _apply( - _crank8_percentiles.mean, _crank16_percentiles.mean, image, selem, out=out, mask=mask, - shift_x=shift_x, shift_y=shift_y, p0=p0, p1=p1) + return _apply(_crank8_percentiles.mean, _crank16_percentiles.mean, + image, selem, out=out, mask=mask, shift_x=shift_x, + shift_y=shift_y, p0=p0, p1=p1) -def percentile_mean_substraction(image, selem, out=None, mask=None, shift_x=False, shift_y=False, p0=.0, p1=1.): +def percentile_mean_substraction(image, selem, out=None, mask=None, + shift_x=False, shift_y=False, p0=.0, p1=1.): """Return greyscale local mean_substraction of an image. - mean_substraction is computed on the given structuring element. Only levels between percentiles [p0,p1] ,are used. + mean_substraction is computed on the given structuring element. Only levels + between percentiles [p0, p1] are used. Parameters ---------- image : ndarray - Image array (uint8 array or uint16). If image is uint16, as the algorithm uses max. 12bit histogram, - an exception will be raised if image has a value > 4095 + Image array (uint8 array or uint16). If image is uint16, as the + algorithm uses max. 12bit histogram, an exception will be raised if + image has a value > 4095. selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray If None, a new array will be allocated. mask : ndarray (uint8) - Mask array that defines (>0) area of the image included in the local neighborhood. - If None, the complete image is used (default). - shift_x, shift_y : (int) - Offset added to the structuring element center point. - Shift is bounded to the structuring element sizes (center must be inside the given structuring element). - p0, p1 : float in [0.,...,1.] - define the [p0,p1] percentile interval to be considered for computing the value. + Mask array that defines (>0) area of the image included in the local + neighborhood. If None, the complete image is used (default). + shift_x, shift_y : int + Offset added to the structuring element center point. Shift is bounded + to the structuring element sizes (center must be inside the given + structuring element). + p0, p1 : float in [0, ..., 1] + Define the [p0, p1] percentile interval to be considered for computing + the value. Returns ------- - local mean_substraction : uint8 array or uint16 array depending on input image + local mean_substraction : uint8 array or uint16 The result of the local mean_substraction. - - """ - return _apply( - _crank8_percentiles.mean_substraction, _crank16_percentiles.mean_substraction, image, selem, out=out, - mask=mask, shift_x=shift_x, shift_y=shift_y, p0=p0, p1=p1) + return _apply(_crank8_percentiles.mean_substraction, + _crank16_percentiles.mean_substraction, + image, selem, out=out, mask=mask, shift_x=shift_x, + shift_y=shift_y, p0=p0, p1=p1) -def percentile_morph_contr_enh(image, selem, out=None, mask=None, shift_x=False, shift_y=False, p0=.0, p1=1.): +def percentile_morph_contr_enh(image, selem, out=None, mask=None, shift_x=False, + shift_y=False, p0=.0, p1=1.): """Return greyscale local morph_contr_enh of an image. - morph_contr_enh is computed on the given structuring element. Only levels between percentiles [p0,p1] ,are used. + morph_contr_enh is computed on the given structuring element. Only levels + between percentiles [p0, p1] are used. Parameters ---------- image : ndarray - Image array (uint8 array or uint16). If image is uint16, as the algorithm uses max. 12bit histogram, - an exception will be raised if image has a value > 4095 + Image array (uint8 array or uint16). If image is uint16, as the + algorithm uses max. 12bit histogram, an exception will be raised if + image has a value > 4095. selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray If None, a new array will be allocated. mask : ndarray (uint8) - Mask array that defines (>0) area of the image included in the local neighborhood. - If None, the complete image is used (default). - shift_x, shift_y : (int) - Offset added to the structuring element center point. - Shift is bounded to the structuring element sizes (center must be inside the given structuring element). - p0, p1 : float in [0.,...,1.] - define the [p0,p1] percentile interval to be considered for computing the value. + Mask array that defines (>0) area of the image included in the local + neighborhood. If None, the complete image is used (default). + shift_x, shift_y : int + Offset added to the structuring element center point. Shift is bounded + to the structuring element sizes (center must be inside the given + structuring element). + p0, p1 : float in [0, ..., 1] + Define the [p0, p1] percentile interval to be considered for computing + the value. Returns ------- - local morph_contr_enh : uint8 array or uint16 array depending on input image + local morph_contr_enh : uint8 array or uint16 The result of the local morph_contr_enh. - - """ - return _apply( - _crank8_percentiles.morph_contr_enh, _crank16_percentiles.morph_contr_enh, image, selem, out=out, - mask=mask, shift_x=shift_x, shift_y=shift_y, p0=p0, p1=p1) + return _apply(_crank8_percentiles.morph_contr_enh, + _crank16_percentiles.morph_contr_enh, + image, selem, out=out, mask=mask, shift_x=shift_x, + shift_y=shift_y, p0=p0, p1=p1) -def percentile(image, selem, out=None, mask=None, shift_x=False, shift_y=False, p0=.0, p1=1.): +def percentile(image, selem, out=None, mask=None, shift_x=False, shift_y=False, + p0=.0, p1=1.): """Return greyscale local percentile of an image. - percentile is computed on the given structuring element. Only levels between percentiles [p0,p1] ,are used. + percentile is computed on the given structuring element. Only levels between + percentiles [p0, p1] are used. Parameters ---------- image : ndarray - Image array (uint8 array or uint16). If image is uint16, as the algorithm uses max. 12bit histogram, - an exception will be raised if image has a value > 4095 + Image array (uint8 array or uint16). If image is uint16, as the + algorithm uses max. 12bit histogram, an exception will be raised if + image has a value > 4095. selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray If None, a new array will be allocated. mask : ndarray (uint8) - Mask array that defines (>0) area of the image included in the local neighborhood. - If None, the complete image is used (default). - shift_x, shift_y : (int) - Offset added to the structuring element center point. - Shift is bounded to the structuring element sizes (center must be inside the given structuring element). - p0, p1 : float in [0.,...,1.] - define the [p0,p1] percentile interval to be considered for computing the value. + Mask array that defines (>0) area of the image included in the local + neighborhood. If None, the complete image is used (default). + shift_x, shift_y : int + Offset added to the structuring element center point. Shift is bounded + to the structuring element sizes (center must be inside the given + structuring element). + p0, p1 : float in [0, ..., 1] + Define the [p0, p1] percentile interval to be considered for computing + the value. Returns ------- - local percentile : uint8 array or uint16 array depending on input image + local percentile : uint8 array or uint16 The result of the local percentile. - - """ - return _apply( - _crank8_percentiles.percentile, _crank16_percentiles.percentile, image, selem, out=out, mask=mask, - shift_x=shift_x, shift_y=shift_y, p0=p0, p1=p1) + return _apply(_crank8_percentiles.percentile, + _crank16_percentiles.percentile, + image, selem, out=out, mask=mask, shift_x=shift_x, + shift_y=shift_y, p0=p0, p1=p1) -def percentile_pop(image, selem, out=None, mask=None, shift_x=False, shift_y=False, p0=.0, p1=1.): +def percentile_pop(image, selem, out=None, mask=None, shift_x=False, + shift_y=False, p0=.0, p1=1.): """Return greyscale local pop of an image. - pop is computed on the given structuring element. Only levels between percentiles [p0,p1] ,are used. + pop is computed on the given structuring element. Only levels between + percentiles [p0, p1] are used. Parameters ---------- image : ndarray - Image array (uint8 array or uint16). If image is uint16, as the algorithm uses max. 12bit histogram, - an exception will be raised if image has a value > 4095 + Image array (uint8 array or uint16). If image is uint16, as the + algorithm uses max. 12bit histogram, an exception will be raised if + image has a value > 4095. selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray If None, a new array will be allocated. mask : ndarray (uint8) - Mask array that defines (>0) area of the image included in the local neighborhood. - If None, the complete image is used (default). - shift_x, shift_y : (int) - Offset added to the structuring element center point. - Shift is bounded to the structuring element sizes (center must be inside the given structuring element). - p0, p1 : float in [0.,...,1.] - define the [p0,p1] percentile interval to be considered for computing the value. + Mask array that defines (>0) area of the image included in the local + neighborhood. If None, the complete image is used (default). + shift_x, shift_y : int + Offset added to the structuring element center point. Shift is bounded + to the structuring element sizes (center must be inside the given + structuring element). + p0, p1 : float in [0, ..., 1] + Define the [p0, p1] percentile interval to be considered for computing + the value. Returns ------- - local pop : uint8 array or uint16 array depending on input image + local pop : uint8 array or uint16 The result of the local pop. - - """ - return _apply( - _crank8_percentiles.pop, _crank16_percentiles.pop, image, selem, out=out, mask=mask, shift_x=shift_x, - shift_y=shift_y, p0=p0, p1=p1) + return _apply(_crank8_percentiles.pop, _crank16_percentiles.pop, + image, selem, out=out, mask=mask, shift_x=shift_x, + shift_y=shift_y, p0=p0, p1=p1) -def percentile_threshold(image, selem, out=None, mask=None, shift_x=False, shift_y=False, p0=.0, p1=1.): +def percentile_threshold(image, selem, out=None, mask=None, shift_x=False, + shift_y=False, p0=.0, p1=1.): """Return greyscale local threshold of an image. - threshold is computed on the given structuring element. Only levels between percentiles [p0,p1] ,are used. + threshold is computed on the given structuring element. Only levels between + percentiles [p0, p1] are used. Parameters ---------- image : ndarray - Image array (uint8 array or uint16). If image is uint16, as the algorithm uses max. 12bit histogram, - an exception will be raised if image has a value > 4095 + Image array (uint8 array or uint16). If image is uint16, as the + algorithm uses max. 12bit histogram, an exception will be raised if + image has a value > 4095. selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray If None, a new array will be allocated. mask : ndarray (uint8) - Mask array that defines (>0) area of the image included in the local neighborhood. - If None, the complete image is used (default). - shift_x, shift_y : (int) - Offset added to the structuring element center point. - Shift is bounded to the structuring element sizes (center must be inside the given structuring element). - p0, p1 : float in [0.,...,1.] - define the [p0,p1] percentile interval to be considered for computing the value. + Mask array that defines (>0) area of the image included in the local + neighborhood. If None, the complete image is used (default). + shift_x, shift_y : int + Offset added to the structuring element center point. Shift is bounded + to the structuring element sizes (center must be inside the given + structuring element). + p0, p1 : float in [0, ..., 1] + Define the [p0, p1] percentile interval to be considered for computing + the value. Returns ------- - local threshold : uint8 array or uint16 array depending on input image + local threshold : uint8 array or uint16 The result of the local threshold. - """ - return _apply( - _crank8_percentiles.threshold, _crank16_percentiles.threshold, image, selem, out=out, mask=mask, - shift_x=shift_x, shift_y=shift_y, p0=p0, p1=p1) - - + return _apply(_crank8_percentiles.threshold, _crank16_percentiles.threshold, + image, selem, out=out, mask=mask, shift_x=shift_x, + shift_y=shift_y, p0=p0, p1=p1) diff --git a/skimage/filter/rank/rank.pyx b/skimage/filter/rank/rank.pyx index 6a35920b..8ac98f81 100644 --- a/skimage/filter/rank/rank.pyx +++ b/skimage/filter/rank/rank.pyx @@ -1,44 +1,63 @@ -"""rank.py - rankfilter for local (custom kernel) maximum, minimum, median, mean, auto-level, equalization, etc +"""The local histogram is computed using a sliding window similar to the method +described in: -The local histogram is computed using a sliding window similar to the method described in +Reference: Huang, T. ,Yang, G. ; Tang, G.. "A fast two-dimensional median +filtering algorithm", IEEE Transactions on Acoustics, Speech and Signal +Processing, Feb 1979. Volume: 27 , Issue: 1, Page(s): 13 - 18. -Reference: Huang, T. ,Yang, G. ; Tang, G.. "A fast two-dimensional median filtering algorithm", -IEEE Transactions on Acoustics, Speech and Signal Processing, Feb 1979. Volume: 27 , Issue: 1, Page(s): 13 - 18. +Input image can be 8 bit or 16 bit with a value < 4096 (i.e. 12 bit), for 16 bit +input images, the number of histogram bins is determined from the maximum value +present in the image. -input image can be 8 bit or 16 bit with a value < 4096 (i.e. 12 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 or 16 bit with respect to the input image. """ -from skimage import img_as_ubyte import numpy as np +from skimage import img_as_ubyte from skimage.filter.rank import _crank8, _crank16 - from skimage.filter.rank.generic import find_bitdepth -__all__ = ['autolevel', 'bottomhat', 'equalize', 'gradient', 'maximum', 'mean', 'meansubstraction', 'median', 'minimum', - 'modal', 'morph_contr_enh', 'pop', 'threshold', 'tophat','noise_filter','entropy','otsu'] + +__all__ = ['autolevel', 'bottomhat', 'equalize', 'gradient', 'maximum', 'mean', + 'meansubstraction', 'median', 'minimum', 'modal', 'morph_contr_enh', + 'pop', 'threshold', 'tophat','noise_filter','entropy','otsu'] def _apply(func8, func16, image, selem, out, mask, shift_x, shift_y): selem = img_as_ubyte(selem) - if mask is not None: + image = np.ascontiguousarray(image) + + if mask is None: + mask = np.ones(image.shape, dtype=np.uint8) + else: + mask = np.ascontiguousarray(mask) mask = img_as_ubyte(mask) + if image is out: + raise NotImplementedError("Cannot perform rank operation in place.") + + mask = np.ascontiguousarray(mask) if image.dtype == np.uint8: if func8 is None: - raise TypeError("not implemented for uint8 image") - return func8(image, selem, shift_x=shift_x, shift_y=shift_y, mask=mask, out=out) + raise TypeError("Not implemented for uint8 image.") + if out is None: + out = np.zeros(image.shape, dtype=np.uint8) + func8(image, selem, shift_x=shift_x, shift_y=shift_y, + mask=mask, out=out) elif image.dtype == np.uint16: if func16 is None: - raise TypeError("not implemented for uint16 image") + raise TypeError("Not implemented for uint16 image.") + if out is None: + out = np.zeros(image.shape, dtype=np.uint16) bitdepth = find_bitdepth(image) if bitdepth > 11: - raise ValueError("only uint16 <4096 image (12bit) supported!") - return func16(image, selem, shift_x=shift_x, shift_y=shift_y, mask=mask, bitdepth=bitdepth + 1, out=out) + raise ValueError("Only uint16 <4096 image (12bit) supported.") + func16(image, selem, shift_x=shift_x, shift_y=shift_y, mask=mask, + bitdepth=bitdepth + 1, out=out) else: - raise TypeError("only uint8 and uint16 image supported!") + raise TypeError("Only uint8 and uint16 image supported.") + + return out def autolevel(image, selem, out=None, mask=None, shift_x=False, shift_y=False): @@ -47,18 +66,20 @@ def autolevel(image, selem, out=None, mask=None, shift_x=False, shift_y=False): Parameters ---------- image : ndarray - Image array (uint8 array or uint16). If image is uint16, the algorithm uses max. 12bit histogram, - an exception will be raised if image has a value > 4095 + Image array (uint8 array or uint16). If image is uint16, the algorithm + uses max. 12bit histogram, an exception will be raised if image has a + value > 4095. selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray If None, a new array will be allocated. mask : ndarray (uint8) - Mask array that defines (>0) area of the image included in the local neighborhood. - If None, the complete image is used (default). - shift_x, shift_y : (int) - Offset added to the structuring element center point. - Shift is bounded to the structuring element sizes (center must be inside the given structuring element). + Mask array that defines (>0) area of the image included in the local + neighborhood. If None, the complete image is used (default). + shift_x, shift_y : int + Offset added to the structuring element center point. Shift is bounded + to the structuring element sizes (center must be inside the given + structuring element). Returns ------- @@ -77,9 +98,8 @@ def autolevel(image, selem, out=None, mask=None, shift_x=False, shift_y=False): """ - return _apply( - _crank8.autolevel, _crank16.autolevel, image, selem, out=out, mask=mask, shift_x=shift_x, - shift_y=shift_y) + return _apply(_crank8.autolevel, _crank16.autolevel, image, selem, out=out, + mask=mask, shift_x=shift_x, shift_y=shift_y) def bottomhat(image, selem, out=None, mask=None, shift_x=False, shift_y=False): @@ -88,30 +108,30 @@ def bottomhat(image, selem, out=None, mask=None, shift_x=False, shift_y=False): Parameters ---------- image : ndarray - Image array (uint8 array or uint16). If image is uint16, the algorithm uses max. 12bit histogram, - an exception will be raised if image has a value > 4095 + Image array (uint8 array or uint16). If image is uint16, the algorithm + uses max. 12bit histogram, an exception will be raised if image has a + value > 4095. selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray If None, a new array will be allocated. mask : ndarray (uint8) - Mask array that defines (>0) area of the image included in the local neighborhood. - If None, the complete image is used (default). - shift_x, shift_y : (int) - Offset added to the structuring element center point. - Shift is bounded to the structuring element sizes (center must be inside the given structuring element). + Mask array that defines (>0) area of the image included in the local + neighborhood. If None, the complete image is used (default). + shift_x, shift_y : int + Offset added to the structuring element center point. Shift is bounded + to the structuring element sizes (center must be inside the given + structuring element). Returns ------- local bottomhat : uint8 array or uint16 array depending on input image The result of the local bottomhat. - """ - return _apply( - _crank8.bottomhat, _crank16.bottomhat, image, selem, out=out, mask=mask, shift_x=shift_x, - shift_y=shift_y) + return _apply(_crank8.bottomhat, _crank16.bottomhat, image, selem, out=out, + mask=mask, shift_x=shift_x, shift_y=shift_y) def equalize(image, selem, out=None, mask=None, shift_x=False, shift_y=False): @@ -120,18 +140,20 @@ def equalize(image, selem, out=None, mask=None, shift_x=False, shift_y=False): Parameters ---------- image : ndarray - Image array (uint8 array or uint16). If image is uint16, the algorithm uses max. 12bit histogram, - an exception will be raised if image has a value > 4095 + Image array (uint8 array or uint16). If image is uint16, the algorithm + uses max. 12bit histogram, an exception will be raised if image has a + value > 4095. selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray If None, a new array will be allocated. mask : ndarray (uint8) - Mask array that defines (>0) area of the image included in the local neighborhood. - If None, the complete image is used (default). - shift_x, shift_y : (int) - Offset added to the structuring element center point. - Shift is bounded to the structuring element sizes (center must be inside the given structuring element). + Mask array that defines (>0) area of the image included in the local + neighborhood. If None, the complete image is used (default). + shift_x, shift_y : int + Offset added to the structuring element center point. Shift is bounded + to the structuring element sizes (center must be inside the given + structuring element). Returns ------- @@ -147,32 +169,35 @@ def equalize(image, selem, out=None, mask=None, shift_x=False, shift_y=False): >>> ima = data.camera() >>> # Local equalization >>> equ = equalize(ima, disk(20)) + """ - return _apply( - _crank8.equalize, _crank16.equalize, image, selem, out=out, mask=mask, shift_x=shift_x, - shift_y=shift_y) + return _apply(_crank8.equalize, _crank16.equalize, image, selem, out=out, + mask=mask, shift_x=shift_x, shift_y=shift_y) def gradient(image, selem, out=None, mask=None, shift_x=False, shift_y=False): - """Return greyscale local gradient of an image (i.e. local maximum - local minimum). + """Return greyscale local gradient of an image (i.e. local maximum - local + minimum). Parameters ---------- image : ndarray - Image array (uint8 array or uint16). If image is uint16, the algorithm uses max. 12bit histogram, - an exception will be raised if image has a value > 4095 + Image array (uint8 array or uint16). If image is uint16, the algorithm + uses max. 12bit histogram, an exception will be raised if image has a + value > 4095. selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray If None, a new array will be allocated. mask : ndarray (uint8) - Mask array that defines (>0) area of the image included in the local neighborhood. - If None, the complete image is used (default). - shift_x, shift_y : (int) - Offset added to the structuring element center point. - Shift is bounded to the structuring element sizes (center must be inside the given structuring element). + Mask array that defines (>0) area of the image included in the local + neighborhood. If None, the complete image is used (default). + shift_x, shift_y : int + Offset added to the structuring element center point. Shift is bounded + to the structuring element sizes (center must be inside the given + structuring element). Returns ------- @@ -181,9 +206,8 @@ def gradient(image, selem, out=None, mask=None, shift_x=False, shift_y=False): """ - return _apply( - _crank8.gradient, _crank16.gradient, image, selem, out=out, mask=mask, shift_x=shift_x, - shift_y=shift_y) + return _apply(_crank8.gradient, _crank16.gradient, image, selem, out=out, + mask=mask, shift_x=shift_x, shift_y=shift_y) def maximum(image, selem, out=None, mask=None, shift_x=False, shift_y=False): @@ -193,18 +217,20 @@ def maximum(image, selem, out=None, mask=None, shift_x=False, shift_y=False): Parameters ---------- image : ndarray - Image array (uint8 array or uint16). If image is uint16, the algorithm uses max. 12bit histogram, - an exception will be raised if image has a value > 4095 + Image array (uint8 array or uint16). If image is uint16, the algorithm + uses max. 12bit histogram, an exception will be raised if image has a + value > 4095. selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray If None, a new array will be allocated. mask : ndarray (uint8) - Mask array that defines (>0) area of the image included in the local neighborhood. - If None, the complete image is used (default). - shift_x, shift_y : (int) - Offset added to the structuring element center point. - Shift is bounded to the structuring element sizes (center must be inside the given structuring element). + Mask array that defines (>0) area of the image included in the local + neighborhood. If None, the complete image is used (default). + shift_x, shift_y : int + Offset added to the structuring element center point. Shift is bounded + to the structuring element sizes (center must be inside the given + structuring element). Returns ------- @@ -213,17 +239,18 @@ def maximum(image, selem, out=None, mask=None, shift_x=False, shift_y=False): See also -------- - skimage.morphology.dilation() + skimage.morphology.dilation Note ---- * input image can be 8 bit or 16 bit with a value < 4096 (i.e. 12 bit) - - * the lower algorithm complexity makes the rank.maximum() more efficient for larger images and structuring elements + * the lower algorithm complexity makes the rank.maximum() more efficient for + larger images and structuring elements """ - return _apply(_crank8.maximum, _crank16.maximum, image, selem, out=out, mask=mask, shift_x=shift_x, shift_y=shift_y) + return _apply(_crank8.maximum, _crank16.maximum, image, selem, out=out, + mask=mask, shift_x=shift_x, shift_y=shift_y) def mean(image, selem, out=None, mask=None, shift_x=False, shift_y=False): @@ -232,18 +259,20 @@ def mean(image, selem, out=None, mask=None, shift_x=False, shift_y=False): Parameters ---------- image : ndarray - Image array (uint8 array or uint16). If image is uint16, the algorithm uses max. 12bit histogram, - an exception will be raised if image has a value > 4095 + Image array (uint8 array or uint16). If image is uint16, the algorithm + uses max. 12bit histogram, an exception will be raised if image has a + value > 4095. selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray If None, a new array will be allocated. mask : ndarray (uint8) - Mask array that defines (>0) area of the image included in the local neighborhood. - If None, the complete image is used (default). - shift_x, shift_y : (int) - Offset added to the structuring element center point. - Shift is bounded to the structuring element sizes (center must be inside the given structuring element). + Mask array that defines (>0) area of the image included in the local + neighborhood. If None, the complete image is used (default). + shift_x, shift_y : int + Offset added to the structuring element center point. Shift is bounded + to the structuring element sizes (center must be inside the given + structuring element). Returns ------- @@ -259,63 +288,66 @@ def mean(image, selem, out=None, mask=None, shift_x=False, shift_y=False): >>> ima = data.camera() >>> # Local mean >>> avg = mean(ima, disk(20)) + """ - return _apply(_crank8.mean, _crank16.mean, image, selem, out=out, mask=mask, shift_x=shift_x, shift_y=shift_y) + return _apply(_crank8.mean, _crank16.mean, image, selem, out=out, + mask=mask, shift_x=shift_x, shift_y=shift_y) -def meansubstraction(image, selem, out=None, mask=None, shift_x=False, shift_y=False): +def meansubstraction(image, selem, out=None, mask=None, shift_x=False, + shift_y=False): """Return image substracted from its local mean. Parameters ---------- image : ndarray - Image array (uint8 array or uint16). If image is uint16, the algorithm uses max. 12bit histogram, - an exception will be raised if image has a value > 4095 + Image array (uint8 array or uint16). If image is uint16, the algorithm + uses max. 12bit histogram, an exception will be raised if image has a + value > 4095. selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray If None, a new array will be allocated. mask : ndarray (uint8) - Mask array that defines (>0) area of the image included in the local neighborhood. - If None, the complete image is used (default). - shift_x, shift_y : (int) - Offset added to the structuring element center point. - Shift is bounded to the structuring element sizes (center must be inside the given structuring element). + Mask array that defines (>0) area of the image included in the local + neighborhood. If None, the complete image is used (default). + shift_x, shift_y : int + Offset added to the structuring element center point. Shift is bounded + to the structuring element sizes (center must be inside the given + structuring element). Returns ------- out : uint8 array or uint16 array (same as input image) The result of the local meansubstraction. - - """ - return _apply( - _crank8.meansubstraction, _crank16.meansubstraction, image, selem, out=out, mask=mask, - shift_x=shift_x, shift_y=shift_y) + return _apply(_crank8.meansubstraction, _crank16.meansubstraction, image, + selem, out=out, mask=mask, shift_x=shift_x, shift_y=shift_y) def median(image, selem, out=None, mask=None, shift_x=False, shift_y=False): """Return greyscale local median of an image. - Parameters ---------- image : ndarray - Image array (uint8 array or uint16). If image is uint16, the algorithm uses max. 12bit histogram, - an exception will be raised if image has a value > 4095 + Image array (uint8 array or uint16). If image is uint16, the algorithm + uses max. 12bit histogram, an exception will be raised if image has a + value > 4095. selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray If None, a new array will be allocated. mask : ndarray (uint8) - Mask array that defines (>0) area of the image included in the local neighborhood. - If None, the complete image is used (default). - shift_x, shift_y : (int) - Offset added to the structuring element center point. - Shift is bounded to the structuring element sizes (center must be inside the given structuring element). + Mask array that defines (>0) area of the image included in the local + neighborhood. If None, the complete image is used (default). + shift_x, shift_y : int + Offset added to the structuring element center point. Shift is bounded + to the structuring element sizes (center must be inside the given + structuring element). Returns ------- @@ -331,9 +363,11 @@ def median(image, selem, out=None, mask=None, shift_x=False, shift_y=False): >>> ima = data.camera() >>> # Local mean >>> avg = median(ima, disk(20)) + """ - return _apply(_crank8.median, _crank16.median, image, selem, out=out, mask=mask, shift_x=shift_x, shift_y=shift_y) + return _apply(_crank8.median, _crank16.median, image, selem, out=out, + mask=mask, shift_x=shift_x, shift_y=shift_y) def minimum(image, selem, out=None, mask=None, shift_x=False, shift_y=False): @@ -342,18 +376,20 @@ def minimum(image, selem, out=None, mask=None, shift_x=False, shift_y=False): Parameters ---------- image : ndarray - Image array (uint8 array or uint16). If image is uint16, the algorithm uses max. 12bit histogram, - an exception will be raised if image has a value > 4095 + Image array (uint8 array or uint16). If image is uint16, the algorithm + uses max. 12bit histogram, an exception will be raised if image has a + value > 4095. selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray If None, a new array will be allocated. mask : ndarray (uint8) - Mask array that defines (>0) area of the image included in the local neighborhood. - If None, the complete image is used (default). - shift_x, shift_y : (int) - Offset added to the structuring element center point. - Shift is bounded to the structuring element sizes (center must be inside the given structuring element). + Mask array that defines (>0) area of the image included in the local + neighborhood. If None, the complete image is used (default). + shift_x, shift_y : int + Offset added to the structuring element center point. Shift is bounded + to the structuring element sizes (center must be inside the given + structuring element). Returns ------- @@ -362,17 +398,18 @@ def minimum(image, selem, out=None, mask=None, shift_x=False, shift_y=False): See also -------- - skimage.morphology.erosion() + skimage.morphology.erosion Note ---- * input image can be 8 bit or 16 bit with a value < 4096 (i.e. 12 bit) - - * the lower algorithm complexity makes the rank.minimum() more efficient for larger images and structuring elements + * the lower algorithm complexity makes the rank.minimum() more efficient + for larger images and structuring elements """ - return _apply(_crank8.minimum, _crank16.minimum, image, selem, out=out, mask=mask, shift_x=shift_x, shift_y=shift_y) + return _apply(_crank8.minimum, _crank16.minimum, image, selem, out=out, + mask=mask, shift_x=shift_x, shift_y=shift_y) def modal(image, selem, out=None, mask=None, shift_x=False, shift_y=False): @@ -381,49 +418,55 @@ def modal(image, selem, out=None, mask=None, shift_x=False, shift_y=False): Parameters ---------- image : ndarray - Image array (uint8 array or uint16). If image is uint16, the algorithm uses max. 12bit histogram, - an exception will be raised if image has a value > 4095 + Image array (uint8 array or uint16). If image is uint16, the algorithm + uses max. 12bit histogram, an exception will be raised if image has a + value > 4095. selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray If None, a new array will be allocated. mask : ndarray (uint8) - Mask array that defines (>0) area of the image included in the local neighborhood. - If None, the complete image is used (default). - shift_x, shift_y : (int) - Offset added to the structuring element center point. - Shift is bounded to the structuring element sizes (center must be inside the given structuring element). + Mask array that defines (>0) area of the image included in the local + neighborhood. If None, the complete image is used (default). + shift_x, shift_y : int + Offset added to the structuring element center point. Shift is bounded + to the structuring element sizes (center must be inside the given + structuring element). Returns ------- out : uint8 array or uint16 array (same as input image) The local modal. - """ - return _apply(_crank8.modal, _crank16.modal, image, selem, out=out, mask=mask, shift_x=shift_x, shift_y=shift_y) + return _apply(_crank8.modal, _crank16.modal, image, selem, out=out, + mask=mask, shift_x=shift_x, shift_y=shift_y) -def morph_contr_enh(image, selem, out=None, mask=None, shift_x=False, shift_y=False): - """Enhance an image replacing each pixel by the local maximum if pixel graylevel is closest to maximimum - than local minimum OR local minimum otherwise. +def morph_contr_enh(image, selem, out=None, mask=None, shift_x=False, + shift_y=False): + """Enhance an image replacing each pixel by the local maximum if pixel + graylevel is closest to maximimum than local minimum OR local minimum + otherwise. Parameters ---------- image : ndarray - Image array (uint8 array or uint16). If image is uint16, the algorithm uses max. 12bit histogram, - an exception will be raised if image has a value > 4095 + Image array (uint8 array or uint16). If image is uint16, the algorithm + uses max. 12bit histogram, an exception will be raised if image has a + value > 4095. selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray If None, a new array will be allocated. mask : ndarray (uint8) - Mask array that defines (>0) area of the image included in the local neighborhood. - If None, the complete image is used (default). - shift_x, shift_y : (int) - Offset added to the structuring element center point. - Shift is bounded to the structuring element sizes (center must be inside the given structuring element). + Mask array that defines (>0) area of the image included in the local + neighborhood. If None, the complete image is used (default). + shift_x, shift_y : int + Offset added to the structuring element center point. Shift is bounded + to the structuring element sizes (center must be inside the given + structuring element). Returns ------- @@ -439,31 +482,34 @@ def morph_contr_enh(image, selem, out=None, mask=None, shift_x=False, shift_y=Fa >>> ima = data.camera() >>> # Local mean >>> avg = morph_contr_enh(ima, disk(20)) + """ - return _apply( - _crank8.morph_contr_enh, _crank16.morph_contr_enh, image, selem, out=out, mask=mask, shift_x=shift_x, - shift_y=shift_y) + return _apply(_crank8.morph_contr_enh, _crank16.morph_contr_enh, image, + selem, out=out, mask=mask, shift_x=shift_x, shift_y=shift_y) def pop(image, selem, out=None, mask=None, shift_x=False, shift_y=False): - """Return the number (population) of pixels actually inside the neighborhood. + """Return the number (population) of pixels actually inside the + neighborhood. Parameters ---------- image : ndarray - Image array (uint8 array or uint16). If image is uint16, the algorithm uses max. 12bit histogram, - an exception will be raised if image has a value > 4095 + Image array (uint8 array or uint16). If image is uint16, the algorithm + uses max. 12bit histogram, an exception will be raised if image has a + value > 4095. selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray If None, a new array will be allocated. mask : ndarray (uint8) - Mask array that defines (>0) area of the image included in the local neighborhood. - If None, the complete image is used (default). - shift_x, shift_y : (int) - Offset added to the structuring element center point. - Shift is bounded to the structuring element sizes (center must be inside the given structuring element). + Mask array that defines (>0) area of the image included in the local + neighborhood. If None, the complete image is used (default). + shift_x, shift_y : int + Offset added to the structuring element center point. Shift is bounded + to the structuring element sizes (center must be inside the given + structuring element). Returns ------- @@ -487,10 +533,10 @@ def pop(image, selem, out=None, mask=None, shift_x=False, shift_y=False): [6, 9, 9, 9, 6], [4, 6, 6, 6, 4]], dtype=uint8) - """ - return _apply(_crank8.pop, _crank16.pop, image, selem, out=out, mask=mask, shift_x=shift_x, shift_y=shift_y) + return _apply(_crank8.pop, _crank16.pop, image, selem, out=out, + mask=mask, shift_x=shift_x, shift_y=shift_y) def threshold(image, selem, out=None, mask=None, shift_x=False, shift_y=False): @@ -499,18 +545,20 @@ def threshold(image, selem, out=None, mask=None, shift_x=False, shift_y=False): Parameters ---------- image : ndarray - Image array (uint8 array or uint16). If image is uint16, the algorithm uses max. 12bit histogram, - an exception will be raised if image has a value > 4095 + Image array (uint8 array or uint16). If image is uint16, the algorithm + uses max. 12bit histogram, an exception will be raised if image has a + value > 4095. selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray If None, a new array will be allocated. mask : ndarray (uint8) - Mask array that defines (>0) area of the image included in the local neighborhood. - If None, the complete image is used (default). - shift_x, shift_y : (int) - Offset added to the structuring element center point. - Shift is bounded to the structuring element sizes (center must be inside the given structuring element). + Mask array that defines (>0) area of the image included in the local + neighborhood. If None, the complete image is used (default). + shift_x, shift_y : int + Offset added to the structuring element center point. Shift is bounded + to the structuring element sizes (center must be inside the given + structuring element). Returns ------- @@ -534,12 +582,10 @@ def threshold(image, selem, out=None, mask=None, shift_x=False, shift_y=False): [0, 1, 1, 1, 0], [0, 0, 0, 0, 0]], dtype=uint8) - """ - return _apply( - _crank8.threshold, _crank16.threshold, image, selem, out=out, mask=mask, shift_x=shift_x, - shift_y=shift_y) + return _apply(_crank8.threshold, _crank16.threshold, image, selem, out=out, + mask=mask, shift_x=shift_x, shift_y=shift_y) def tophat(image, selem, out=None, mask=None, shift_x=False, shift_y=False): @@ -548,18 +594,20 @@ def tophat(image, selem, out=None, mask=None, shift_x=False, shift_y=False): Parameters ---------- image : ndarray - Image array (uint8 array or uint16). If image is uint16, the algorithm uses max. 12bit histogram, - an exception will be raised if image has a value > 4095 + Image array (uint8 array or uint16). If image is uint16, the algorithm + uses max. 12bit histogram, an exception will be raised if image has a + value > 4095. selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray If None, a new array will be allocated. mask : ndarray (uint8) - Mask array that defines (>0) area of the image included in the local neighborhood. - If None, the complete image is used (default). - shift_x, shift_y : (int) - Offset added to the structuring element center point. - Shift is bounded to the structuring element sizes (center must be inside the given structuring element). + Mask array that defines (>0) area of the image included in the local + neighborhood. If None, the complete image is used (default). + shift_x, shift_y : int + Offset added to the structuring element center point. Shift is bounded + to the structuring element sizes (center must be inside the given + structuring element). Returns ------- @@ -568,32 +616,35 @@ def tophat(image, selem, out=None, mask=None, shift_x=False, shift_y=False): """ - return _apply(_crank8.tophat, _crank16.tophat, image, selem, out=out, mask=mask, shift_x=shift_x, shift_y=shift_y) + return _apply(_crank8.tophat, _crank16.tophat, image, selem, out=out, + mask=mask, shift_x=shift_x, shift_y=shift_y) -def noise_filter(image, selem, out=None, mask=None, shift_x=False, shift_y=False): +def noise_filter(image, selem, out=None, mask=None, shift_x=False, + shift_y=False): """Returns the noise feature as described in [Hashimoto12]_ Parameters ---------- image : ndarray - Image array (uint8 array or uint16). If image is uint16, the algorithm uses max. 12bit histogram, - an exception will be raised if image has a value > 4095 + Image array (uint8 array or uint16). If image is uint16, the algorithm + uses max. 12bit histogram, an exception will be raised if image has a + value > 4095. selem : ndarray - The neighborhood expressed as a 2-D array of 1's and 0's. Central element is removed during the filtering. + The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray If None, a new array will be allocated. mask : ndarray (uint8) - Mask array that defines (>0) area of the image included in the local neighborhood. - If None, the complete image is used (default). - shift_x, shift_y : (int) - Offset added to the structuring element center point. - Shift is bounded to the structuring element sizes (center must be inside the given structuring element). + Mask array that defines (>0) area of the image included in the local + neighborhood. If None, the complete image is used (default). + shift_x, shift_y : int + Offset added to the structuring element center point. Shift is bounded + to the structuring element sizes (center must be inside the given + structuring element). - Reference + References ---------- - - .. [Hashimoto12] N. Hashimoto et al. Referenceless image quality evaluation for whole slide imaging. J Pathol Inform 2012;3:9. - + .. [Hashimoto12] N. Hashimoto et al. Referenceless image quality evaluation + for whole slide imaging. J Pathol Inform 2012;3:9. Returns ------- @@ -601,6 +652,7 @@ def noise_filter(image, selem, out=None, mask=None, shift_x=False, shift_y=False The image noise . """ + # ensure that the central pixel in the structuring element is empty centre_r = int(selem.shape[0] / 2) + shift_y centre_c = int(selem.shape[1] / 2) + shift_x @@ -608,41 +660,43 @@ def noise_filter(image, selem, out=None, mask=None, shift_x=False, shift_y=False selem_cpy = selem.copy() selem_cpy[centre_r,centre_c] = 0 - return _apply(_crank8.noise_filter, None, image, selem_cpy, out=out, mask=mask, shift_x=shift_x, shift_y=shift_y) + return _apply(_crank8.noise_filter, None, image, selem_cpy, out=out, + mask=mask, shift_x=shift_x, shift_y=shift_y) def entropy(image, selem, out=None, mask=None, shift_x=False, shift_y=False): - """Returns the entropy [wiki_entropy]_ computed locally. Entropy is computed using base 2 logarithm i.e. - the filter returns the minimum number of bits needed to encode local greylevel distribution. - - References - ---------- - .. [wiki_entropy] http://en.wikipedia.org/wiki/Entropy_(information_theory) + """Returns the entropy [wiki_entropy]_ computed locally. Entropy is computed + using base 2 logarithm i.e. the filter returns the minimum number of + bits needed to encode local greylevel distribution. Parameters ---------- image : ndarray - Image array (uint8 array or uint16). If image is uint16, the algorithm uses max. 12bit histogram, - an exception will be raised if image has a value > 4095 + Image array (uint8 array or uint16). If image is uint16, the algorithm + uses max. 12bit histogram, an exception will be raised if image has a + value > 4095. selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray If None, a new array will be allocated. mask : ndarray (uint8) - Mask array that defines (>0) area of the image included in the local neighborhood. - If None, the complete image is used (default). - shift_x, shift_y : (int) - Offset added to the structuring element center point. - Shift is bounded to the structuring element sizes (center must be inside the given structuring element). + Mask array that defines (>0) area of the image included in the local + neighborhood. If None, the complete image is used (default). + shift_x, shift_y : int + Offset added to the structuring element center point. Shift is bounded + to the structuring element sizes (center must be inside the given + structuring element). Returns ------- out : uint8 array or uint16 array (same as input image) entropy x10 (uint8 images) and entropy x1000 (uint16 images) + References + ---------- + .. [wiki_entropy] http://en.wikipedia.org/wiki/Entropy_(information_theory) Examples -------- - >>> # Local entropy >>> from skimage import data >>> from skimage.filter.rank import entropy @@ -650,46 +704,48 @@ def entropy(image, selem, out=None, mask=None, shift_x=False, shift_y=False): >>> # defining a 8- and a 16-bit test images >>> a8 = data.camera() >>> a16 = data.camera().astype(np.uint16)*4 - >>> ent8 = entropy(a8,disk(5)) # pixel value contain 10x the local entropy - >>> ent16 = entropy(a16,disk(5)) # pixel value contain 1000x the local entropy + >>> # pixel values contain 10x the local entropy + >>> ent8 = entropy(a8,disk(5)) + >>> # pixel values contain 1000x the local entropy + >>> ent16 = entropy(a16,disk(5)) """ - return _apply(_crank8.entropy, _crank16.entropy, image, selem, out=out, mask=mask, shift_x=shift_x, shift_y=shift_y) + return _apply(_crank8.entropy, _crank16.entropy, image, selem, out=out, + mask=mask, shift_x=shift_x, shift_y=shift_y) def otsu(image, selem, out=None, mask=None, shift_x=False, shift_y=False): """Returns the image threshold using a the Otsu [otsu]_ locally . - References - ---------- - - .. [otsu] http://en.wikipedia.org/wiki/Otsu's_method - Parameters ---------- image : ndarray - Image array (uint8 array or uint16). If image is uint16, the algorithm uses max. 12bit histogram, - an exception will be raised if image has a value > 4095 + Image array (uint8 array or uint16). If image is uint16, the algorithm + uses max. 12bit histogram, an exception will be raised if image has a + value > 4095. selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray If None, a new array will be allocated. mask : ndarray (uint8) - Mask array that defines (>0) area of the image included in the local neighborhood. - If None, the complete image is used (default). - shift_x, shift_y : (int) - Offset added to the structuring element center point. - Shift is bounded to the structuring element sizes (center must be inside the given structuring element). + Mask array that defines (>0) area of the image included in the local + neighborhood. If None, the complete image is used (default). + shift_x, shift_y : int + Offset added to the structuring element center point. Shift is bounded + to the structuring element sizes (center must be inside the given + structuring element). Returns ------- out : uint8 array or uint16 array (same as input image) threshold image + References + ---------- + .. [otsu] http://en.wikipedia.org/wiki/Otsu's_method Examples -------- - >>> # Local entropy >>> from skimage import data >>> from skimage.filter.rank import otsu @@ -700,4 +756,5 @@ def otsu(image, selem, out=None, mask=None, shift_x=False, shift_y=False): """ - return _apply(_crank8.otsu, None, image, selem, out=out, mask=mask, shift_x=shift_x, shift_y=shift_y) \ No newline at end of file + return _apply(_crank8.otsu, None, image, selem, out=out, + mask=mask, shift_x=shift_x, shift_y=shift_y) From 28e7b19c93524fad824c0f3747f76aac626b0f81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Sch=C3=B6nberger?= Date: Sat, 10 Nov 2012 08:24:44 +0100 Subject: [PATCH 03/12] Improve code layout of kernel functions --- skimage/filter/rank/_crank16.pyx | 205 ++++++++++-------- skimage/filter/rank/_crank16_bilateral.pyx | 34 +-- skimage/filter/rank/_crank16_percentiles.pyx | 119 ++++++---- skimage/filter/rank/_crank8.pyx | 217 ++++++++++--------- skimage/filter/rank/_crank8_percentiles.pyx | 103 +++++---- 5 files changed, 378 insertions(+), 300 deletions(-) diff --git a/skimage/filter/rank/_crank16.pyx b/skimage/filter/rank/_crank16.pyx index ab5b6015..602a60f4 100644 --- a/skimage/filter/rank/_crank16.pyx +++ b/skimage/filter/rank/_crank16.pyx @@ -6,18 +6,19 @@ import numpy as np cimport numpy as np from libc.math cimport log2 - -# import main loop from skimage.filter.rank._core16 cimport _core16 + # ----------------------------------------------------------------- # kernels uint16 take extra parameter for defining the bitdepth # ----------------------------------------------------------------- -cdef inline np.uint16_t kernel_autolevel( - Py_ssize_t * histo, float pop, np.uint16_t g, - Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, - float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): + +cdef inline np.uint16_t kernel_autolevel(Py_ssize_t * histo, float pop, + np.uint16_t g, Py_ssize_t bitdepth, + Py_ssize_t maxbin, Py_ssize_t midbin, + float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i, imin, imax, delta if pop: @@ -31,27 +32,30 @@ cdef inline np.uint16_t kernel_autolevel( break delta = imax - imin if delta > 0: - return < np.uint16_t > (1. * (maxbin - 1) * (g - imin) / delta) + return (1. * (maxbin - 1) * (g - imin) / delta) else: - return < np.uint16_t > (imax - imin) + return (imax - imin) -cdef inline np.uint16_t kernel_bottomhat( - Py_ssize_t * histo, float pop, np.uint16_t g, - Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, - float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): + +cdef inline np.uint16_t kernel_bottomhat(Py_ssize_t * histo, float pop, + np.uint16_t g, Py_ssize_t bitdepth, + Py_ssize_t maxbin, Py_ssize_t midbin, + float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i for i in range(maxbin): if histo[i]: break - return < np.uint16_t > (g - i) + return (g - i) -cdef inline np.uint16_t kernel_equalize( - Py_ssize_t * histo, float pop, np.uint16_t g, - Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, - float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): +cdef inline np.uint16_t kernel_equalize(Py_ssize_t * histo, float pop, + np.uint16_t g, Py_ssize_t bitdepth, + Py_ssize_t maxbin, Py_ssize_t midbin, + float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i cdef float sum = 0. @@ -61,14 +65,16 @@ cdef inline np.uint16_t kernel_equalize( if i >= g: break - return < np.uint16_t > (((maxbin - 1) * sum) / pop) + return (((maxbin - 1) * sum) / pop) else: - return < np.uint16_t > (0) + return (0) -cdef inline np.uint16_t kernel_gradient( - Py_ssize_t * histo, float pop, np.uint16_t g, - Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, - float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): + +cdef inline np.uint16_t kernel_gradient(Py_ssize_t * histo, float pop, + np.uint16_t g, Py_ssize_t bitdepth, + Py_ssize_t maxbin, Py_ssize_t midbin, + float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i, imin, imax if pop: @@ -80,55 +86,63 @@ cdef inline np.uint16_t kernel_gradient( if histo[i]: imin = i break - return < np.uint16_t > (imax - imin) + return (imax - imin) else: - return < np.uint16_t > (0) + return (0) -cdef inline np.uint16_t kernel_maximum( - Py_ssize_t * histo, float pop, np.uint16_t g, - Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, - float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): + +cdef inline np.uint16_t kernel_maximum(Py_ssize_t * histo, float pop, + np.uint16_t g, Py_ssize_t bitdepth, + Py_ssize_t maxbin, Py_ssize_t midbin, + float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i if pop: for i in range(maxbin - 1, -1, -1): if histo[i]: - return < np.uint16_t > (i) + return (i) - return < np.uint16_t > (0) + return (0) -cdef inline np.uint16_t kernel_mean( - Py_ssize_t * histo, float pop, np.uint16_t g, - Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, - float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): + +cdef inline np.uint16_t kernel_mean(Py_ssize_t * histo, float pop, + np.uint16_t g, Py_ssize_t bitdepth, + Py_ssize_t maxbin, Py_ssize_t midbin, + float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i cdef float mean = 0. if pop: for i in range(maxbin): mean += histo[i] * i - return < np.uint16_t > (mean / pop) + return (mean / pop) else: - return < np.uint16_t > (0) + return (0) -cdef inline np.uint16_t kernel_meansubstraction( - Py_ssize_t * histo, float pop, np.uint16_t g, - Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, - float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): + +cdef inline np.uint16_t kernel_meansubstraction(Py_ssize_t * histo, float pop, + np.uint16_t g, Py_ssize_t bitdepth, + Py_ssize_t maxbin, Py_ssize_t midbin, + float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i cdef float mean = 0. if pop: for i in range(maxbin): mean += histo[i] * i - return < np.uint16_t > ((g - mean / pop) / 2. + (midbin - 1)) + return ((g - mean / pop) / 2. + (midbin - 1)) else: - return < np.uint16_t > (0) + return (0) -cdef inline np.uint16_t kernel_median( - Py_ssize_t * histo, float pop, np.uint16_t g, - Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, - float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): + +cdef inline np.uint16_t kernel_median(Py_ssize_t * histo, float pop, + np.uint16_t g, Py_ssize_t bitdepth, + Py_ssize_t maxbin, Py_ssize_t midbin, + float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i cdef float sum = pop / 2.0 @@ -137,27 +151,31 @@ cdef inline np.uint16_t kernel_median( if histo[i]: sum -= histo[i] if sum < 0: - return < np.uint16_t > (i) + return (i) - return < np.uint16_t > (0) + return (0) -cdef inline np.uint16_t kernel_minimum( - Py_ssize_t * histo, float pop, np.uint16_t g, - Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, - float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): + +cdef inline np.uint16_t kernel_minimum(Py_ssize_t * histo, float pop, + np.uint16_t g, Py_ssize_t bitdepth, + Py_ssize_t maxbin, Py_ssize_t midbin, + float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i if pop: for i in range(maxbin): if histo[i]: - return < np.uint16_t > (i) + return (i) - return < np.uint16_t > (0) + return (0) -cdef inline np.uint16_t kernel_modal( - Py_ssize_t * histo, float pop, np.uint16_t g, - Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, - float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): + +cdef inline np.uint16_t kernel_modal(Py_ssize_t * histo, float pop, + np.uint16_t g, Py_ssize_t bitdepth, + Py_ssize_t maxbin, Py_ssize_t midbin, + float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t hmax = 0, imax = 0 if pop: @@ -165,14 +183,16 @@ cdef inline np.uint16_t kernel_modal( if histo[i] > hmax: hmax = histo[i] imax = i - return < np.uint16_t > (imax) + return (imax) - return < np.uint16_t > (0) + return (0) -cdef inline np.uint16_t kernel_morph_contr_enh( - Py_ssize_t * histo, float pop, np.uint16_t g, - Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, - float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): + +cdef inline np.uint16_t kernel_morph_contr_enh(Py_ssize_t * histo, float pop, + np.uint16_t g, Py_ssize_t bitdepth, + Py_ssize_t maxbin, Py_ssize_t midbin, + float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i, imin, imax if pop: @@ -185,49 +205,56 @@ cdef inline np.uint16_t kernel_morph_contr_enh( imin = i break if imax - g < g - imin: - return < np.uint16_t > (imax) + return (imax) else: - return < np.uint16_t > (imin) + return (imin) else: - return < np.uint16_t > (0) + return (0) -cdef inline np.uint16_t kernel_pop( - Py_ssize_t * histo, float pop, np.uint16_t g, - Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, - float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): - return < np.uint16_t > (pop) -cdef inline np.uint16_t kernel_threshold( - Py_ssize_t * histo, float pop, np.uint16_t g, - Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, - float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): +cdef inline np.uint16_t kernel_pop(Py_ssize_t * histo, float pop, + np.uint16_t g, Py_ssize_t bitdepth, + Py_ssize_t maxbin, Py_ssize_t midbin, + float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): + return (pop) + + +cdef inline np.uint16_t kernel_threshold(Py_ssize_t * histo, float pop, + np.uint16_t g, Py_ssize_t bitdepth, + Py_ssize_t maxbin, Py_ssize_t midbin, + float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i cdef float mean = 0. if pop: for i in range(maxbin): mean += histo[i] * i - return < np.uint16_t > (g > (mean / pop)) + return (g > (mean / pop)) else: - return < np.uint16_t > (0) + return (0) -cdef inline np.uint16_t kernel_tophat( - Py_ssize_t * histo, float pop, np.uint16_t g, - Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, - float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): + +cdef inline np.uint16_t kernel_tophat(Py_ssize_t * histo, float pop, + np.uint16_t g, Py_ssize_t bitdepth, + Py_ssize_t maxbin, Py_ssize_t midbin, + float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i for i in range(maxbin - 1, -1, -1): if histo[i]: break - return < np.uint16_t > (i - g) + return (i - g) -cdef inline np.uint16_t kernel_entropy( - Py_ssize_t * histo, float pop, np.uint16_t g, - Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, - float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): +cdef inline np.uint16_t kernel_entropy(Py_ssize_t * histo, float pop, + np.uint16_t g, Py_ssize_t bitdepth, + Py_ssize_t maxbin, Py_ssize_t midbin, + float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i cdef float e,p @@ -238,7 +265,7 @@ cdef inline np.uint16_t kernel_entropy( if p>0: e -= p*log2(p) - return < np.uint16_t > e*1000 + return e*1000 # ----------------------------------------------------------------- diff --git a/skimage/filter/rank/_crank16_bilateral.pyx b/skimage/filter/rank/_crank16_bilateral.pyx index cf68115e..1fb81a2d 100644 --- a/skimage/filter/rank/_crank16_bilateral.pyx +++ b/skimage/filter/rank/_crank16_bilateral.pyx @@ -5,18 +5,19 @@ import numpy as np cimport numpy as np - -# import main loop from skimage.filter.rank._core16 cimport _core16 + # ----------------------------------------------------------------- # kernels uint16 take extra parameter for defining the bitdepth # ----------------------------------------------------------------- -cdef inline np.uint16_t kernel_mean( - Py_ssize_t * histo, float pop, np.uint16_t g, Py_ssize_t bitdepth, - Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): +cdef inline np.uint16_t kernel_mean(Py_ssize_t * histo, float pop, + np.uint16_t g, Py_ssize_t bitdepth, + Py_ssize_t maxbin, Py_ssize_t midbin, + float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef int i, bilat_pop = 0 cdef float mean = 0. @@ -27,16 +28,18 @@ cdef inline np.uint16_t kernel_mean( bilat_pop += histo[i] mean += histo[i] * i if bilat_pop: - return < np.uint16_t > (mean / bilat_pop) + return (mean / bilat_pop) else: - return < np.uint16_t > (0) + return (0) else: - return < np.uint16_t > (0) + return (0) -cdef inline np.uint16_t kernel_pop( - Py_ssize_t * histo, float pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, - Py_ssize_t midbin, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): +cdef inline np.uint16_t kernel_pop(Py_ssize_t * histo, float pop, + np.uint16_t g, Py_ssize_t bitdepth, + Py_ssize_t maxbin, Py_ssize_t midbin, + float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef int i, bilat_pop = 0 @@ -44,14 +47,16 @@ cdef inline np.uint16_t kernel_pop( for i in range(maxbin): if (g > (i - s0)) and (g < (i + s1)): bilat_pop += histo[i] - return < np.uint16_t > (bilat_pop) + return (bilat_pop) else: - return < np.uint16_t > (0) + return (0) # ----------------------------------------------------------------- # python wrappers # ----------------------------------------------------------------- + + def mean(np.ndarray[np.uint16_t, ndim=2] image, np.ndarray[np.uint8_t, ndim=2] selem, np.ndarray[np.uint8_t, ndim=2] mask=None, @@ -68,7 +73,8 @@ def pop(np.ndarray[np.uint16_t, ndim=2] image, np.ndarray[np.uint8_t, ndim=2] mask=None, np.ndarray[np.uint16_t, ndim=2] out=None, char shift_x=0, char shift_y=0, int bitdepth=8, int s0=1, int s1=1): - """returns the number of actual pixels of the structuring element inside the mask + """returns the number of actual pixels of the structuring element inside + the mask """ _core16(kernel_pop, image, selem, mask, out, shift_x, shift_y, bitdepth, .0, .0, s0, s1) diff --git a/skimage/filter/rank/_crank16_percentiles.pyx b/skimage/filter/rank/_crank16_percentiles.pyx index 3b50c86c..4c2525be 100644 --- a/skimage/filter/rank/_crank16_percentiles.pyx +++ b/skimage/filter/rank/_crank16_percentiles.pyx @@ -5,17 +5,19 @@ import numpy as np cimport numpy as np - -# import main loop from skimage.filter.rank._core16 cimport _core16, int_min, int_max + # ----------------------------------------------------------------- # kernels uint16 (SOFT version using percentiles) # ----------------------------------------------------------------- -cdef inline np.uint16_t kernel_autolevel( - Py_ssize_t * histo, float pop, np.uint16_t g, Py_ssize_t bitdepth, - Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): + +cdef inline np.uint16_t kernel_autolevel(Py_ssize_t * histo, float pop, + np.uint16_t g, Py_ssize_t bitdepth, + Py_ssize_t maxbin, Py_ssize_t midbin, + float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef int i, imin, imax, sum, delta @@ -36,16 +38,19 @@ cdef inline np.uint16_t kernel_autolevel( delta = imax - imin if delta > 0: - return < np.uint16_t > (1.0 * (maxbin - 1) * (int_min(int_max(imin, g), imax) - imin) / delta) + return (1.0 * (maxbin - 1) \ + * (int_min(int_max(imin, g), imax) - imin) / delta) else: - return < np.uint16_t > (imax - imin) + return (imax - imin) else: - return < np.uint16_t > (0) + return (0) -cdef inline np.uint16_t kernel_gradient( - Py_ssize_t * histo, float pop, np.uint16_t g, Py_ssize_t bitdepth, - Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): +cdef inline np.uint16_t kernel_gradient(Py_ssize_t * histo, float pop, + np.uint16_t g, Py_ssize_t bitdepth, + Py_ssize_t maxbin, Py_ssize_t midbin, + float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef int i, imin, imax, sum, delta @@ -64,14 +69,16 @@ cdef inline np.uint16_t kernel_gradient( imax = i break - return < np.uint16_t > (imax - imin) + return (imax - imin) else: - return < np.uint16_t > (0) + return (0) -cdef inline np.uint16_t kernel_mean( - Py_ssize_t * histo, float pop, np.uint16_t g, Py_ssize_t bitdepth, - Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): +cdef inline np.uint16_t kernel_mean(Py_ssize_t * histo, float pop, + np.uint16_t g, Py_ssize_t bitdepth, + Py_ssize_t maxbin, Py_ssize_t midbin, + float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef int i, sum, mean, n @@ -86,15 +93,18 @@ cdef inline np.uint16_t kernel_mean( mean += histo[i] * i if n > 0: - return < np.uint16_t > (1.0 * mean / n) + return (1.0 * mean / n) else: - return < np.uint16_t > (0) + return (0) else: - return < np.uint16_t > (0) + return (0) -cdef inline np.uint16_t kernel_mean_substraction( - Py_ssize_t * histo, float pop, np.uint16_t g, Py_ssize_t bitdepth, - Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): + +cdef inline np.uint16_t kernel_mean_substraction(Py_ssize_t * histo, float pop, + np.uint16_t g, Py_ssize_t bitdepth, + Py_ssize_t maxbin, Py_ssize_t midbin, + float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef int i, sum, mean, n @@ -108,15 +118,18 @@ cdef inline np.uint16_t kernel_mean_substraction( n += histo[i] mean += histo[i] * i if n > 0: - return < np.uint16_t > ((g - (mean / n)) * .5 + midbin) + return ((g - (mean / n)) * .5 + midbin) else: - return < np.uint16_t > (0) + return (0) else: - return < np.uint16_t > (0) + return (0) -cdef inline np.uint16_t kernel_morph_contr_enh( - Py_ssize_t * histo, float pop, np.uint16_t g, Py_ssize_t bitdepth, - Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): + +cdef inline np.uint16_t kernel_morph_contr_enh(Py_ssize_t * histo, float pop, + np.uint16_t g, Py_ssize_t bitdepth, + Py_ssize_t maxbin, Py_ssize_t midbin, + float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef int i, imin, imax, sum, delta @@ -135,19 +148,22 @@ cdef inline np.uint16_t kernel_morph_contr_enh( imax = i break if g > imax: - return < np.uint16_t > imax + return imax if g < imin: - return < np.uint16_t > imin + return imin if imax - g < g - imin: - return < np.uint16_t > imax + return imax else: - return < np.uint16_t > imin + return imin else: - return < np.uint16_t > (0) + return (0) -cdef inline np.uint16_t kernel_percentile( - Py_ssize_t * histo, float pop, np.uint16_t g, Py_ssize_t bitdepth, - Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): + +cdef inline np.uint16_t kernel_percentile(Py_ssize_t * histo, float pop, + np.uint16_t g, Py_ssize_t bitdepth, + Py_ssize_t maxbin, Py_ssize_t midbin, + float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef int i cdef float sum = 0. @@ -158,13 +174,16 @@ cdef inline np.uint16_t kernel_percentile( if sum >= p0 * pop: break - return < np.uint16_t > (i) + return (i) else: - return < np.uint16_t > (0) + return (0) -cdef inline np.uint16_t kernel_pop( - Py_ssize_t * histo, float pop, np.uint16_t g, Py_ssize_t bitdepth, - Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): + +cdef inline np.uint16_t kernel_pop(Py_ssize_t * histo, float pop, + np.uint16_t g, Py_ssize_t bitdepth, + Py_ssize_t maxbin, Py_ssize_t midbin, + float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef int i, sum, n @@ -175,13 +194,16 @@ cdef inline np.uint16_t kernel_pop( sum += histo[i] if (sum >= p0 * pop) and (sum <= p1 * pop): n += histo[i] - return < np.uint16_t > (n) + return (n) else: - return < np.uint16_t > (0) + return (0) -cdef inline np.uint16_t kernel_threshold( - Py_ssize_t * histo, float pop, np.uint16_t g, Py_ssize_t bitdepth, - Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): + +cdef inline np.uint16_t kernel_threshold(Py_ssize_t * histo, float pop, + np.uint16_t g, Py_ssize_t bitdepth, + Py_ssize_t maxbin, Py_ssize_t midbin, + float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef int i cdef float sum = 0. @@ -192,9 +214,10 @@ cdef inline np.uint16_t kernel_threshold( if sum >= p0 * pop: break - return < np.uint16_t > ((maxbin - 1) * (g >= i)) + return ((maxbin - 1) * (g >= i)) else: - return < np.uint16_t > (0) + return (0) + # ----------------------------------------------------------------- # python wrappers diff --git a/skimage/filter/rank/_crank8.pyx b/skimage/filter/rank/_crank8.pyx index 5b2cba01..7398b26f 100644 --- a/skimage/filter/rank/_crank8.pyx +++ b/skimage/filter/rank/_crank8.pyx @@ -5,19 +5,18 @@ import numpy as np cimport numpy as np - from libc.math cimport log2 - -# import main loop from skimage.filter.rank._core8 cimport _core8 + # ----------------------------------------------------------------- # kernels uint8 # ----------------------------------------------------------------- -cdef inline np.uint8_t kernel_autolevel( - Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, - Py_ssize_t s0, Py_ssize_t s1): + +cdef inline np.uint8_t kernel_autolevel(Py_ssize_t * histo, float pop, + np.uint8_t g, float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i, imin, imax, delta @@ -32,15 +31,16 @@ cdef inline np.uint8_t kernel_autolevel( break delta = imax - imin if delta > 0: - return < np.uint8_t > (255. * (g - imin) / delta) + return (255. * (g - imin) / delta) else: - return < np.uint8_t > (imax - imin) + return (imax - imin) else: - return < np.uint8_t > (0) + return (0) -cdef inline np.uint8_t kernel_bottomhat( - Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, - Py_ssize_t s0, Py_ssize_t s1): + +cdef inline np.uint8_t kernel_bottomhat(Py_ssize_t * histo, float pop, + np.uint8_t g, float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i @@ -48,12 +48,12 @@ cdef inline np.uint8_t kernel_bottomhat( if histo[i]: break - return < np.uint8_t > (g - i) + return (g - i) -cdef inline np.uint8_t kernel_equalize( - Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, - Py_ssize_t s0, Py_ssize_t s1): +cdef inline np.uint8_t kernel_equalize(Py_ssize_t * histo, float pop, + np.uint8_t g, float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i cdef float sum = 0. @@ -64,13 +64,14 @@ cdef inline np.uint8_t kernel_equalize( if i >= g: break - return < np.uint8_t > ((255 * sum) / pop) + return ((255 * sum) / pop) else: - return < np.uint8_t > (0) + return (0) -cdef inline np.uint8_t kernel_gradient( - Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, - Py_ssize_t s1): + +cdef inline np.uint8_t kernel_gradient(Py_ssize_t * histo, float pop, + np.uint8_t g, float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i, imin, imax @@ -83,26 +84,28 @@ cdef inline np.uint8_t kernel_gradient( if histo[i]: imin = i break - return < np.uint8_t > (imax - imin) + return (imax - imin) else: - return < np.uint8_t > (0) + return (0) -cdef inline np.uint8_t kernel_maximum( - Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, - Py_ssize_t s1): + +cdef inline np.uint8_t kernel_maximum(Py_ssize_t * histo, float pop, + np.uint8_t g, float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i if pop: for i in range(255, -1, -1): if histo[i]: - return < np.uint8_t > (i) + return (i) - return < np.uint8_t > (0) + return (0) -cdef inline np.uint8_t kernel_mean( - Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, - Py_ssize_t s1): + +cdef inline np.uint8_t kernel_mean(Py_ssize_t * histo, float pop, + np.uint8_t g, float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i cdef float mean = 0. @@ -110,13 +113,14 @@ cdef inline np.uint8_t kernel_mean( if pop: for i in range(256): mean += histo[i] * i - return < np.uint8_t > (mean / pop) + return (mean / pop) else: - return < np.uint8_t > (0) + return (0) -cdef inline np.uint8_t kernel_meansubstraction( - Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, - Py_ssize_t s0, Py_ssize_t s1): + +cdef inline np.uint8_t kernel_meansubstraction(Py_ssize_t * histo, float pop, + np.uint8_t g, float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i cdef float mean = 0. @@ -124,13 +128,14 @@ cdef inline np.uint8_t kernel_meansubstraction( if pop: for i in range(256): mean += histo[i] * i - return < np.uint8_t > ((g - mean / pop) / 2. + 127) + return ((g - mean / pop) / 2. + 127) else: - return < np.uint8_t > (0) + return (0) -cdef inline np.uint8_t kernel_median( - Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, - Py_ssize_t s1): + +cdef inline np.uint8_t kernel_median(Py_ssize_t * histo, float pop, + np.uint8_t g, float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i cdef float sum = pop / 2.0 @@ -140,25 +145,28 @@ cdef inline np.uint8_t kernel_median( if histo[i]: sum -= histo[i] if sum < 0: - return < np.uint8_t > (i) + return (i) - return < np.uint8_t > (0) + return (0) -cdef inline np.uint8_t kernel_minimum( - Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, - Py_ssize_t s1): + +cdef inline np.uint8_t kernel_minimum(Py_ssize_t * histo, float pop, + np.uint8_t g, float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i if pop: for i in range(256): if histo[i]: - return < np.uint8_t > (i) + return (i) - return < np.uint8_t > (0) + return (0) -cdef inline np.uint8_t kernel_modal( - Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): + +cdef inline np.uint8_t kernel_modal(Py_ssize_t * histo, float pop, + np.uint8_t g, float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t hmax = 0, imax = 0 @@ -167,13 +175,14 @@ cdef inline np.uint8_t kernel_modal( if histo[i] > hmax: hmax = histo[i] imax = i - return < np.uint8_t > (imax) + return (imax) - return < np.uint8_t > (0) + return (0) -cdef inline np.uint8_t kernel_morph_contr_enh( - Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, - Py_ssize_t s0, Py_ssize_t s1): + +cdef inline np.uint8_t kernel_morph_contr_enh(Py_ssize_t * histo, float pop, + np.uint8_t g, float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i, imin, imax @@ -187,21 +196,23 @@ cdef inline np.uint8_t kernel_morph_contr_enh( imin = i break if imax - g < g - imin: - return < np.uint8_t > (imax) + return (imax) else: - return < np.uint8_t > (imin) + return (imin) else: - return < np.uint8_t > (0) + return (0) -cdef inline np.uint8_t kernel_pop( - Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, - Py_ssize_t s1): - return < np.uint8_t > (pop) +cdef inline np.uint8_t kernel_pop(Py_ssize_t * histo, float pop, + np.uint8_t g, float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): -cdef inline np.uint8_t kernel_threshold( - Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, - Py_ssize_t s1): + return (pop) + + +cdef inline np.uint8_t kernel_threshold(Py_ssize_t * histo, float pop, + np.uint8_t g, float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i cdef float mean = 0. @@ -209,13 +220,14 @@ cdef inline np.uint8_t kernel_threshold( if pop: for i in range(256): mean += histo[i] * i - return < np.uint8_t > (g > (mean / pop)) + return (g > (mean / pop)) else: - return < np.uint8_t > (0) + return (0) -cdef inline np.uint8_t kernel_tophat( - Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, - Py_ssize_t s1): + +cdef inline np.uint8_t kernel_tophat(Py_ssize_t * histo, float pop, + np.uint8_t g, float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i @@ -223,64 +235,64 @@ cdef inline np.uint8_t kernel_tophat( if histo[i]: break - return < np.uint8_t > (i - g) + return (i - g) -cdef inline np.uint8_t kernel_noise_filter( - Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, - Py_ssize_t s1): + +cdef inline np.uint8_t kernel_noise_filter(Py_ssize_t * histo, float pop, + np.uint8_t g, 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 < np.uint8_t > 0 + if histo[g] > 0: + return 0 for i in range(g, -1, -1): if histo[i]: break - min_i = g-i + min_i = g - i for i in range(g, 256): if histo[i]: break - if i-g < min_i: - return < np.uint8_t > (i-g) + if i - g < min_i: + return (i - g) else: - return < np.uint8_t > min_i + return min_i -cdef inline np.uint8_t kernel_entropy( - Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, - Py_ssize_t s1): +cdef inline np.uint8_t kernel_entropy(Py_ssize_t * histo, float pop, + np.uint8_t g, float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i cdef float e,p e = 0. for i in range(256): - p = histo[i]/pop - if p>0: - e -= p*log2(p) + p = histo[i] / pop + if p > 0: + e -= p * log2(p) - return < np.uint8_t > e*10 + return e*10 -cdef inline np.uint8_t kernel_otsu( - Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, - Py_ssize_t s1): +cdef inline np.uint8_t kernel_otsu(Py_ssize_t * histo, float pop, np.uint8_t g, + 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 cdef float mu = 0. # compute local mean - if pop: for i in range(256): mu += histo[i] * i mu = (mu / pop) else: - return < np.uint8_t > (0) + return (0) # maximizing the between class variance max_i = 0 @@ -289,21 +301,24 @@ cdef inline np.uint8_t kernel_otsu( max_sigma_b = 0. for i in range(1,256): - P = histo[i]/pop + P = histo[i] / pop new_q1 = q1 + P - if new_q1>0: - mu1 = (q1*mu1 + i*P)/new_q1 - mu2 = (mu-new_q1*mu1)/(1.-new_q1) - sigma_b = new_q1*(1.-new_q1)*(mu1-mu2)**2 - if sigma_b>max_sigma_b: + if new_q1 > 0: + mu1 = (q1 * mu1 + i * P) / new_q1 + mu2 = (mu - new_q1*mu1) / (1. - new_q1) + sigma_b = new_q1 * (1. - new_q1) * (mu1 - mu2)**2 + if sigma_b > max_sigma_b: max_sigma_b = sigma_b max_i = i q1 = new_q1 - if g>max_i: - return < np.uint8_t > 255 + if g > max_i: + return 255 else: - return < np.uint8_t > 0 + return 0 + + + # ----------------------------------------------------------------- # python wrappers # used only internally diff --git a/skimage/filter/rank/_crank8_percentiles.pyx b/skimage/filter/rank/_crank8_percentiles.pyx index 636295fd..777aec64 100644 --- a/skimage/filter/rank/_crank8_percentiles.pyx +++ b/skimage/filter/rank/_crank8_percentiles.pyx @@ -5,17 +5,17 @@ import numpy as np cimport numpy as np - -# import main loop from skimage.filter.rank._core8 cimport _core8, uint8_max, uint8_min + # ----------------------------------------------------------------- # kernels uint8 (SOFT version using percentiles) # ----------------------------------------------------------------- -cdef inline np.uint8_t kernel_autolevel( - Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, - Py_ssize_t s1): + +cdef inline np.uint8_t kernel_autolevel(Py_ssize_t * histo, float pop, + np.uint8_t g, float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef int i, imin, imax, sum, delta if pop: @@ -37,16 +37,17 @@ cdef inline np.uint8_t kernel_autolevel( break delta = imax - imin if delta > 0: - return < np.uint8_t > (255 * (uint8_min(uint8_max(imin, g), imax) - imin) / delta) + return (255 \ + * (uint8_min(uint8_max(imin, g), imax) - imin) / delta) else: - return < np.uint8_t > (imax - imin) + return (imax - imin) else: - return < np.uint8_t > (128) + return (128) -cdef inline np.uint8_t kernel_gradient( - Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, - Py_ssize_t s1): +cdef inline np.uint8_t kernel_gradient(Py_ssize_t * histo, float pop, + np.uint8_t g, float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef int i, imin, imax, sum, delta if pop: @@ -64,14 +65,14 @@ cdef inline np.uint8_t kernel_gradient( imax = i break - return < np.uint8_t > (imax - imin) + return (imax - imin) else: - return < np.uint8_t > (0) + return (0) -cdef inline np.uint8_t kernel_mean( - Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, - Py_ssize_t s1): +cdef inline np.uint8_t kernel_mean(Py_ssize_t * histo, float pop, + np.uint8_t g, float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef int i, sum, mean, n if pop: @@ -84,15 +85,16 @@ cdef inline np.uint8_t kernel_mean( n += histo[i] mean += histo[i] * i if n > 0: - return < np.uint8_t > (1.0 * mean / n) + return (1.0 * mean / n) else: - return < np.uint8_t > (0) + return (0) else: - return < np.uint8_t > (0) + return (0) -cdef inline np.uint8_t kernel_mean_substraction( - Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, - Py_ssize_t s0, Py_ssize_t s1): + +cdef inline np.uint8_t kernel_mean_substraction(Py_ssize_t * histo, float pop, + np.uint8_t g, float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef int i, sum, mean, n if pop: @@ -105,15 +107,16 @@ cdef inline np.uint8_t kernel_mean_substraction( n += histo[i] mean += histo[i] * i if n > 0: - return < np.uint8_t > ((g - (mean / n)) * .5 + 127) + return ((g - (mean / n)) * .5 + 127) else: - return < np.uint8_t > (0) + return (0) else: - return < np.uint8_t > (0) + return (0) -cdef inline np.uint8_t kernel_morph_contr_enh( - Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, - Py_ssize_t s0, Py_ssize_t s1): + +cdef inline np.uint8_t kernel_morph_contr_enh(Py_ssize_t * histo, float pop, + np.uint8_t g, float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef int i, imin, imax, sum, delta if pop: @@ -131,19 +134,20 @@ cdef inline np.uint8_t kernel_morph_contr_enh( imax = i break if g > imax: - return < np.uint8_t > imax + return imax if g < imin: - return < np.uint8_t > imin + return imin if imax - g < g - imin: - return < np.uint8_t > imax + return imax else: - return < np.uint8_t > imin + return imin else: - return < np.uint8_t > (0) + return (0) -cdef inline np.uint8_t kernel_percentile( - Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, - Py_ssize_t s0, Py_ssize_t s1): + +cdef inline np.uint8_t kernel_percentile(Py_ssize_t * histo, float pop, + np.uint8_t g, float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef int i cdef float sum = 0. @@ -153,13 +157,14 @@ cdef inline np.uint8_t kernel_percentile( if sum >= p0 * pop: break - return < np.uint8_t > (i) + return (i) else: - return < np.uint8_t > (0) + return (0) -cdef inline np.uint8_t kernel_pop( - Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, - Py_ssize_t s0, Py_ssize_t s1): + +cdef inline np.uint8_t kernel_pop(Py_ssize_t * histo, float pop, + np.uint8_t g, float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef int i, sum, n if pop: @@ -169,13 +174,14 @@ cdef inline np.uint8_t kernel_pop( sum += histo[i] if (sum >= p0 * pop) and (sum <= p1 * pop): n += histo[i] - return < np.uint8_t > (n) + return (n) else: - return < np.uint8_t > (0) + return (0) -cdef inline np.uint8_t kernel_threshold( - Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, - Py_ssize_t s1): + +cdef inline np.uint8_t kernel_threshold(Py_ssize_t * histo, float pop, + np.uint8_t g, float p0, float p1, + Py_ssize_t s0, Py_ssize_t s1): cdef int i cdef float sum = 0. @@ -185,9 +191,10 @@ cdef inline np.uint8_t kernel_threshold( if sum >= p0 * pop: break - return < np.uint8_t > (255 * (g >= i)) + return (255 * (g >= i)) else: - return < np.uint8_t > (0) + return (0) + # ----------------------------------------------------------------- # python wrappers From 045eb88e9f030aabbdadff2fe7fdc3071bfda677 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Sch=C3=B6nberger?= Date: Sat, 10 Nov 2012 08:31:20 +0100 Subject: [PATCH 04/12] Change type of pop variable from float to Py_ssize_t --- skimage/filter/rank/_core16.pxd | 2 +- skimage/filter/rank/_core16.pyx | 12 +++---- skimage/filter/rank/_core8.pxd | 2 +- skimage/filter/rank/_core8.pyx | 12 +++---- skimage/filter/rank/_crank16.pyx | 30 ++++++++--------- skimage/filter/rank/_crank16_bilateral.pyx | 4 +-- skimage/filter/rank/_crank16_percentiles.pyx | 16 ++++----- skimage/filter/rank/_crank8.pyx | 34 ++++++++++---------- skimage/filter/rank/_crank8_percentiles.pyx | 16 ++++----- 9 files changed, 64 insertions(+), 64 deletions(-) diff --git a/skimage/filter/rank/_core16.pxd b/skimage/filter/rank/_core16.pxd index b236d982..0ff5d518 100644 --- a/skimage/filter/rank/_core16.pxd +++ b/skimage/filter/rank/_core16.pxd @@ -6,7 +6,7 @@ cdef int int_min(int a, int b) # 16 bit core kernel receives extra information about data bitdepth -cdef void _core16(np.uint16_t kernel(Py_ssize_t *, float, np.uint16_t, +cdef void _core16(np.uint16_t kernel(Py_ssize_t *, Py_ssize_t, np.uint16_t, Py_ssize_t, Py_ssize_t, Py_ssize_t, float, float, Py_ssize_t, Py_ssize_t), np.ndarray[np.uint16_t, ndim=2] image, diff --git a/skimage/filter/rank/_core16.pyx b/skimage/filter/rank/_core16.pyx index 671a92fc..30d0a5f2 100644 --- a/skimage/filter/rank/_core16.pyx +++ b/skimage/filter/rank/_core16.pyx @@ -17,19 +17,19 @@ cdef inline int int_min(int a, int b): return a if a <= b else b -cdef inline void histogram_increment(Py_ssize_t * histo, float * pop, +cdef inline void histogram_increment(Py_ssize_t * histo, Py_ssize_t * pop, np.uint16_t value): histo[value] += 1 - pop[0] += 1. + pop[0] += 1 -cdef inline void histogram_decrement(Py_ssize_t * histo, float * pop, +cdef inline void histogram_decrement(Py_ssize_t * histo, Py_ssize_t * pop, np.uint16_t value): histo[value] -= 1 - pop[0] -= 1. + pop[0] -= 1 -cdef void _core16(np.uint16_t kernel(Py_ssize_t *, float, np.uint16_t, +cdef void _core16(np.uint16_t kernel(Py_ssize_t *, Py_ssize_t, np.uint16_t, Py_ssize_t, Py_ssize_t, Py_ssize_t, float, float, Py_ssize_t, Py_ssize_t), np.ndarray[np.uint16_t, ndim=2] image, @@ -74,7 +74,7 @@ cdef void _core16(np.uint16_t kernel(Py_ssize_t *, float, np.uint16_t, # define local variable types cdef Py_ssize_t r, c, rr, cc, s, value, local_max, i, even_row # number of pixels actually inside the neighborhood (float) - cdef float pop + cdef Py_ssize_t pop # allocate memory with malloc cdef Py_ssize_t max_se = srows * scols diff --git a/skimage/filter/rank/_core8.pxd b/skimage/filter/rank/_core8.pxd index d724c417..6a6bdafa 100644 --- a/skimage/filter/rank/_core8.pxd +++ b/skimage/filter/rank/_core8.pxd @@ -12,7 +12,7 @@ cdef np.uint8_t is_in_mask(Py_ssize_t rows, Py_ssize_t cols, # 8 bit core kernel receives extra information about data inferior and superior # percentiles -cdef void _core8(np.uint8_t kernel(Py_ssize_t *, float, np.uint8_t, float, +cdef void _core8(np.uint8_t kernel(Py_ssize_t *, Py_ssize_t, np.uint8_t, float, float, Py_ssize_t, Py_ssize_t), np.ndarray[np.uint8_t, ndim=2] image, np.ndarray[np.uint8_t, ndim=2] selem, diff --git a/skimage/filter/rank/_core8.pyx b/skimage/filter/rank/_core8.pyx index 17e5f64e..fc1b64b6 100644 --- a/skimage/filter/rank/_core8.pyx +++ b/skimage/filter/rank/_core8.pyx @@ -16,16 +16,16 @@ cdef inline np.uint8_t uint8_min(np.uint8_t a, np.uint8_t b): return a if a <= b else b -cdef inline void histogram_increment(Py_ssize_t * histo, float * pop, +cdef inline void histogram_increment(Py_ssize_t * histo, Py_ssize_t * pop, np.uint8_t value): histo[value] += 1 - pop[0] += 1. + pop[0] += 1 -cdef inline void histogram_decrement(Py_ssize_t * histo, float * pop, +cdef inline void histogram_decrement(Py_ssize_t * histo, Py_ssize_t * pop, np.uint8_t value): histo[value] -= 1 - pop[0] -= 1. + pop[0] -= 1 cdef inline np.uint8_t is_in_mask(Py_ssize_t rows, Py_ssize_t cols, @@ -41,7 +41,7 @@ cdef inline np.uint8_t is_in_mask(Py_ssize_t rows, Py_ssize_t cols, return 0 -cdef void _core8(np.uint8_t kernel(Py_ssize_t *, float, np.uint8_t, float, +cdef void _core8(np.uint8_t kernel(Py_ssize_t *, Py_ssize_t, np.uint8_t, float, float, Py_ssize_t, Py_ssize_t), np.ndarray[np.uint8_t, ndim=2] image, np.ndarray[np.uint8_t, ndim=2] selem, @@ -77,7 +77,7 @@ cdef void _core8(np.uint8_t kernel(Py_ssize_t *, float, np.uint8_t, float, cdef Py_ssize_t r, c, rr, cc, s, value, local_max, i, even_row # number of pixels actually inside the neighborhood (float) - cdef float pop + cdef Py_ssize_t pop # allocate memory with malloc cdef Py_ssize_t max_se = srows * scols diff --git a/skimage/filter/rank/_crank16.pyx b/skimage/filter/rank/_crank16.pyx index 602a60f4..bb3f7c7d 100644 --- a/skimage/filter/rank/_crank16.pyx +++ b/skimage/filter/rank/_crank16.pyx @@ -14,7 +14,7 @@ from skimage.filter.rank._core16 cimport _core16 # ----------------------------------------------------------------- -cdef inline np.uint16_t kernel_autolevel(Py_ssize_t * histo, float pop, +cdef inline np.uint16_t kernel_autolevel(Py_ssize_t * histo, Py_ssize_t pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, @@ -37,7 +37,7 @@ cdef inline np.uint16_t kernel_autolevel(Py_ssize_t * histo, float pop, return (imax - imin) -cdef inline np.uint16_t kernel_bottomhat(Py_ssize_t * histo, float pop, +cdef inline np.uint16_t kernel_bottomhat(Py_ssize_t * histo, Py_ssize_t pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, @@ -51,7 +51,7 @@ cdef inline np.uint16_t kernel_bottomhat(Py_ssize_t * histo, float pop, return (g - i) -cdef inline np.uint16_t kernel_equalize(Py_ssize_t * histo, float pop, +cdef inline np.uint16_t kernel_equalize(Py_ssize_t * histo, Py_ssize_t pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, @@ -70,7 +70,7 @@ cdef inline np.uint16_t kernel_equalize(Py_ssize_t * histo, float pop, return (0) -cdef inline np.uint16_t kernel_gradient(Py_ssize_t * histo, float pop, +cdef inline np.uint16_t kernel_gradient(Py_ssize_t * histo, Py_ssize_t pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, @@ -91,7 +91,7 @@ cdef inline np.uint16_t kernel_gradient(Py_ssize_t * histo, float pop, return (0) -cdef inline np.uint16_t kernel_maximum(Py_ssize_t * histo, float pop, +cdef inline np.uint16_t kernel_maximum(Py_ssize_t * histo, Py_ssize_t pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, @@ -106,7 +106,7 @@ cdef inline np.uint16_t kernel_maximum(Py_ssize_t * histo, float pop, return (0) -cdef inline np.uint16_t kernel_mean(Py_ssize_t * histo, float pop, +cdef inline np.uint16_t kernel_mean(Py_ssize_t * histo, Py_ssize_t pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, @@ -122,7 +122,7 @@ cdef inline np.uint16_t kernel_mean(Py_ssize_t * histo, float pop, return (0) -cdef inline np.uint16_t kernel_meansubstraction(Py_ssize_t * histo, float pop, +cdef inline np.uint16_t kernel_meansubstraction(Py_ssize_t * histo, Py_ssize_t pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, @@ -138,7 +138,7 @@ cdef inline np.uint16_t kernel_meansubstraction(Py_ssize_t * histo, float pop, return (0) -cdef inline np.uint16_t kernel_median(Py_ssize_t * histo, float pop, +cdef inline np.uint16_t kernel_median(Py_ssize_t * histo, Py_ssize_t pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, @@ -156,7 +156,7 @@ cdef inline np.uint16_t kernel_median(Py_ssize_t * histo, float pop, return (0) -cdef inline np.uint16_t kernel_minimum(Py_ssize_t * histo, float pop, +cdef inline np.uint16_t kernel_minimum(Py_ssize_t * histo, Py_ssize_t pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, @@ -171,7 +171,7 @@ cdef inline np.uint16_t kernel_minimum(Py_ssize_t * histo, float pop, return (0) -cdef inline np.uint16_t kernel_modal(Py_ssize_t * histo, float pop, +cdef inline np.uint16_t kernel_modal(Py_ssize_t * histo, Py_ssize_t pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, @@ -188,7 +188,7 @@ cdef inline np.uint16_t kernel_modal(Py_ssize_t * histo, float pop, return (0) -cdef inline np.uint16_t kernel_morph_contr_enh(Py_ssize_t * histo, float pop, +cdef inline np.uint16_t kernel_morph_contr_enh(Py_ssize_t * histo, Py_ssize_t pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, @@ -212,7 +212,7 @@ cdef inline np.uint16_t kernel_morph_contr_enh(Py_ssize_t * histo, float pop, return (0) -cdef inline np.uint16_t kernel_pop(Py_ssize_t * histo, float pop, +cdef inline np.uint16_t kernel_pop(Py_ssize_t * histo, Py_ssize_t pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, @@ -220,7 +220,7 @@ cdef inline np.uint16_t kernel_pop(Py_ssize_t * histo, float pop, return (pop) -cdef inline np.uint16_t kernel_threshold(Py_ssize_t * histo, float pop, +cdef inline np.uint16_t kernel_threshold(Py_ssize_t * histo, Py_ssize_t pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, @@ -236,7 +236,7 @@ cdef inline np.uint16_t kernel_threshold(Py_ssize_t * histo, float pop, return (0) -cdef inline np.uint16_t kernel_tophat(Py_ssize_t * histo, float pop, +cdef inline np.uint16_t kernel_tophat(Py_ssize_t * histo, Py_ssize_t pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, @@ -250,7 +250,7 @@ cdef inline np.uint16_t kernel_tophat(Py_ssize_t * histo, float pop, return (i - g) -cdef inline np.uint16_t kernel_entropy(Py_ssize_t * histo, float pop, +cdef inline np.uint16_t kernel_entropy(Py_ssize_t * histo, Py_ssize_t pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, diff --git a/skimage/filter/rank/_crank16_bilateral.pyx b/skimage/filter/rank/_crank16_bilateral.pyx index 1fb81a2d..98bc5683 100644 --- a/skimage/filter/rank/_crank16_bilateral.pyx +++ b/skimage/filter/rank/_crank16_bilateral.pyx @@ -13,7 +13,7 @@ from skimage.filter.rank._core16 cimport _core16 # ----------------------------------------------------------------- -cdef inline np.uint16_t kernel_mean(Py_ssize_t * histo, float pop, +cdef inline np.uint16_t kernel_mean(Py_ssize_t * histo, Py_ssize_t pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, @@ -35,7 +35,7 @@ cdef inline np.uint16_t kernel_mean(Py_ssize_t * histo, float pop, return (0) -cdef inline np.uint16_t kernel_pop(Py_ssize_t * histo, float pop, +cdef inline np.uint16_t kernel_pop(Py_ssize_t * histo, Py_ssize_t pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, diff --git a/skimage/filter/rank/_crank16_percentiles.pyx b/skimage/filter/rank/_crank16_percentiles.pyx index 4c2525be..8f8585e7 100644 --- a/skimage/filter/rank/_crank16_percentiles.pyx +++ b/skimage/filter/rank/_crank16_percentiles.pyx @@ -13,7 +13,7 @@ from skimage.filter.rank._core16 cimport _core16, int_min, int_max # ----------------------------------------------------------------- -cdef inline np.uint16_t kernel_autolevel(Py_ssize_t * histo, float pop, +cdef inline np.uint16_t kernel_autolevel(Py_ssize_t * histo, Py_ssize_t pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, @@ -46,7 +46,7 @@ cdef inline np.uint16_t kernel_autolevel(Py_ssize_t * histo, float pop, return (0) -cdef inline np.uint16_t kernel_gradient(Py_ssize_t * histo, float pop, +cdef inline np.uint16_t kernel_gradient(Py_ssize_t * histo, Py_ssize_t pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, @@ -74,7 +74,7 @@ cdef inline np.uint16_t kernel_gradient(Py_ssize_t * histo, float pop, return (0) -cdef inline np.uint16_t kernel_mean(Py_ssize_t * histo, float pop, +cdef inline np.uint16_t kernel_mean(Py_ssize_t * histo, Py_ssize_t pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, @@ -100,7 +100,7 @@ cdef inline np.uint16_t kernel_mean(Py_ssize_t * histo, float pop, return (0) -cdef inline np.uint16_t kernel_mean_substraction(Py_ssize_t * histo, float pop, +cdef inline np.uint16_t kernel_mean_substraction(Py_ssize_t * histo, Py_ssize_t pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, @@ -125,7 +125,7 @@ cdef inline np.uint16_t kernel_mean_substraction(Py_ssize_t * histo, float pop, return (0) -cdef inline np.uint16_t kernel_morph_contr_enh(Py_ssize_t * histo, float pop, +cdef inline np.uint16_t kernel_morph_contr_enh(Py_ssize_t * histo, Py_ssize_t pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, @@ -159,7 +159,7 @@ cdef inline np.uint16_t kernel_morph_contr_enh(Py_ssize_t * histo, float pop, return (0) -cdef inline np.uint16_t kernel_percentile(Py_ssize_t * histo, float pop, +cdef inline np.uint16_t kernel_percentile(Py_ssize_t * histo, Py_ssize_t pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, @@ -179,7 +179,7 @@ cdef inline np.uint16_t kernel_percentile(Py_ssize_t * histo, float pop, return (0) -cdef inline np.uint16_t kernel_pop(Py_ssize_t * histo, float pop, +cdef inline np.uint16_t kernel_pop(Py_ssize_t * histo, Py_ssize_t pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, @@ -199,7 +199,7 @@ cdef inline np.uint16_t kernel_pop(Py_ssize_t * histo, float pop, return (0) -cdef inline np.uint16_t kernel_threshold(Py_ssize_t * histo, float pop, +cdef inline np.uint16_t kernel_threshold(Py_ssize_t * histo, Py_ssize_t pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, diff --git a/skimage/filter/rank/_crank8.pyx b/skimage/filter/rank/_crank8.pyx index 7398b26f..6fee8a9f 100644 --- a/skimage/filter/rank/_crank8.pyx +++ b/skimage/filter/rank/_crank8.pyx @@ -14,7 +14,7 @@ from skimage.filter.rank._core8 cimport _core8 # ----------------------------------------------------------------- -cdef inline np.uint8_t kernel_autolevel(Py_ssize_t * histo, float pop, +cdef inline np.uint8_t kernel_autolevel(Py_ssize_t * histo, Py_ssize_t pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): @@ -38,7 +38,7 @@ cdef inline np.uint8_t kernel_autolevel(Py_ssize_t * histo, float pop, return (0) -cdef inline np.uint8_t kernel_bottomhat(Py_ssize_t * histo, float pop, +cdef inline np.uint8_t kernel_bottomhat(Py_ssize_t * histo, Py_ssize_t pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): @@ -51,7 +51,7 @@ cdef inline np.uint8_t kernel_bottomhat(Py_ssize_t * histo, float pop, return (g - i) -cdef inline np.uint8_t kernel_equalize(Py_ssize_t * histo, float pop, +cdef inline np.uint8_t kernel_equalize(Py_ssize_t * histo, Py_ssize_t pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): @@ -69,7 +69,7 @@ cdef inline np.uint8_t kernel_equalize(Py_ssize_t * histo, float pop, return (0) -cdef inline np.uint8_t kernel_gradient(Py_ssize_t * histo, float pop, +cdef inline np.uint8_t kernel_gradient(Py_ssize_t * histo, Py_ssize_t pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): @@ -89,7 +89,7 @@ cdef inline np.uint8_t kernel_gradient(Py_ssize_t * histo, float pop, return (0) -cdef inline np.uint8_t kernel_maximum(Py_ssize_t * histo, float pop, +cdef inline np.uint8_t kernel_maximum(Py_ssize_t * histo, Py_ssize_t pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): @@ -103,7 +103,7 @@ cdef inline np.uint8_t kernel_maximum(Py_ssize_t * histo, float pop, return (0) -cdef inline np.uint8_t kernel_mean(Py_ssize_t * histo, float pop, +cdef inline np.uint8_t kernel_mean(Py_ssize_t * histo, Py_ssize_t pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): @@ -118,7 +118,7 @@ cdef inline np.uint8_t kernel_mean(Py_ssize_t * histo, float pop, return (0) -cdef inline np.uint8_t kernel_meansubstraction(Py_ssize_t * histo, float pop, +cdef inline np.uint8_t kernel_meansubstraction(Py_ssize_t * histo, Py_ssize_t pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): @@ -133,7 +133,7 @@ cdef inline np.uint8_t kernel_meansubstraction(Py_ssize_t * histo, float pop, return (0) -cdef inline np.uint8_t kernel_median(Py_ssize_t * histo, float pop, +cdef inline np.uint8_t kernel_median(Py_ssize_t * histo, Py_ssize_t pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): @@ -150,7 +150,7 @@ cdef inline np.uint8_t kernel_median(Py_ssize_t * histo, float pop, return (0) -cdef inline np.uint8_t kernel_minimum(Py_ssize_t * histo, float pop, +cdef inline np.uint8_t kernel_minimum(Py_ssize_t * histo, Py_ssize_t pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): @@ -164,7 +164,7 @@ cdef inline np.uint8_t kernel_minimum(Py_ssize_t * histo, float pop, return (0) -cdef inline np.uint8_t kernel_modal(Py_ssize_t * histo, float pop, +cdef inline np.uint8_t kernel_modal(Py_ssize_t * histo, Py_ssize_t pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): @@ -180,7 +180,7 @@ cdef inline np.uint8_t kernel_modal(Py_ssize_t * histo, float pop, return (0) -cdef inline np.uint8_t kernel_morph_contr_enh(Py_ssize_t * histo, float pop, +cdef inline np.uint8_t kernel_morph_contr_enh(Py_ssize_t * histo, Py_ssize_t pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): @@ -203,14 +203,14 @@ cdef inline np.uint8_t kernel_morph_contr_enh(Py_ssize_t * histo, float pop, return (0) -cdef inline np.uint8_t kernel_pop(Py_ssize_t * histo, float pop, +cdef inline np.uint8_t kernel_pop(Py_ssize_t * histo, Py_ssize_t pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): return (pop) -cdef inline np.uint8_t kernel_threshold(Py_ssize_t * histo, float pop, +cdef inline np.uint8_t kernel_threshold(Py_ssize_t * histo, Py_ssize_t pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): @@ -225,7 +225,7 @@ cdef inline np.uint8_t kernel_threshold(Py_ssize_t * histo, float pop, return (0) -cdef inline np.uint8_t kernel_tophat(Py_ssize_t * histo, float pop, +cdef inline np.uint8_t kernel_tophat(Py_ssize_t * histo, Py_ssize_t pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): @@ -238,7 +238,7 @@ cdef inline np.uint8_t kernel_tophat(Py_ssize_t * histo, float pop, return (i - g) -cdef inline np.uint8_t kernel_noise_filter(Py_ssize_t * histo, float pop, +cdef inline np.uint8_t kernel_noise_filter(Py_ssize_t * histo, Py_ssize_t pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): @@ -262,7 +262,7 @@ cdef inline np.uint8_t kernel_noise_filter(Py_ssize_t * histo, float pop, return min_i -cdef inline np.uint8_t kernel_entropy(Py_ssize_t * histo, float pop, +cdef inline np.uint8_t kernel_entropy(Py_ssize_t * histo, Py_ssize_t pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i @@ -278,7 +278,7 @@ cdef inline np.uint8_t kernel_entropy(Py_ssize_t * histo, float pop, return e*10 -cdef inline np.uint8_t kernel_otsu(Py_ssize_t * histo, float pop, np.uint8_t g, +cdef inline np.uint8_t kernel_otsu(Py_ssize_t * histo, Py_ssize_t pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i diff --git a/skimage/filter/rank/_crank8_percentiles.pyx b/skimage/filter/rank/_crank8_percentiles.pyx index 777aec64..0bc81aac 100644 --- a/skimage/filter/rank/_crank8_percentiles.pyx +++ b/skimage/filter/rank/_crank8_percentiles.pyx @@ -13,7 +13,7 @@ from skimage.filter.rank._core8 cimport _core8, uint8_max, uint8_min # ----------------------------------------------------------------- -cdef inline np.uint8_t kernel_autolevel(Py_ssize_t * histo, float pop, +cdef inline np.uint8_t kernel_autolevel(Py_ssize_t * histo, Py_ssize_t pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): cdef int i, imin, imax, sum, delta @@ -45,7 +45,7 @@ cdef inline np.uint8_t kernel_autolevel(Py_ssize_t * histo, float pop, return (128) -cdef inline np.uint8_t kernel_gradient(Py_ssize_t * histo, float pop, +cdef inline np.uint8_t kernel_gradient(Py_ssize_t * histo, Py_ssize_t pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): cdef int i, imin, imax, sum, delta @@ -70,7 +70,7 @@ cdef inline np.uint8_t kernel_gradient(Py_ssize_t * histo, float pop, return (0) -cdef inline np.uint8_t kernel_mean(Py_ssize_t * histo, float pop, +cdef inline np.uint8_t kernel_mean(Py_ssize_t * histo, Py_ssize_t pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): cdef int i, sum, mean, n @@ -92,7 +92,7 @@ cdef inline np.uint8_t kernel_mean(Py_ssize_t * histo, float pop, return (0) -cdef inline np.uint8_t kernel_mean_substraction(Py_ssize_t * histo, float pop, +cdef inline np.uint8_t kernel_mean_substraction(Py_ssize_t * histo, Py_ssize_t pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): cdef int i, sum, mean, n @@ -114,7 +114,7 @@ cdef inline np.uint8_t kernel_mean_substraction(Py_ssize_t * histo, float pop, return (0) -cdef inline np.uint8_t kernel_morph_contr_enh(Py_ssize_t * histo, float pop, +cdef inline np.uint8_t kernel_morph_contr_enh(Py_ssize_t * histo, Py_ssize_t pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): cdef int i, imin, imax, sum, delta @@ -145,7 +145,7 @@ cdef inline np.uint8_t kernel_morph_contr_enh(Py_ssize_t * histo, float pop, return (0) -cdef inline np.uint8_t kernel_percentile(Py_ssize_t * histo, float pop, +cdef inline np.uint8_t kernel_percentile(Py_ssize_t * histo, Py_ssize_t pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): cdef int i @@ -162,7 +162,7 @@ cdef inline np.uint8_t kernel_percentile(Py_ssize_t * histo, float pop, return (0) -cdef inline np.uint8_t kernel_pop(Py_ssize_t * histo, float pop, +cdef inline np.uint8_t kernel_pop(Py_ssize_t * histo, Py_ssize_t pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): cdef int i, sum, n @@ -179,7 +179,7 @@ cdef inline np.uint8_t kernel_pop(Py_ssize_t * histo, float pop, return (0) -cdef inline np.uint8_t kernel_threshold(Py_ssize_t * histo, float pop, +cdef inline np.uint8_t kernel_threshold(Py_ssize_t * histo, Py_ssize_t pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): cdef int i From 804b426787869932a1d5dbb1977045321acb9684 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Sch=C3=B6nberger?= Date: Sat, 10 Nov 2012 08:35:23 +0100 Subject: [PATCH 05/12] Clean Readme --- skimage/filter/rank/README.rst | 41 ++++++++++++++++------------------ 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/skimage/filter/rank/README.rst b/skimage/filter/rank/README.rst index aae62162..29a68edb 100644 --- a/skimage/filter/rank/README.rst +++ b/skimage/filter/rank/README.rst @@ -1,35 +1,32 @@ -To use this to build your Cython file use the commandline options: - -.. sourcecode:: text - - $ python setup.py build_ext --inplace - - -**To do** +To do +----- * add simple examples, adapt documentation on existing examples - * add/check existing doc - * adapting tests for each type of filter -**General remarks** +General remarks +--------------- -Basically these filters compute local histogram for each pixel. Histogram is build using a moving window in -order to limit redundant computation. The path followed by the moving window is given hereunder +Basically these filters compute local histogram for each pixel. Histogram is +build using a moving window in order to limit redundant computation. The path +followed by the moving window is given hereunder ...-----------------------\ /--------------------------/ \-------------------------- ... -A comparison is proposed with cmorph.dilate algorithm to show how computation costs evolve with respect to image size or -structuring element size. This implementation gives better results for large structuring elements. +A comparison is proposed with cmorph.dilate algorithm to show how computation +costs evolve with respect to image size or structuring element size. This +implementation gives better results for large structuring elements. -A local histogram is update at each pixel by introducing pixel entering the structuring element border and -by removing those leaving it. The histogram size is 8bit (256 bins) for 8 bit images and 2 to 12 bit (up to 4096 bins) -for 16bit image depending on the image maximum value. Image with pixels higher than 4095 raise a ValueError. - -The filter is applied up to the image border, the neighboorhood used is adjusted accordingly. The user may provide -a mask image (same size as input image) where non zero value are the part of the image participating the the -histogram computation. By default all the image is filtered. +A local histogram is update at each pixel by introducing pixel entering the +structuring element border and by removing those leaving it. The histogram size +is 8bit (256 bins) for 8 bit images and 2 to 12 bit (up to 4096 bins) for 16bit +image depending on the image maximum value. Image with pixels higher than 4095 +raise a ValueError. +The filter is applied up to the image border, the neighboorhood used is adjusted +accordingly. The user may provide a mask image (same size as input image) where +non zero value are the part of the image participating the the histogram +computation. By default all the image is filtered. From 2bb139fb03a8443e7e01cfa9fa9eccb3e2d405db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Sch=C3=B6nberger?= Date: Sat, 10 Nov 2012 08:39:27 +0100 Subject: [PATCH 06/12] Wrap lines --- skimage/filter/rank/_crank16.pyx | 18 ++++++++++++------ skimage/filter/rank/_crank16_percentiles.pyx | 18 ++++++++++++------ skimage/filter/rank/_crank8_percentiles.pyx | 9 ++++++--- 3 files changed, 30 insertions(+), 15 deletions(-) diff --git a/skimage/filter/rank/_crank16.pyx b/skimage/filter/rank/_crank16.pyx index bb3f7c7d..9c4b8fe1 100644 --- a/skimage/filter/rank/_crank16.pyx +++ b/skimage/filter/rank/_crank16.pyx @@ -122,9 +122,12 @@ cdef inline np.uint16_t kernel_mean(Py_ssize_t * histo, Py_ssize_t pop, return (0) -cdef inline np.uint16_t kernel_meansubstraction(Py_ssize_t * histo, Py_ssize_t pop, - np.uint16_t g, Py_ssize_t bitdepth, - Py_ssize_t maxbin, Py_ssize_t midbin, +cdef inline np.uint16_t kernel_meansubstraction(Py_ssize_t * histo, + Py_ssize_t pop, + np.uint16_t g, + Py_ssize_t bitdepth, + Py_ssize_t maxbin, + Py_ssize_t midbin, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i @@ -188,9 +191,12 @@ cdef inline np.uint16_t kernel_modal(Py_ssize_t * histo, Py_ssize_t pop, return (0) -cdef inline np.uint16_t kernel_morph_contr_enh(Py_ssize_t * histo, Py_ssize_t pop, - np.uint16_t g, Py_ssize_t bitdepth, - Py_ssize_t maxbin, Py_ssize_t midbin, +cdef inline np.uint16_t kernel_morph_contr_enh(Py_ssize_t * histo, + Py_ssize_t pop, + np.uint16_t g, + Py_ssize_t bitdepth, + Py_ssize_t maxbin, + Py_ssize_t midbin, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i, imin, imax diff --git a/skimage/filter/rank/_crank16_percentiles.pyx b/skimage/filter/rank/_crank16_percentiles.pyx index 8f8585e7..e5dc2ab7 100644 --- a/skimage/filter/rank/_crank16_percentiles.pyx +++ b/skimage/filter/rank/_crank16_percentiles.pyx @@ -100,9 +100,12 @@ cdef inline np.uint16_t kernel_mean(Py_ssize_t * histo, Py_ssize_t pop, return (0) -cdef inline np.uint16_t kernel_mean_substraction(Py_ssize_t * histo, Py_ssize_t pop, - np.uint16_t g, Py_ssize_t bitdepth, - Py_ssize_t maxbin, Py_ssize_t midbin, +cdef inline np.uint16_t kernel_mean_substraction(Py_ssize_t * histo, + Py_ssize_t pop, + np.uint16_t g, + Py_ssize_t bitdepth, + Py_ssize_t maxbin, + Py_ssize_t midbin, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): @@ -125,9 +128,12 @@ cdef inline np.uint16_t kernel_mean_substraction(Py_ssize_t * histo, Py_ssize_t return (0) -cdef inline np.uint16_t kernel_morph_contr_enh(Py_ssize_t * histo, Py_ssize_t pop, - np.uint16_t g, Py_ssize_t bitdepth, - Py_ssize_t maxbin, Py_ssize_t midbin, +cdef inline np.uint16_t kernel_morph_contr_enh(Py_ssize_t * histo, + Py_ssize_t pop, + np.uint16_t g, + Py_ssize_t bitdepth, + Py_ssize_t maxbin, + Py_ssize_t midbin, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): diff --git a/skimage/filter/rank/_crank8_percentiles.pyx b/skimage/filter/rank/_crank8_percentiles.pyx index 0bc81aac..4a11bdc4 100644 --- a/skimage/filter/rank/_crank8_percentiles.pyx +++ b/skimage/filter/rank/_crank8_percentiles.pyx @@ -92,8 +92,10 @@ cdef inline np.uint8_t kernel_mean(Py_ssize_t * histo, Py_ssize_t pop, return (0) -cdef inline np.uint8_t kernel_mean_substraction(Py_ssize_t * histo, Py_ssize_t pop, - np.uint8_t g, float p0, float p1, +cdef inline np.uint8_t kernel_mean_substraction(Py_ssize_t * histo, + Py_ssize_t pop, + np.uint8_t g, + float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): cdef int i, sum, mean, n @@ -114,7 +116,8 @@ cdef inline np.uint8_t kernel_mean_substraction(Py_ssize_t * histo, Py_ssize_t p return (0) -cdef inline np.uint8_t kernel_morph_contr_enh(Py_ssize_t * histo, Py_ssize_t pop, +cdef inline np.uint8_t kernel_morph_contr_enh(Py_ssize_t * histo, + Py_ssize_t pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): cdef int i, imin, imax, sum, delta From 7ea3a754e0584cb5057f7928d0714ab1cd1ebef8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Sch=C3=B6nberger?= Date: Sat, 10 Nov 2012 08:59:48 +0100 Subject: [PATCH 07/12] Remove duplicate contiguous conversion --- skimage/filter/rank/bilateral_rank.pyx | 2 +- skimage/filter/rank/percentile_rank.pyx | 2 +- skimage/filter/rank/rank.pyx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/skimage/filter/rank/bilateral_rank.pyx b/skimage/filter/rank/bilateral_rank.pyx index 39afa71a..73434bb5 100644 --- a/skimage/filter/rank/bilateral_rank.pyx +++ b/skimage/filter/rank/bilateral_rank.pyx @@ -41,10 +41,10 @@ def _apply(func8, func16, image, selem, out, mask, shift_x, shift_y, s0, s1): else: mask = np.ascontiguousarray(mask) mask = img_as_ubyte(mask) + if image is out: raise NotImplementedError("Cannot perform rank operation in place.") - mask = np.ascontiguousarray(mask) if image.dtype == np.uint8: if func8 is None: raise TypeError("Not implemented for uint8 image.") diff --git a/skimage/filter/rank/percentile_rank.pyx b/skimage/filter/rank/percentile_rank.pyx index c5a5a594..5e506035 100644 --- a/skimage/filter/rank/percentile_rank.pyx +++ b/skimage/filter/rank/percentile_rank.pyx @@ -40,10 +40,10 @@ def _apply(func8, func16, image, selem, out, mask, shift_x, shift_y, p0, p1): else: mask = np.ascontiguousarray(mask) mask = img_as_ubyte(mask) + if image is out: raise NotImplementedError("Cannot perform rank operation in place.") - mask = np.ascontiguousarray(mask) if image.dtype == np.uint8: if func8 is None: raise TypeError("Not implemented for uint8 image.") diff --git a/skimage/filter/rank/rank.pyx b/skimage/filter/rank/rank.pyx index 8ac98f81..74add3d7 100644 --- a/skimage/filter/rank/rank.pyx +++ b/skimage/filter/rank/rank.pyx @@ -33,10 +33,10 @@ def _apply(func8, func16, image, selem, out, mask, shift_x, shift_y): else: mask = np.ascontiguousarray(mask) mask = img_as_ubyte(mask) + if image is out: raise NotImplementedError("Cannot perform rank operation in place.") - mask = np.ascontiguousarray(mask) if image.dtype == np.uint8: if func8 is None: raise TypeError("Not implemented for uint8 image.") From c00fedde6cff84949cd7a5826af46980a45ebf99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Sch=C3=B6nberger?= Date: Sat, 10 Nov 2012 09:43:15 +0100 Subject: [PATCH 08/12] Fix, improve and extend histogram test cases --- skimage/filter/rank/tests/test_histo.py | 135 ++++++++++++++++-------- 1 file changed, 89 insertions(+), 46 deletions(-) diff --git a/skimage/filter/rank/tests/test_histo.py b/skimage/filter/rank/tests/test_histo.py index b6a7bbca..a943176d 100644 --- a/skimage/filter/rank/tests/test_histo.py +++ b/skimage/filter/rank/tests/test_histo.py @@ -1,57 +1,100 @@ -import sys -print sys.path -import skimage -print skimage - -import unittest - import numpy as np -from skimage.filter import rank +from numpy.testing import run_module_suite, assert_array_equal -from skimage import data -from skimage.morphology import cmorph,disk from skimage.filter.rank import _crank8, _crank16 -from skimage.filter.rank import _crank16_percentiles -class TestSequenceFunctions(unittest.TestCase): +def test_trivial_selem8(): + # check that min, max and mean returns identity if structuring element + # contains only central pixel - def setUp(self): - pass + image = np.zeros((5, 5), dtype=np.uint8) + out = np.zeros_like(image) + mask = np.ones_like(image, dtype=np.uint8) + image[2,2] = 255 + image[2,3] = 128 + image[1,2] = 16 - def test_trivial_selem(self): - # check that min, max and mean returns identity if structuring element contains only central pixel - - a = np.zeros((5,5),dtype='uint8') - a[2,2] = 255 - a[2,3] = 128 - a[1,2] = 16 - elem = np.asarray([[0,0,0],[0,1,0],[0,0,0]],dtype='uint8') - f = _crank8.mean(image=a,selem = elem,shift_x=0,shift_y=0) - np.testing.assert_array_equal(a,f) - f = _crank8.minimum(image=a,selem = elem,shift_x=0,shift_y=0) - np.testing.assert_array_equal(a,f) - f = _crank8.maximum(image=a,selem = elem,shift_x=0,shift_y=0) - np.testing.assert_array_equal(a,f) - - def test_smallest_selem(self): - # check that min, max and mean returns identity if structuring element contains only central pixel - - a = np.zeros((5,5),dtype='uint8') - a[2,2] = 255 - a[2,3] = 128 - a[1,2] = 16 - elem = np.asarray([[1]],dtype='uint8') - f = _crank8.mean(image=a,selem = elem,shift_x=0,shift_y=0) - np.testing.assert_array_equal(a,f) - f = _crank8.minimum(image=a,selem = elem,shift_x=0,shift_y=0) - np.testing.assert_array_equal(a,f) - f = _crank8.maximum(image=a,selem = elem,shift_x=0,shift_y=0) - np.testing.assert_array_equal(a,f) + elem = np.array([[0, 0, 0], [0, 1, 0],[0, 0, 0]], dtype=np.uint8) + _crank8.mean(image=image, selem=elem, out=out, mask=mask, + shift_x=0, shift_y=0) + assert_array_equal(image, out) + _crank8.minimum(image=image, selem=elem, out=out, mask=mask, + shift_x=0, shift_y=0) + assert_array_equal(image, out) + _crank8.maximum(image=image, selem=elem, out=out, mask=mask, + shift_x=0, shift_y=0) + assert_array_equal(image, out) +def test_trivial_selem16(): + # check that min, max and mean returns identity if structuring element + # contains only central pixel -if __name__ == '__main__': + image = np.zeros((5, 5), dtype=np.uint16) + out = np.zeros_like(image) + mask = np.ones_like(image, dtype=np.uint8) + image[2,2] = 255 + image[2,3] = 128 + image[1,2] = 16 - suite = unittest.TestLoader().loadTestsFromTestCase(TestSequenceFunctions) - unittest.TextTestRunner(verbosity=2).run(suite) + elem = np.array([[0, 0, 0], [0, 1, 0],[0, 0, 0]], dtype=np.uint8) + _crank16.mean(image=image, selem=elem, out=out, mask=mask, + shift_x=0, shift_y=0) + assert_array_equal(image, out) + _crank16.minimum(image=image, selem=elem, out=out, mask=mask, + shift_x=0, shift_y=0) + assert_array_equal(image, out) + _crank16.maximum(image=image, selem=elem, out=out, mask=mask, + shift_x=0, shift_y=0) + assert_array_equal(image, out) + + +def test_smallest_selem8(): + # check that min, max and mean returns identity if structuring element + # contains only central pixel + + image = np.zeros((5, 5), dtype=np.uint8) + out = np.zeros_like(image) + mask = np.ones_like(image, dtype=np.uint8) + image[2,2] = 255 + image[2,3] = 128 + image[1,2] = 16 + + elem = np.array([[1]], dtype=np.uint8) + _crank8.mean(image=image, selem=elem, out=out, mask=mask, + shift_x=0, shift_y=0) + assert_array_equal(image, out) + _crank8.minimum(image=image, selem=elem, out=out, mask=mask, + shift_x=0, shift_y=0) + assert_array_equal(image, out) + _crank8.maximum(image=image, selem=elem, out=out, mask=mask, + shift_x=0, shift_y=0) + assert_array_equal(image, out) + + +def test_smallest_selem16(): + # check that min, max and mean returns identity if structuring element + # contains only central pixel + + image = np.zeros((5, 5), dtype=np.uint16) + out = np.zeros_like(image) + mask = np.ones_like(image, dtype=np.uint8) + image[2,2] = 255 + image[2,3] = 128 + image[1,2] = 16 + + elem = np.array([[1]], dtype=np.uint8) + _crank16.mean(image=image, selem=elem, out=out, mask=mask, + shift_x=0, shift_y=0) + assert_array_equal(image, out) + _crank16.minimum(image=image, selem=elem, out=out, mask=mask, + shift_x=0, shift_y=0) + assert_array_equal(image, out) + _crank16.maximum(image=image, selem=elem, out=out, mask=mask, + shift_x=0, shift_y=0) + assert_array_equal(image, out) + + +if __name__ == "__main__": + run_module_suite() From 8c55640d6092a018f1c4628090fdbdef45da3b29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Sch=C3=B6nberger?= Date: Sat, 10 Nov 2012 11:20:56 +0100 Subject: [PATCH 09/12] Do not ignore exceptions in core functions --- skimage/filter/rank/_core16.pxd | 2 +- skimage/filter/rank/_core16.pyx | 4 ++-- skimage/filter/rank/_core8.pxd | 2 +- skimage/filter/rank/_core8.pyx | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/skimage/filter/rank/_core16.pxd b/skimage/filter/rank/_core16.pxd index 0ff5d518..f6f85202 100644 --- a/skimage/filter/rank/_core16.pxd +++ b/skimage/filter/rank/_core16.pxd @@ -14,4 +14,4 @@ cdef void _core16(np.uint16_t kernel(Py_ssize_t *, Py_ssize_t, np.uint16_t, np.ndarray[np.uint8_t, ndim=2] mask, np.ndarray[np.uint16_t, ndim=2] out, char shift_x, char shift_y, Py_ssize_t bitdepth, - float p0, float p1, Py_ssize_t s0, Py_ssize_t s1) + float p0, float p1, Py_ssize_t s0, Py_ssize_t s1) except * diff --git a/skimage/filter/rank/_core16.pyx b/skimage/filter/rank/_core16.pyx index 30d0a5f2..79fefe2b 100644 --- a/skimage/filter/rank/_core16.pyx +++ b/skimage/filter/rank/_core16.pyx @@ -37,7 +37,7 @@ cdef void _core16(np.uint16_t kernel(Py_ssize_t *, Py_ssize_t, np.uint16_t, np.ndarray[np.uint8_t, ndim=2] mask, np.ndarray[np.uint16_t, ndim=2] out, char shift_x, char shift_y, Py_ssize_t bitdepth, - float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): + float p0, float p1, Py_ssize_t s0, Py_ssize_t s1) except *: """Compute histogram for each pixel neighborhood, apply kernel function and use kernel function return value for output image. """ @@ -60,7 +60,7 @@ cdef void _core16(np.uint16_t kernel(Py_ssize_t *, Py_ssize_t, np.uint16_t, maxbin_list = [0, 0, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096] midbin_list = [0, 0, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048] - #set maxbin and midbin + # set maxbin and midbin cdef Py_ssize_t maxbin = maxbin_list[bitdepth] cdef Py_ssize_t midbin = midbin_list[bitdepth] diff --git a/skimage/filter/rank/_core8.pxd b/skimage/filter/rank/_core8.pxd index 6a6bdafa..08391eaf 100644 --- a/skimage/filter/rank/_core8.pxd +++ b/skimage/filter/rank/_core8.pxd @@ -19,4 +19,4 @@ cdef void _core8(np.uint8_t kernel(Py_ssize_t *, Py_ssize_t, np.uint8_t, float, np.ndarray[np.uint8_t, ndim=2] mask, np.ndarray[np.uint8_t, ndim=2] out, char shift_x, char shift_y, float p0, float p1, - Py_ssize_t s0, Py_ssize_t s1) + Py_ssize_t s0, Py_ssize_t s1) except * diff --git a/skimage/filter/rank/_core8.pyx b/skimage/filter/rank/_core8.pyx index fc1b64b6..3dabe9ec 100644 --- a/skimage/filter/rank/_core8.pyx +++ b/skimage/filter/rank/_core8.pyx @@ -48,7 +48,7 @@ cdef void _core8(np.uint8_t kernel(Py_ssize_t *, Py_ssize_t, np.uint8_t, float, np.ndarray[np.uint8_t, ndim=2] mask, np.ndarray[np.uint8_t, ndim=2] out, char shift_x, char shift_y, float p0, float p1, - Py_ssize_t s0, Py_ssize_t s1): + Py_ssize_t s0, Py_ssize_t s1) except *: """Compute histogram for each pixel neighborhood, apply kernel function and use kernel function return value for output image. """ From c9f95db67f425bf249269896a3c4ee92a313218b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Sch=C3=B6nberger?= Date: Sat, 10 Nov 2012 11:21:55 +0100 Subject: [PATCH 10/12] Fix, improve and extend test cases --- skimage/filter/rank/tests/test_suite.py | 353 ++++++++++++------------ 1 file changed, 182 insertions(+), 171 deletions(-) diff --git a/skimage/filter/rank/tests/test_suite.py b/skimage/filter/rank/tests/test_suite.py index 66b6537c..dd7c7703 100644 --- a/skimage/filter/rank/tests/test_suite.py +++ b/skimage/filter/rank/tests/test_suite.py @@ -1,191 +1,202 @@ -import sys -print sys.path -import skimage -print skimage - +import numpy as np +from numpy.testing import run_module_suite, assert_array_equal, assert_raises import unittest -import numpy as np -from skimage.filter import rank - from skimage import data -from skimage.morphology import cmorph,disk -from skimage.filter.rank import _crank8, _crank16 -from skimage.filter.rank import _crank16_percentiles +from skimage.morphology import cmorph, disk +from skimage.filter import rank +from skimage.filter.rank import _crank8, _crank16, _crank16_percentiles -class TestSequenceFunctions(unittest.TestCase): +def test_random_sizes(): + # make sure the size is not a problem - def setUp(self): - pass + niter = 10 + elem = np.array([[1, 1, 1], [1, 1, 1], [1, 1, 1]], dtype=np.uint8) + for m, n in np.random.random_integers(1, 100, size=(10, 2)): + mask = np.ones((m, n), dtype=np.uint8) - def test_random_sizes(self): - # make sure the size is not a problem + image8 = np.ones((m, n), dtype=np.uint8) + out8 = np.empty_like(image8) + _crank8.mean(image=image8, selem=elem, mask=mask, out=out8, + shift_x=0, shift_y=0) + assert_array_equal(image8.shape, out8.shape) + _crank8.mean(image=image8, selem=elem, mask=mask, out=out8, + shift_x=+1, shift_y=+1) + assert_array_equal(image8.shape, out8.shape) - niter = 10 - elem = np.asarray([[1,1,1],[1,1,1],[1,1,1]],dtype='uint8') - for m,n in np.random.random_integers(1,100,size=(10,2)): - a8 = np.ones((m,n),dtype='uint8') - r = _crank8.mean(image=a8,selem = elem,shift_x=0,shift_y=0) - self.assertTrue(a8.shape == r.shape) - r = _crank8.mean(image=a8,selem = elem,shift_x=+1,shift_y=+1) - self.assertTrue(a8.shape == r.shape) + image16 = np.ones((m, n), dtype=np.uint16) + out16 = np.empty_like(image8, dtype=np.uint16) + _crank16.mean(image=image16, selem=elem, mask=mask, out=out16, + shift_x=0, shift_y=0) + assert_array_equal(image16.shape, out16.shape) + _crank16.mean(image=image16, selem=elem, mask=mask, out=out16, + shift_x=+1, shift_y=+1) + assert_array_equal(image16.shape, out16.shape) - for m,n in np.random.random_integers(1,100,size=(10,2)): - a16 = np.ones((m,n),dtype='uint16') - r = _crank16.mean(image=a16,selem = elem,shift_x=0,shift_y=0) - self.assertTrue(a16.shape == r.shape) - r = _crank16.mean(image=a16,selem = elem,shift_x=+1,shift_y=+1) - self.assertTrue(a16.shape == r.shape) - - for m,n in np.random.random_integers(1,100,size=(10,2)): - a16 = np.ones((m,n),dtype='uint16') - r = _crank16_percentiles.mean(image=a16,selem = elem,shift_x=0,shift_y=0,p0=.1,p1=.9) - self.assertTrue(a16.shape == r.shape) - r = _crank16_percentiles.mean(image=a16,selem = elem,shift_x=+1,shift_y=+1,p0=.1,p1=.9) - self.assertTrue(a16.shape == r.shape) - - def test_compare_with_cmorph_dilate(self): - #compare the result of maximum filter with dilate - - a = (np.random.random((500,500))*256).astype('uint8') - - for r in range(1,20,1): - elem = np.ones((r,r),dtype='uint8') - # elem = (np.random.random((r,r))>.5).astype('uint8') - rc = _crank8.maximum(image=a,selem = elem) - cm = cmorph.dilate(image=a,selem = elem) - self.assertTrue((rc==cm).all()) - - def test_compare_with_cmorph_erode(self): - #compare the result of maximum filter with erode - - a = (np.random.random((500,500))*256).astype('uint8') - - for r in range(1,20,1): - elem = np.ones((r,r),dtype='uint8') - # elem = (np.random.random((r,r))>.5).astype('uint8') - rc = _crank8.minimum(image=a,selem = elem) - cm = cmorph.erode(image=a,selem = elem) - self.assertTrue((rc==cm).all()) - - def test_bitdepth(self): - # test the different bit depth for rank16 - - elem = np.ones((3,3),dtype='uint8') - a16 = np.ones((100,100),dtype='uint16')*255 - r = _crank16_percentiles.mean(image=a16,selem = elem,shift_x=0,shift_y=0,p0=.1,p1=.9,bitdepth=8) - a16 = np.ones((100,100),dtype='uint16')*255*2 - r = _crank16_percentiles.mean(image=a16,selem = elem,shift_x=0,shift_y=0,p0=.1,p1=.9,bitdepth=9) - a16 = np.ones((100,100),dtype='uint16')*255*4 - r = _crank16_percentiles.mean(image=a16,selem = elem,shift_x=0,shift_y=0,p0=.1,p1=.9,bitdepth=10) - a16 = np.ones((100,100),dtype='uint16')*255*8 - r = _crank16_percentiles.mean(image=a16,selem = elem,shift_x=0,shift_y=0,p0=.1,p1=.9,bitdepth=11) - a16 = np.ones((100,100),dtype='uint16')*255*16 - r = _crank16_percentiles.mean(image=a16,selem = elem,shift_x=0,shift_y=0,p0=.1,p1=.9,bitdepth=12) - - def test_population(self): - # check the number of valid pixels in the neighborhood - - a = np.zeros((5,5),dtype='uint8') - elem = np.ones((3,3),dtype='uint8') - p = _crank8.pop(image=a,selem = elem) - r = np.asarray([[4, 6, 6, 6, 4], - [6, 9, 9, 9, 6], - [6, 9, 9, 9, 6], - [6, 9, 9, 9, 6], - [4, 6, 6, 6, 4]]) - np.testing.assert_array_equal(r,p) - - def test_structuring_element(self): - # check the output for a custom structuring element - - a = np.zeros((6,6),dtype='uint8') - a[2,2] = 255 - elem = np.asarray([[1,1,0],[1,1,1],[0,0,1]],dtype='uint8') - f = _crank8.maximum(image=a,selem = elem,shift_x=1,shift_y=1) - r = np.asarray([[ 0, 0, 0, 0, 0, 0], - [ 0, 0, 0, 0, 0, 0], - [ 0, 0, 255, 0, 0, 0], - [ 0, 0, 255, 255, 255, 0], - [ 0, 0, 0, 255, 255, 0], - [ 0, 0, 0, 0, 0, 0]]) - np.testing.assert_array_equal(r,f) + _crank16_percentiles.mean(image=image16, mask=mask, out=out16, + selem=elem, shift_x=0, shift_y=0, p0=.1, p1=.9) + assert_array_equal(image16.shape, out16.shape) + _crank16_percentiles.mean(image=image16, mask=mask, out=out16, + selem=elem, shift_x=+1, shift_y=+1, p0=.1, p1=.9) + assert_array_equal(image16.shape, out16.shape) - @unittest.expectedFailure - def test_fail_on_bitdepth(self): - # should fail because data bitdepth is too high for the function +def test_compare_with_cmorph_dilate(): + # compare the result of maximum filter with dilate - a16 = np.ones((100,100),dtype='uint16')*255 - elem = np.ones((3,3),dtype='uint8') - f = _crank16_percentiles.mean(image=a16,selem = elem,shift_x=0,shift_y=0,p0=.1,p1=.9,bitdepth=4) + image = (np.random.random((100, 100)) * 256).astype(np.uint8) + out = np.empty_like(image) + mask = np.ones(image.shape, dtype=np.uint8) - def test_output(self): - #check rank function with external OUT output array - - selem = disk(20) - a = (np.random.random((500,500))*256).astype('uint8') - out = np.zeros_like(a) - f1 = rank.mean(a,selem,out=out) - f2 = rank.mean(a,selem) - np.testing.assert_array_equal(f1,f2) - np.testing.assert_array_equal(out,f2) - - @unittest.expectedFailure - def test_inplace_output(self): - #rank filters are not supposed to filter inplace - - selem = disk(20) - a = (np.random.random((500,500))*256).astype('uint8') - out = a - f = rank.mean(a,selem,out=out) - np.testing.assert_array_equal(f,out) + for r in range(1, 20, 1): + elem = np.ones((r, r), dtype=np.uint8) + _crank8.maximum(image=image, selem=elem, out=out, mask=mask) + cm = cmorph.dilate(image=image, selem=elem) + assert_array_equal(out, cm) - def test_compare_autolevels(self): - # compare autolevel and percentile autolevel with p0=0.0 and p1=1.0 - # should returns the same arrays +def test_compare_with_cmorph_erode(): + # compare the result of maximum filter with erode - image = data.camera() + image = (np.random.random((100, 100)) * 256).astype(np.uint8) + out = np.empty_like(image) + mask = np.ones(image.shape, dtype=np.uint8) - selem = disk(20) - loc_autolevel = rank.autolevel(image,selem=selem) - loc_perc_autolevel = rank.percentile_autolevel(image,selem=selem,p0=.0,p1=1.) - - assert (loc_autolevel==loc_perc_autolevel).all() - - def test_compare_autolevels_16bit(self): - # compare autolevel(16bit) and percentile autolevel(16bit) with p0=0.0 and p1=1.0 - # should returns the same arrays - - image = data.camera().astype(np.uint16)*4 - - selem = disk(20) - loc_autolevel = rank.autolevel(image,selem=selem) - loc_perc_autolevel = rank.percentile_autolevel(image,selem=selem,p0=.0,p1=1.) - - assert (loc_autolevel==loc_perc_autolevel).all() - - def test_compare_8bit_vs_16bit(self): - # filters applied on 8bit image ore 16bit image (having only real 8bit of dynamic) - # should be identical - - i8 = data.camera() - i16 = i8.astype(np.uint16) - assert (i8==i16).all() - - methods = ['autolevel','bottomhat','equalize','gradient','maximum','mean' - ,'meansubstraction','median','minimum','modal','morph_contr_enh','pop','threshold', 'tophat'] - - for method in methods: - func = eval('rank.%s'%method) - f8 = func(i8,disk(3)) - f16 = func(i16,disk(3)) - assert (f8==f16).all() + for r in range(1, 20, 1): + elem = np.ones((r, r), dtype=np.uint8) + _crank8.minimum(image=image, selem=elem, out=out, mask=mask) + cm = cmorph.erode(image=image, selem=elem) + assert_array_equal(out, cm) -if __name__ == '__main__': +def test_bitdepth(): + # test the different bit depth for rank16 - suite = unittest.TestLoader().loadTestsFromTestCase(TestSequenceFunctions) - unittest.TextTestRunner(verbosity=2).run(suite) + elem = np.ones((3, 3), dtype=np.uint8) + out = np.empty((100, 100), dtype=np.uint16) + mask = np.ones((100, 100), dtype=np.uint8) + + for i in range(5): + image = np.ones((100, 100),dtype=np.uint16) * 255 * 2**i + r = _crank16_percentiles.mean(image=image, selem=elem, mask=mask, + out=out, shift_x=0, shift_y=0, p0=.1, p1=.9, bitdepth=8 + i) + + +def test_population(): + # check the number of valid pixels in the neighborhood + + image = np.zeros((5, 5), dtype=np.uint8) + elem = np.ones((3, 3), dtype=np.uint8) + out = np.empty_like(image) + mask = np.ones(image.shape, dtype=np.uint8) + + _crank8.pop(image=image, selem=elem, out=out, mask=mask) + r = np.array([[4, 6, 6, 6, 4], + [6, 9, 9, 9, 6], + [6, 9, 9, 9, 6], + [6, 9, 9, 9, 6], + [4, 6, 6, 6, 4]]) + assert_array_equal(r, out) + + +def test_structuring_element8(): + # check the output for a custom structuring element + + r = np.array([[ 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0], + [ 0, 0, 255, 0, 0, 0], + [ 0, 0, 255, 255, 255, 0], + [ 0, 0, 0, 255, 255, 0], + [ 0, 0, 0, 0, 0, 0]]) + + # 8bit + image = np.zeros((6, 6), dtype=np.uint8) + image[2, 2] = 255 + elem = np.asarray([[1, 1, 0], [1, 1, 1], [0, 0, 1]], dtype=np.uint8) + out = np.empty_like(image) + mask = np.ones(image.shape, dtype=np.uint8) + + _crank8.maximum(image=image, selem=elem, out=out, mask=mask, + shift_x=1, shift_y=1) + assert_array_equal(r, out) + + # 16bit + image = np.zeros((6, 6), dtype=np.uint16) + image[2, 2] = 255 + out = np.empty_like(image) + + _crank16.maximum(image=image, selem=elem, out=out, mask=mask, + shift_x=1, shift_y=1) + assert_array_equal(r, out) + + +def test_fail_on_bitdepth(): + # should fail because data bitdepth is too high for the function + + image = np.ones((100, 100), dtype=np.uint16) * 255 + elem = np.ones((3, 3), dtype=np.uint8) + out = np.empty_like(image) + mask = np.ones(image.shape, dtype=np.uint8) + assert_raises(AssertionError, _crank16_percentiles.mean, image=image, + selem=elem, out=out, mask=mask, shift_x=0, shift_y=0, bitdepth=4) + + +def test_inplace_output(): + # rank filters are not supposed to filter inplace + + selem = disk(20) + image = (np.random.random((500,500))*256).astype(np.uint8) + out = image + assert_raises(NotImplementedError, rank.mean, image, selem, out=out) + + +def test_compare_autolevels(): + # compare autolevel and percentile autolevel with p0=0.0 and p1=1.0 + # should returns the same arrays + + image = data.camera() + + selem = disk(20) + loc_autolevel = rank.autolevel(image, selem=selem) + loc_perc_autolevel = rank.percentile_autolevel(image, selem=selem, + p0=.0, p1=1.) + + assert_array_equal(loc_autolevel, loc_perc_autolevel) + + +def test_compare_autolevels_16bit(): + # compare autolevel(16bit) and percentile autolevel(16bit) with p0=0.0 and + # p1=1.0 should returns the same arrays + + image = data.camera().astype(np.uint16) * 4 + + selem = disk(20) + loc_autolevel = rank.autolevel(image, selem=selem) + loc_perc_autolevel = rank.percentile_autolevel(image, selem=selem, + p0=.0, p1=1.) + + assert_array_equal(loc_autolevel, loc_perc_autolevel) + + +def test_compare_8bit_vs_16bit(): + # filters applied on 8bit image ore 16bit image (having only real 8bit of + # dynamic) should be identical + + image8 = data.camera() + image16 = image8.astype(np.uint16) + assert_array_equal(image8, image16) + + methods = ['autolevel', 'bottomhat', 'equalize', 'gradient', 'maximum', + 'mean', 'meansubstraction', 'median', 'minimum', 'modal', + 'morph_contr_enh', 'pop', 'threshold', 'tophat'] + + for method in methods: + func = getattr(rank, method) + f8 = func(image8, disk(3)) + f16 = func(image16, disk(3)) + assert_array_equal(f8, f16) + + +if __name__ == "__main__": + run_module_suite() From f5ad204aca5912fddeefd6c6386aac6b12765678 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Sch=C3=B6nberger?= Date: Sat, 10 Nov 2012 11:23:43 +0100 Subject: [PATCH 11/12] Use single file for test cases and rename file --- skimage/filter/rank/tests/test_histo.py | 100 ------------------ .../tests/{test_suite.py => test_rank.py} | 92 ++++++++++++++++ 2 files changed, 92 insertions(+), 100 deletions(-) delete mode 100644 skimage/filter/rank/tests/test_histo.py rename skimage/filter/rank/tests/{test_suite.py => test_rank.py} (68%) diff --git a/skimage/filter/rank/tests/test_histo.py b/skimage/filter/rank/tests/test_histo.py deleted file mode 100644 index a943176d..00000000 --- a/skimage/filter/rank/tests/test_histo.py +++ /dev/null @@ -1,100 +0,0 @@ -import numpy as np -from numpy.testing import run_module_suite, assert_array_equal - -from skimage.filter.rank import _crank8, _crank16 - - -def test_trivial_selem8(): - # check that min, max and mean returns identity if structuring element - # contains only central pixel - - image = np.zeros((5, 5), dtype=np.uint8) - out = np.zeros_like(image) - mask = np.ones_like(image, dtype=np.uint8) - image[2,2] = 255 - image[2,3] = 128 - image[1,2] = 16 - - elem = np.array([[0, 0, 0], [0, 1, 0],[0, 0, 0]], dtype=np.uint8) - _crank8.mean(image=image, selem=elem, out=out, mask=mask, - shift_x=0, shift_y=0) - assert_array_equal(image, out) - _crank8.minimum(image=image, selem=elem, out=out, mask=mask, - shift_x=0, shift_y=0) - assert_array_equal(image, out) - _crank8.maximum(image=image, selem=elem, out=out, mask=mask, - shift_x=0, shift_y=0) - assert_array_equal(image, out) - - -def test_trivial_selem16(): - # check that min, max and mean returns identity if structuring element - # contains only central pixel - - image = np.zeros((5, 5), dtype=np.uint16) - out = np.zeros_like(image) - mask = np.ones_like(image, dtype=np.uint8) - image[2,2] = 255 - image[2,3] = 128 - image[1,2] = 16 - - elem = np.array([[0, 0, 0], [0, 1, 0],[0, 0, 0]], dtype=np.uint8) - _crank16.mean(image=image, selem=elem, out=out, mask=mask, - shift_x=0, shift_y=0) - assert_array_equal(image, out) - _crank16.minimum(image=image, selem=elem, out=out, mask=mask, - shift_x=0, shift_y=0) - assert_array_equal(image, out) - _crank16.maximum(image=image, selem=elem, out=out, mask=mask, - shift_x=0, shift_y=0) - assert_array_equal(image, out) - - -def test_smallest_selem8(): - # check that min, max and mean returns identity if structuring element - # contains only central pixel - - image = np.zeros((5, 5), dtype=np.uint8) - out = np.zeros_like(image) - mask = np.ones_like(image, dtype=np.uint8) - image[2,2] = 255 - image[2,3] = 128 - image[1,2] = 16 - - elem = np.array([[1]], dtype=np.uint8) - _crank8.mean(image=image, selem=elem, out=out, mask=mask, - shift_x=0, shift_y=0) - assert_array_equal(image, out) - _crank8.minimum(image=image, selem=elem, out=out, mask=mask, - shift_x=0, shift_y=0) - assert_array_equal(image, out) - _crank8.maximum(image=image, selem=elem, out=out, mask=mask, - shift_x=0, shift_y=0) - assert_array_equal(image, out) - - -def test_smallest_selem16(): - # check that min, max and mean returns identity if structuring element - # contains only central pixel - - image = np.zeros((5, 5), dtype=np.uint16) - out = np.zeros_like(image) - mask = np.ones_like(image, dtype=np.uint8) - image[2,2] = 255 - image[2,3] = 128 - image[1,2] = 16 - - elem = np.array([[1]], dtype=np.uint8) - _crank16.mean(image=image, selem=elem, out=out, mask=mask, - shift_x=0, shift_y=0) - assert_array_equal(image, out) - _crank16.minimum(image=image, selem=elem, out=out, mask=mask, - shift_x=0, shift_y=0) - assert_array_equal(image, out) - _crank16.maximum(image=image, selem=elem, out=out, mask=mask, - shift_x=0, shift_y=0) - assert_array_equal(image, out) - - -if __name__ == "__main__": - run_module_suite() diff --git a/skimage/filter/rank/tests/test_suite.py b/skimage/filter/rank/tests/test_rank.py similarity index 68% rename from skimage/filter/rank/tests/test_suite.py rename to skimage/filter/rank/tests/test_rank.py index dd7c7703..e92f386c 100644 --- a/skimage/filter/rank/tests/test_suite.py +++ b/skimage/filter/rank/tests/test_rank.py @@ -198,5 +198,97 @@ def test_compare_8bit_vs_16bit(): assert_array_equal(f8, f16) +def test_trivial_selem8(): + # check that min, max and mean returns identity if structuring element + # contains only central pixel + + image = np.zeros((5, 5), dtype=np.uint8) + out = np.zeros_like(image) + mask = np.ones_like(image, dtype=np.uint8) + image[2,2] = 255 + image[2,3] = 128 + image[1,2] = 16 + + elem = np.array([[0, 0, 0], [0, 1, 0],[0, 0, 0]], dtype=np.uint8) + _crank8.mean(image=image, selem=elem, out=out, mask=mask, + shift_x=0, shift_y=0) + assert_array_equal(image, out) + _crank8.minimum(image=image, selem=elem, out=out, mask=mask, + shift_x=0, shift_y=0) + assert_array_equal(image, out) + _crank8.maximum(image=image, selem=elem, out=out, mask=mask, + shift_x=0, shift_y=0) + assert_array_equal(image, out) + + +def test_trivial_selem16(): + # check that min, max and mean returns identity if structuring element + # contains only central pixel + + image = np.zeros((5, 5), dtype=np.uint16) + out = np.zeros_like(image) + mask = np.ones_like(image, dtype=np.uint8) + image[2,2] = 255 + image[2,3] = 128 + image[1,2] = 16 + + elem = np.array([[0, 0, 0], [0, 1, 0],[0, 0, 0]], dtype=np.uint8) + _crank16.mean(image=image, selem=elem, out=out, mask=mask, + shift_x=0, shift_y=0) + assert_array_equal(image, out) + _crank16.minimum(image=image, selem=elem, out=out, mask=mask, + shift_x=0, shift_y=0) + assert_array_equal(image, out) + _crank16.maximum(image=image, selem=elem, out=out, mask=mask, + shift_x=0, shift_y=0) + assert_array_equal(image, out) + + +def test_smallest_selem8(): + # check that min, max and mean returns identity if structuring element + # contains only central pixel + + image = np.zeros((5, 5), dtype=np.uint8) + out = np.zeros_like(image) + mask = np.ones_like(image, dtype=np.uint8) + image[2,2] = 255 + image[2,3] = 128 + image[1,2] = 16 + + elem = np.array([[1]], dtype=np.uint8) + _crank8.mean(image=image, selem=elem, out=out, mask=mask, + shift_x=0, shift_y=0) + assert_array_equal(image, out) + _crank8.minimum(image=image, selem=elem, out=out, mask=mask, + shift_x=0, shift_y=0) + assert_array_equal(image, out) + _crank8.maximum(image=image, selem=elem, out=out, mask=mask, + shift_x=0, shift_y=0) + assert_array_equal(image, out) + + +def test_smallest_selem16(): + # check that min, max and mean returns identity if structuring element + # contains only central pixel + + image = np.zeros((5, 5), dtype=np.uint16) + out = np.zeros_like(image) + mask = np.ones_like(image, dtype=np.uint8) + image[2,2] = 255 + image[2,3] = 128 + image[1,2] = 16 + + elem = np.array([[1]], dtype=np.uint8) + _crank16.mean(image=image, selem=elem, out=out, mask=mask, + shift_x=0, shift_y=0) + assert_array_equal(image, out) + _crank16.minimum(image=image, selem=elem, out=out, mask=mask, + shift_x=0, shift_y=0) + assert_array_equal(image, out) + _crank16.maximum(image=image, selem=elem, out=out, mask=mask, + shift_x=0, shift_y=0) + assert_array_equal(image, out) + + if __name__ == "__main__": run_module_suite() From 8fea5d15d1900df7cfb36e8a1b65d07b2fbe65ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Sch=C3=B6nberger?= Date: Sat, 10 Nov 2012 13:49:52 +0100 Subject: [PATCH 12/12] Change data type of pop variable to float --- skimage/filter/rank/_core16.pxd | 2 +- skimage/filter/rank/_core16.pyx | 8 ++--- skimage/filter/rank/_core8.pxd | 2 +- skimage/filter/rank/_core8.pyx | 8 ++--- skimage/filter/rank/_crank16.pyx | 30 ++++++++--------- skimage/filter/rank/_crank16_bilateral.pyx | 4 +-- skimage/filter/rank/_crank16_percentiles.pyx | 16 ++++----- skimage/filter/rank/_crank8.pyx | 34 ++++++++++---------- skimage/filter/rank/_crank8_percentiles.pyx | 16 ++++----- 9 files changed, 60 insertions(+), 60 deletions(-) diff --git a/skimage/filter/rank/_core16.pxd b/skimage/filter/rank/_core16.pxd index f6f85202..92c6f7d6 100644 --- a/skimage/filter/rank/_core16.pxd +++ b/skimage/filter/rank/_core16.pxd @@ -6,7 +6,7 @@ cdef int int_min(int a, int b) # 16 bit core kernel receives extra information about data bitdepth -cdef void _core16(np.uint16_t kernel(Py_ssize_t *, Py_ssize_t, np.uint16_t, +cdef void _core16(np.uint16_t kernel(Py_ssize_t *, float, np.uint16_t, Py_ssize_t, Py_ssize_t, Py_ssize_t, float, float, Py_ssize_t, Py_ssize_t), np.ndarray[np.uint16_t, ndim=2] image, diff --git a/skimage/filter/rank/_core16.pyx b/skimage/filter/rank/_core16.pyx index 79fefe2b..d3715f47 100644 --- a/skimage/filter/rank/_core16.pyx +++ b/skimage/filter/rank/_core16.pyx @@ -17,19 +17,19 @@ cdef inline int int_min(int a, int b): return a if a <= b else b -cdef inline void histogram_increment(Py_ssize_t * histo, Py_ssize_t * pop, +cdef inline void histogram_increment(Py_ssize_t * histo, float * pop, np.uint16_t value): histo[value] += 1 pop[0] += 1 -cdef inline void histogram_decrement(Py_ssize_t * histo, Py_ssize_t * pop, +cdef inline void histogram_decrement(Py_ssize_t * histo, float * pop, np.uint16_t value): histo[value] -= 1 pop[0] -= 1 -cdef void _core16(np.uint16_t kernel(Py_ssize_t *, Py_ssize_t, np.uint16_t, +cdef void _core16(np.uint16_t kernel(Py_ssize_t *, float, np.uint16_t, Py_ssize_t, Py_ssize_t, Py_ssize_t, float, float, Py_ssize_t, Py_ssize_t), np.ndarray[np.uint16_t, ndim=2] image, @@ -74,7 +74,7 @@ cdef void _core16(np.uint16_t kernel(Py_ssize_t *, Py_ssize_t, np.uint16_t, # define local variable types cdef Py_ssize_t r, c, rr, cc, s, value, local_max, i, even_row # number of pixels actually inside the neighborhood (float) - cdef Py_ssize_t pop + cdef float pop # allocate memory with malloc cdef Py_ssize_t max_se = srows * scols diff --git a/skimage/filter/rank/_core8.pxd b/skimage/filter/rank/_core8.pxd index 08391eaf..503d2df0 100644 --- a/skimage/filter/rank/_core8.pxd +++ b/skimage/filter/rank/_core8.pxd @@ -12,7 +12,7 @@ cdef np.uint8_t is_in_mask(Py_ssize_t rows, Py_ssize_t cols, # 8 bit core kernel receives extra information about data inferior and superior # percentiles -cdef void _core8(np.uint8_t kernel(Py_ssize_t *, Py_ssize_t, np.uint8_t, float, +cdef void _core8(np.uint8_t kernel(Py_ssize_t *, float, np.uint8_t, float, float, Py_ssize_t, Py_ssize_t), np.ndarray[np.uint8_t, ndim=2] image, np.ndarray[np.uint8_t, ndim=2] selem, diff --git a/skimage/filter/rank/_core8.pyx b/skimage/filter/rank/_core8.pyx index 3dabe9ec..cfb011ac 100644 --- a/skimage/filter/rank/_core8.pyx +++ b/skimage/filter/rank/_core8.pyx @@ -16,13 +16,13 @@ cdef inline np.uint8_t uint8_min(np.uint8_t a, np.uint8_t b): return a if a <= b else b -cdef inline void histogram_increment(Py_ssize_t * histo, Py_ssize_t * pop, +cdef inline void histogram_increment(Py_ssize_t * histo, float * pop, np.uint8_t value): histo[value] += 1 pop[0] += 1 -cdef inline void histogram_decrement(Py_ssize_t * histo, Py_ssize_t * pop, +cdef inline void histogram_decrement(Py_ssize_t * histo, float * pop, np.uint8_t value): histo[value] -= 1 pop[0] -= 1 @@ -41,7 +41,7 @@ cdef inline np.uint8_t is_in_mask(Py_ssize_t rows, Py_ssize_t cols, return 0 -cdef void _core8(np.uint8_t kernel(Py_ssize_t *, Py_ssize_t, np.uint8_t, float, +cdef void _core8(np.uint8_t kernel(Py_ssize_t *, float, np.uint8_t, float, float, Py_ssize_t, Py_ssize_t), np.ndarray[np.uint8_t, ndim=2] image, np.ndarray[np.uint8_t, ndim=2] selem, @@ -77,7 +77,7 @@ cdef void _core8(np.uint8_t kernel(Py_ssize_t *, Py_ssize_t, np.uint8_t, float, cdef Py_ssize_t r, c, rr, cc, s, value, local_max, i, even_row # number of pixels actually inside the neighborhood (float) - cdef Py_ssize_t pop + cdef float pop # allocate memory with malloc cdef Py_ssize_t max_se = srows * scols diff --git a/skimage/filter/rank/_crank16.pyx b/skimage/filter/rank/_crank16.pyx index 9c4b8fe1..ce300cdd 100644 --- a/skimage/filter/rank/_crank16.pyx +++ b/skimage/filter/rank/_crank16.pyx @@ -14,7 +14,7 @@ from skimage.filter.rank._core16 cimport _core16 # ----------------------------------------------------------------- -cdef inline np.uint16_t kernel_autolevel(Py_ssize_t * histo, Py_ssize_t pop, +cdef inline np.uint16_t kernel_autolevel(Py_ssize_t * histo, float pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, @@ -37,7 +37,7 @@ cdef inline np.uint16_t kernel_autolevel(Py_ssize_t * histo, Py_ssize_t pop, return (imax - imin) -cdef inline np.uint16_t kernel_bottomhat(Py_ssize_t * histo, Py_ssize_t pop, +cdef inline np.uint16_t kernel_bottomhat(Py_ssize_t * histo, float pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, @@ -51,7 +51,7 @@ cdef inline np.uint16_t kernel_bottomhat(Py_ssize_t * histo, Py_ssize_t pop, return (g - i) -cdef inline np.uint16_t kernel_equalize(Py_ssize_t * histo, Py_ssize_t pop, +cdef inline np.uint16_t kernel_equalize(Py_ssize_t * histo, float pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, @@ -70,7 +70,7 @@ cdef inline np.uint16_t kernel_equalize(Py_ssize_t * histo, Py_ssize_t pop, return (0) -cdef inline np.uint16_t kernel_gradient(Py_ssize_t * histo, Py_ssize_t pop, +cdef inline np.uint16_t kernel_gradient(Py_ssize_t * histo, float pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, @@ -91,7 +91,7 @@ cdef inline np.uint16_t kernel_gradient(Py_ssize_t * histo, Py_ssize_t pop, return (0) -cdef inline np.uint16_t kernel_maximum(Py_ssize_t * histo, Py_ssize_t pop, +cdef inline np.uint16_t kernel_maximum(Py_ssize_t * histo, float pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, @@ -106,7 +106,7 @@ cdef inline np.uint16_t kernel_maximum(Py_ssize_t * histo, Py_ssize_t pop, return (0) -cdef inline np.uint16_t kernel_mean(Py_ssize_t * histo, Py_ssize_t pop, +cdef inline np.uint16_t kernel_mean(Py_ssize_t * histo, float pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, @@ -123,7 +123,7 @@ cdef inline np.uint16_t kernel_mean(Py_ssize_t * histo, Py_ssize_t pop, cdef inline np.uint16_t kernel_meansubstraction(Py_ssize_t * histo, - Py_ssize_t pop, + float pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, @@ -141,7 +141,7 @@ cdef inline np.uint16_t kernel_meansubstraction(Py_ssize_t * histo, return (0) -cdef inline np.uint16_t kernel_median(Py_ssize_t * histo, Py_ssize_t pop, +cdef inline np.uint16_t kernel_median(Py_ssize_t * histo, float pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, @@ -159,7 +159,7 @@ cdef inline np.uint16_t kernel_median(Py_ssize_t * histo, Py_ssize_t pop, return (0) -cdef inline np.uint16_t kernel_minimum(Py_ssize_t * histo, Py_ssize_t pop, +cdef inline np.uint16_t kernel_minimum(Py_ssize_t * histo, float pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, @@ -174,7 +174,7 @@ cdef inline np.uint16_t kernel_minimum(Py_ssize_t * histo, Py_ssize_t pop, return (0) -cdef inline np.uint16_t kernel_modal(Py_ssize_t * histo, Py_ssize_t pop, +cdef inline np.uint16_t kernel_modal(Py_ssize_t * histo, float pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, @@ -192,7 +192,7 @@ cdef inline np.uint16_t kernel_modal(Py_ssize_t * histo, Py_ssize_t pop, cdef inline np.uint16_t kernel_morph_contr_enh(Py_ssize_t * histo, - Py_ssize_t pop, + float pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, @@ -218,7 +218,7 @@ cdef inline np.uint16_t kernel_morph_contr_enh(Py_ssize_t * histo, return (0) -cdef inline np.uint16_t kernel_pop(Py_ssize_t * histo, Py_ssize_t pop, +cdef inline np.uint16_t kernel_pop(Py_ssize_t * histo, float pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, @@ -226,7 +226,7 @@ cdef inline np.uint16_t kernel_pop(Py_ssize_t * histo, Py_ssize_t pop, return (pop) -cdef inline np.uint16_t kernel_threshold(Py_ssize_t * histo, Py_ssize_t pop, +cdef inline np.uint16_t kernel_threshold(Py_ssize_t * histo, float pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, @@ -242,7 +242,7 @@ cdef inline np.uint16_t kernel_threshold(Py_ssize_t * histo, Py_ssize_t pop, return (0) -cdef inline np.uint16_t kernel_tophat(Py_ssize_t * histo, Py_ssize_t pop, +cdef inline np.uint16_t kernel_tophat(Py_ssize_t * histo, float pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, @@ -256,7 +256,7 @@ cdef inline np.uint16_t kernel_tophat(Py_ssize_t * histo, Py_ssize_t pop, return (i - g) -cdef inline np.uint16_t kernel_entropy(Py_ssize_t * histo, Py_ssize_t pop, +cdef inline np.uint16_t kernel_entropy(Py_ssize_t * histo, float pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, diff --git a/skimage/filter/rank/_crank16_bilateral.pyx b/skimage/filter/rank/_crank16_bilateral.pyx index 98bc5683..1fb81a2d 100644 --- a/skimage/filter/rank/_crank16_bilateral.pyx +++ b/skimage/filter/rank/_crank16_bilateral.pyx @@ -13,7 +13,7 @@ from skimage.filter.rank._core16 cimport _core16 # ----------------------------------------------------------------- -cdef inline np.uint16_t kernel_mean(Py_ssize_t * histo, Py_ssize_t pop, +cdef inline np.uint16_t kernel_mean(Py_ssize_t * histo, float pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, @@ -35,7 +35,7 @@ cdef inline np.uint16_t kernel_mean(Py_ssize_t * histo, Py_ssize_t pop, return (0) -cdef inline np.uint16_t kernel_pop(Py_ssize_t * histo, Py_ssize_t pop, +cdef inline np.uint16_t kernel_pop(Py_ssize_t * histo, float pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, diff --git a/skimage/filter/rank/_crank16_percentiles.pyx b/skimage/filter/rank/_crank16_percentiles.pyx index e5dc2ab7..8b45d46a 100644 --- a/skimage/filter/rank/_crank16_percentiles.pyx +++ b/skimage/filter/rank/_crank16_percentiles.pyx @@ -13,7 +13,7 @@ from skimage.filter.rank._core16 cimport _core16, int_min, int_max # ----------------------------------------------------------------- -cdef inline np.uint16_t kernel_autolevel(Py_ssize_t * histo, Py_ssize_t pop, +cdef inline np.uint16_t kernel_autolevel(Py_ssize_t * histo, float pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, @@ -46,7 +46,7 @@ cdef inline np.uint16_t kernel_autolevel(Py_ssize_t * histo, Py_ssize_t pop, return (0) -cdef inline np.uint16_t kernel_gradient(Py_ssize_t * histo, Py_ssize_t pop, +cdef inline np.uint16_t kernel_gradient(Py_ssize_t * histo, float pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, @@ -74,7 +74,7 @@ cdef inline np.uint16_t kernel_gradient(Py_ssize_t * histo, Py_ssize_t pop, return (0) -cdef inline np.uint16_t kernel_mean(Py_ssize_t * histo, Py_ssize_t pop, +cdef inline np.uint16_t kernel_mean(Py_ssize_t * histo, float pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, @@ -101,7 +101,7 @@ cdef inline np.uint16_t kernel_mean(Py_ssize_t * histo, Py_ssize_t pop, cdef inline np.uint16_t kernel_mean_substraction(Py_ssize_t * histo, - Py_ssize_t pop, + float pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, @@ -129,7 +129,7 @@ cdef inline np.uint16_t kernel_mean_substraction(Py_ssize_t * histo, cdef inline np.uint16_t kernel_morph_contr_enh(Py_ssize_t * histo, - Py_ssize_t pop, + float pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, @@ -165,7 +165,7 @@ cdef inline np.uint16_t kernel_morph_contr_enh(Py_ssize_t * histo, return (0) -cdef inline np.uint16_t kernel_percentile(Py_ssize_t * histo, Py_ssize_t pop, +cdef inline np.uint16_t kernel_percentile(Py_ssize_t * histo, float pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, @@ -185,7 +185,7 @@ cdef inline np.uint16_t kernel_percentile(Py_ssize_t * histo, Py_ssize_t pop, return (0) -cdef inline np.uint16_t kernel_pop(Py_ssize_t * histo, Py_ssize_t pop, +cdef inline np.uint16_t kernel_pop(Py_ssize_t * histo, float pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, @@ -205,7 +205,7 @@ cdef inline np.uint16_t kernel_pop(Py_ssize_t * histo, Py_ssize_t pop, return (0) -cdef inline np.uint16_t kernel_threshold(Py_ssize_t * histo, Py_ssize_t pop, +cdef inline np.uint16_t kernel_threshold(Py_ssize_t * histo, float pop, np.uint16_t g, Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, float p0, float p1, diff --git a/skimage/filter/rank/_crank8.pyx b/skimage/filter/rank/_crank8.pyx index 6fee8a9f..7398b26f 100644 --- a/skimage/filter/rank/_crank8.pyx +++ b/skimage/filter/rank/_crank8.pyx @@ -14,7 +14,7 @@ from skimage.filter.rank._core8 cimport _core8 # ----------------------------------------------------------------- -cdef inline np.uint8_t kernel_autolevel(Py_ssize_t * histo, Py_ssize_t pop, +cdef inline np.uint8_t kernel_autolevel(Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): @@ -38,7 +38,7 @@ cdef inline np.uint8_t kernel_autolevel(Py_ssize_t * histo, Py_ssize_t pop, return (0) -cdef inline np.uint8_t kernel_bottomhat(Py_ssize_t * histo, Py_ssize_t pop, +cdef inline np.uint8_t kernel_bottomhat(Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): @@ -51,7 +51,7 @@ cdef inline np.uint8_t kernel_bottomhat(Py_ssize_t * histo, Py_ssize_t pop, return (g - i) -cdef inline np.uint8_t kernel_equalize(Py_ssize_t * histo, Py_ssize_t pop, +cdef inline np.uint8_t kernel_equalize(Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): @@ -69,7 +69,7 @@ cdef inline np.uint8_t kernel_equalize(Py_ssize_t * histo, Py_ssize_t pop, return (0) -cdef inline np.uint8_t kernel_gradient(Py_ssize_t * histo, Py_ssize_t pop, +cdef inline np.uint8_t kernel_gradient(Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): @@ -89,7 +89,7 @@ cdef inline np.uint8_t kernel_gradient(Py_ssize_t * histo, Py_ssize_t pop, return (0) -cdef inline np.uint8_t kernel_maximum(Py_ssize_t * histo, Py_ssize_t pop, +cdef inline np.uint8_t kernel_maximum(Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): @@ -103,7 +103,7 @@ cdef inline np.uint8_t kernel_maximum(Py_ssize_t * histo, Py_ssize_t pop, return (0) -cdef inline np.uint8_t kernel_mean(Py_ssize_t * histo, Py_ssize_t pop, +cdef inline np.uint8_t kernel_mean(Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): @@ -118,7 +118,7 @@ cdef inline np.uint8_t kernel_mean(Py_ssize_t * histo, Py_ssize_t pop, return (0) -cdef inline np.uint8_t kernel_meansubstraction(Py_ssize_t * histo, Py_ssize_t pop, +cdef inline np.uint8_t kernel_meansubstraction(Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): @@ -133,7 +133,7 @@ cdef inline np.uint8_t kernel_meansubstraction(Py_ssize_t * histo, Py_ssize_t po return (0) -cdef inline np.uint8_t kernel_median(Py_ssize_t * histo, Py_ssize_t pop, +cdef inline np.uint8_t kernel_median(Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): @@ -150,7 +150,7 @@ cdef inline np.uint8_t kernel_median(Py_ssize_t * histo, Py_ssize_t pop, return (0) -cdef inline np.uint8_t kernel_minimum(Py_ssize_t * histo, Py_ssize_t pop, +cdef inline np.uint8_t kernel_minimum(Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): @@ -164,7 +164,7 @@ cdef inline np.uint8_t kernel_minimum(Py_ssize_t * histo, Py_ssize_t pop, return (0) -cdef inline np.uint8_t kernel_modal(Py_ssize_t * histo, Py_ssize_t pop, +cdef inline np.uint8_t kernel_modal(Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): @@ -180,7 +180,7 @@ cdef inline np.uint8_t kernel_modal(Py_ssize_t * histo, Py_ssize_t pop, return (0) -cdef inline np.uint8_t kernel_morph_contr_enh(Py_ssize_t * histo, Py_ssize_t pop, +cdef inline np.uint8_t kernel_morph_contr_enh(Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): @@ -203,14 +203,14 @@ cdef inline np.uint8_t kernel_morph_contr_enh(Py_ssize_t * histo, Py_ssize_t pop return (0) -cdef inline np.uint8_t kernel_pop(Py_ssize_t * histo, Py_ssize_t pop, +cdef inline np.uint8_t kernel_pop(Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): return (pop) -cdef inline np.uint8_t kernel_threshold(Py_ssize_t * histo, Py_ssize_t pop, +cdef inline np.uint8_t kernel_threshold(Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): @@ -225,7 +225,7 @@ cdef inline np.uint8_t kernel_threshold(Py_ssize_t * histo, Py_ssize_t pop, return (0) -cdef inline np.uint8_t kernel_tophat(Py_ssize_t * histo, Py_ssize_t pop, +cdef inline np.uint8_t kernel_tophat(Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): @@ -238,7 +238,7 @@ cdef inline np.uint8_t kernel_tophat(Py_ssize_t * histo, Py_ssize_t pop, return (i - g) -cdef inline np.uint8_t kernel_noise_filter(Py_ssize_t * histo, Py_ssize_t pop, +cdef inline np.uint8_t kernel_noise_filter(Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): @@ -262,7 +262,7 @@ cdef inline np.uint8_t kernel_noise_filter(Py_ssize_t * histo, Py_ssize_t pop, return min_i -cdef inline np.uint8_t kernel_entropy(Py_ssize_t * histo, Py_ssize_t pop, +cdef inline np.uint8_t kernel_entropy(Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i @@ -278,7 +278,7 @@ cdef inline np.uint8_t kernel_entropy(Py_ssize_t * histo, Py_ssize_t pop, return e*10 -cdef inline np.uint8_t kernel_otsu(Py_ssize_t * histo, Py_ssize_t pop, np.uint8_t g, +cdef inline np.uint8_t kernel_otsu(Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): cdef Py_ssize_t i diff --git a/skimage/filter/rank/_crank8_percentiles.pyx b/skimage/filter/rank/_crank8_percentiles.pyx index 4a11bdc4..d5072c81 100644 --- a/skimage/filter/rank/_crank8_percentiles.pyx +++ b/skimage/filter/rank/_crank8_percentiles.pyx @@ -13,7 +13,7 @@ from skimage.filter.rank._core8 cimport _core8, uint8_max, uint8_min # ----------------------------------------------------------------- -cdef inline np.uint8_t kernel_autolevel(Py_ssize_t * histo, Py_ssize_t pop, +cdef inline np.uint8_t kernel_autolevel(Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): cdef int i, imin, imax, sum, delta @@ -45,7 +45,7 @@ cdef inline np.uint8_t kernel_autolevel(Py_ssize_t * histo, Py_ssize_t pop, return (128) -cdef inline np.uint8_t kernel_gradient(Py_ssize_t * histo, Py_ssize_t pop, +cdef inline np.uint8_t kernel_gradient(Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): cdef int i, imin, imax, sum, delta @@ -70,7 +70,7 @@ cdef inline np.uint8_t kernel_gradient(Py_ssize_t * histo, Py_ssize_t pop, return (0) -cdef inline np.uint8_t kernel_mean(Py_ssize_t * histo, Py_ssize_t pop, +cdef inline np.uint8_t kernel_mean(Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): cdef int i, sum, mean, n @@ -93,7 +93,7 @@ cdef inline np.uint8_t kernel_mean(Py_ssize_t * histo, Py_ssize_t pop, cdef inline np.uint8_t kernel_mean_substraction(Py_ssize_t * histo, - Py_ssize_t pop, + float pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): @@ -117,7 +117,7 @@ cdef inline np.uint8_t kernel_mean_substraction(Py_ssize_t * histo, cdef inline np.uint8_t kernel_morph_contr_enh(Py_ssize_t * histo, - Py_ssize_t pop, + float pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): cdef int i, imin, imax, sum, delta @@ -148,7 +148,7 @@ cdef inline np.uint8_t kernel_morph_contr_enh(Py_ssize_t * histo, return (0) -cdef inline np.uint8_t kernel_percentile(Py_ssize_t * histo, Py_ssize_t pop, +cdef inline np.uint8_t kernel_percentile(Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): cdef int i @@ -165,7 +165,7 @@ cdef inline np.uint8_t kernel_percentile(Py_ssize_t * histo, Py_ssize_t pop, return (0) -cdef inline np.uint8_t kernel_pop(Py_ssize_t * histo, Py_ssize_t pop, +cdef inline np.uint8_t kernel_pop(Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): cdef int i, sum, n @@ -182,7 +182,7 @@ cdef inline np.uint8_t kernel_pop(Py_ssize_t * histo, Py_ssize_t pop, return (0) -cdef inline np.uint8_t kernel_threshold(Py_ssize_t * histo, Py_ssize_t pop, +cdef inline np.uint8_t kernel_threshold(Py_ssize_t * histo, float pop, np.uint8_t g, float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): cdef int i