From 9079d004bbd55058546e2f3c76337c2ff6fb9131 Mon Sep 17 00:00:00 2001 From: Olivier Debeir Date: Mon, 15 Oct 2012 16:46:41 +0200 Subject: [PATCH] grou rank16 and rank16b, remove core16b --- skimage/rank/_core16b.pxd | 12 -- skimage/rank/_core16b.pyx | 284 ---------------------------- skimage/rank/_crank16_bilateral.pyx | 10 +- skimage/rank/setup.py | 3 - skimage/rank/tests/test_suite.py | 9 + 5 files changed, 14 insertions(+), 304 deletions(-) delete mode 100644 skimage/rank/_core16b.pxd delete mode 100644 skimage/rank/_core16b.pyx diff --git a/skimage/rank/_core16b.pxd b/skimage/rank/_core16b.pxd deleted file mode 100644 index b972ae9a..00000000 --- a/skimage/rank/_core16b.pxd +++ /dev/null @@ -1,12 +0,0 @@ -cimport numpy as np - -#--------------------------------------------------------------------------- -# 16 bit core kernel receives extra information about data bitdepth and bilateral interval -#--------------------------------------------------------------------------- - -cdef inline _core16b(np.uint16_t kernel(int*, float, np.uint16_t, int ,int,int,int,int), -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,int bitdepth, int s0, int s1) \ No newline at end of file diff --git a/skimage/rank/_core16b.pyx b/skimage/rank/_core16b.pyx deleted file mode 100644 index 163662b5..00000000 --- a/skimage/rank/_core16b.pyx +++ /dev/null @@ -1,284 +0,0 @@ -""" to compile this use: ->>> python setup.py build_ext --inplace - -to generate html report use: ->>> cython -a core16b.pxd -""" - -#cython: cdivision=True -#cython: boundscheck=False -#cython: nonecheck=False -#cython: wraparound=False - -import numpy as np -cimport numpy as np -from libc.stdlib cimport malloc, free - -#--------------------------------------------------------------------------- -# 16 bit core kernel receives extra information about data bitdepth and bilateral interval -#--------------------------------------------------------------------------- - -cdef inline _core16b(np.uint16_t kernel(int*, float, np.uint16_t, int ,int,int,int,int), -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,int bitdepth, int s0, int s1): - """ Main loop, this function computes the histogram for each image point - - data is uint8 - - result is uint8 casted - - only pixel inside [s0,s1] centered on g are taken into account - """ - - cdef int rows = image.shape[0] - cdef int cols = image.shape[1] - cdef int srows = selem.shape[0] - cdef int scols = selem.shape[1] - - cdef int centre_r = int(selem.shape[0] / 2) + shift_y - cdef int centre_c = int(selem.shape[1] / 2) + shift_x - - # check that structuring element center is inside the element bounding box - assert centre_r >= 0 - assert centre_c >= 0 - assert centre_r < srows - assert centre_c < scols - assert bitdepth in range(2,13) - - 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 - cdef int maxbin=maxbin_list[bitdepth],midbin=midbin_list[bitdepth] - - assert (imageeimage.data - cdef np.uint8_t* emask_data = emask.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 int r, c, rr, cc, s, value, local_max, i, even_row - cdef float pop # number of pixels actually inside the neighborhood (float) - - # allocate memory with malloc - cdef int max_se = srows*scols - - # number of element in each attack border - cdef int num_se_n, num_se_s, num_se_e, num_se_w - - # the current local histogram distribution - cdef int* histo = malloc(maxbin * sizeof(int)) - - # 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 int* se_e_r = malloc(max_se * sizeof(int)) - cdef int* se_e_c = malloc(max_se * sizeof(int)) - cdef int* se_w_r = malloc(max_se * sizeof(int)) - cdef int* se_w_c = malloc(max_se * sizeof(int)) - cdef int* se_n_r = malloc(max_se * sizeof(int)) - cdef int* se_n_c = malloc(max_se * sizeof(int)) - cdef int* se_s_r = malloc(max_se * sizeof(int)) - cdef int* se_s_c = malloc(max_se * sizeof(int)) - - # 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 - - t = np.hstack((np.zeros((selem.shape[0],1)),selem)) - t_w = np.diff(t,axis=1)==1 - - t = np.vstack((selem,np.zeros((1,selem.shape[1])))) - t_s = np.diff(t,axis=0)==-1 - - t = np.vstack((np.zeros((1,selem.shape[1])),selem)) - t_n = np.diff(t,axis=0)==1 - - num_se_n = num_se_s = num_se_e = num_se_w = 0 - - for r in range(srows): - for c in range(scols): - if t_e[r,c]: - se_e_r[num_se_e] = r - centre_r - se_e_c[num_se_e] = c - centre_c - num_se_e += 1 - if t_w[r,c]: - se_w_r[num_se_w] = r - centre_r - se_w_c[num_se_w] = c - centre_c - num_se_w += 1 - if t_n[r,c]: - se_n_r[num_se_n] = r - centre_r - se_n_c[num_se_n] = c - centre_c - num_se_n += 1 - if t_s[r,c]: - se_s_r[num_se_s] = r - centre_r - se_s_c[num_se_s] = c - centre_c - num_se_s += 1 - - # initial population and histogram - for i in range(maxbin): - histo[i] = 0 - - pop = 0 - - for r in range(srows): - for c in range(scols): - rr = r - cc = c - if selem[r, c]: - if emask_data[rr * ecols + cc]: - value = eimage_data[rr * ecols + cc] - histo[value] += 1 - pop += 1. - - r = 0 - c = 0 - # kernel ------------------------------------------- - out_data[r * cols + c] = kernel(histo,pop,eimage_data[(r+centre_r) * ecols + c + centre_c], - bitdepth,maxbin,midbin,s0,s1) - # kernel ------------------------------------------- - - # main loop - r = 0 - for even_row in range(0,rows,2): - # ---> west to east - for c in range(1,cols): - for s in range(num_se_e): - rr = r + se_e_r[s] + centre_r - cc = c + se_e_c[s] + centre_c - if emask_data[rr * ecols + cc]: - value = eimage_data[rr * ecols + cc] - histo[value] += 1 - pop += 1. - for s in range(num_se_w): - rr = r + se_w_r[s] + centre_r - cc = c + se_w_c[s] + centre_c - 1 - if emask_data[rr * ecols + cc]: - value = eimage_data[rr * ecols + cc] - histo[value] -= 1 - pop -= 1. - - # kernel ------------------------------------------- - out_data[r * cols + c] = kernel(histo,pop,eimage_data[(r+centre_r) * ecols + c + centre_c], - bitdepth,maxbin,midbin,s0,s1) - # kernel ------------------------------------------- - - r += 1 # pass to the next row - if r>=rows: - break - - # ---> north to south - for s in range(num_se_s): - rr = r + se_s_r[s] + centre_r - cc = c + se_s_c[s] + centre_c - if emask_data[rr * ecols + cc]: - value = eimage_data[rr * ecols + cc] - histo[value] += 1 - pop += 1. - for s in range(num_se_n): - rr = r + se_n_r[s] + centre_r - 1 - cc = c + se_n_c[s] + centre_c - if emask_data[rr * ecols + cc]: - value = eimage_data[rr * ecols + cc] - histo[value] -= 1 - pop -= 1. - - # kernel ------------------------------------------- - out_data[r * cols + c] = kernel(histo,pop,eimage_data[(r+centre_r) * ecols + c + centre_c], - bitdepth,maxbin,midbin,s0,s1) - # kernel ------------------------------------------- - - # ---> east to west - for c in range(cols-2,-1,-1): - for s in range(num_se_w): - rr = r + se_w_r[s] + centre_r - cc = c + se_w_c[s] + centre_c - if emask_data[rr * ecols + cc]: - value = eimage_data[rr * ecols + cc] - histo[value] += 1 - pop += 1. - for s in range(num_se_e): - rr = r + se_e_r[s] + centre_r - cc = c + se_e_c[s] + centre_c + 1 - if emask_data[rr * ecols + cc]: - value = eimage_data[rr * ecols + cc] - histo[value] -= 1 - pop -= 1. - - # kernel ------------------------------------------- - out_data[r * cols + c] = kernel(histo,pop,eimage_data[(r+centre_r) * ecols + c + centre_c], - bitdepth,maxbin,midbin,s0,s1) - # kernel ------------------------------------------- - - r += 1 # pass to the next row - if r>=rows: - break - - # ---> north to south - for s in range(num_se_s): - rr = r + se_s_r[s] + centre_r - cc = c + se_s_c[s] + centre_c - if emask_data[rr * ecols + cc]: - value = eimage_data[rr * ecols + cc] - histo[value] += 1 - pop += 1. - for s in range(num_se_n): - rr = r + se_n_r[s] + centre_r - 1 - cc = c + se_n_c[s] + centre_c - if emask_data[rr * ecols + cc]: - value = eimage_data[rr * ecols + cc] - histo[value] -= 1 - pop -= 1. - - # kernel ------------------------------------------- - out_data[r * cols + c] = kernel(histo,pop,eimage_data[(r+centre_r) * ecols + c + centre_c], - bitdepth,maxbin,midbin,s0,s1) - # kernel ------------------------------------------- - - # release memory allocated by malloc - - free(se_e_r) - free(se_e_c) - free(se_w_r) - free(se_w_c) - free(se_n_r) - free(se_n_c) - free(se_s_r) - free(se_s_c) - - free(histo) - - return out diff --git a/skimage/rank/_crank16_bilateral.pyx b/skimage/rank/_crank16_bilateral.pyx index e783d7ea..46028ad3 100644 --- a/skimage/rank/_crank16_bilateral.pyx +++ b/skimage/rank/_crank16_bilateral.pyx @@ -15,14 +15,14 @@ import numpy as np cimport numpy as np # import main loop -from _core16b cimport _core16b +from _core16 cimport _core16 # ----------------------------------------------------------------- # kernels uint16 take extra parameter for defining the bitdepth # ----------------------------------------------------------------- -cdef inline np.uint16_t kernel_mean(int* histo, float pop, np.uint16_t g,int bitdepth,int maxbin, int midbin, int s0, int 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. @@ -39,7 +39,7 @@ cdef inline np.uint16_t kernel_mean(int* histo, float pop, np.uint16_t g,int bit return (0) -cdef inline np.uint16_t kernel_pop(int* histo, float pop, np.uint16_t g,int bitdepth,int maxbin, int midbin, int s0, int 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 if pop: @@ -61,7 +61,7 @@ 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 _core16b(kernel_mean,image,selem,mask,out,shift_x,shift_y,bitdepth,s0,s1) + return _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, @@ -71,5 +71,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 _core16b(kernel_pop,image,selem,mask,out,shift_x,shift_y,bitdepth,s0,s1) + return _core16(kernel_pop,image,selem,mask,out,shift_x,shift_y,bitdepth,.0,.0,s0,s1) diff --git a/skimage/rank/setup.py b/skimage/rank/setup.py index b7cac4dc..e1f996f7 100644 --- a/skimage/rank/setup.py +++ b/skimage/rank/setup.py @@ -14,7 +14,6 @@ def configuration(parent_package='', top_path=None): cython(['_core8.pyx'], working_path=base_path) cython(['_core16.pyx'], working_path=base_path) - cython(['_core16b.pyx'], working_path=base_path) cython(['_crank8.pyx'], working_path=base_path) cython(['_crank8_percentiles.pyx'], working_path=base_path) cython(['_crank16.pyx'], working_path=base_path) @@ -25,8 +24,6 @@ def configuration(parent_package='', top_path=None): include_dirs=[get_numpy_include_dirs()]) config.add_extension('_core16', sources=['_core16.c'], include_dirs=[get_numpy_include_dirs()]) - config.add_extension('_core16b', sources=['_core16b.c'], - include_dirs=[get_numpy_include_dirs()]) config.add_extension('_crank8', sources=['_crank8.c'], include_dirs=[get_numpy_include_dirs()]) config.add_extension('_crank8_percentiles', sources=['_crank8_percentiles.c'], diff --git a/skimage/rank/tests/test_suite.py b/skimage/rank/tests/test_suite.py index 0887fa8f..e7d2436b 100644 --- a/skimage/rank/tests/test_suite.py +++ b/skimage/rank/tests/test_suite.py @@ -104,6 +104,15 @@ class TestSequenceFunctions(unittest.TestCase): assert (loc_autolevel==loc_perc_autolevel).all() + def test_compare_autolevels_16bit(self): + image = data.camera().astype(np.uint16) + + 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()