Improve overall code style

This commit is contained in:
Johannes Schönberger
2012-11-09 19:39:30 +01:00
parent 0737cc4220
commit 4a14a217b9
12 changed files with 812 additions and 705 deletions
+11 -12
View File
@@ -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)
+48 -77
View File
@@ -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 = <np.uint16_t * >out.data
cdef np.uint16_t * image_data = <np.uint16_t * >image.data
cdef np.uint8_t * mask_data = <np.uint8_t * >mask.data
cdef np.uint16_t * out_data = <np.uint16_t*>out.data
cdef np.uint16_t * image_data = <np.uint16_t*>image.data
cdef np.uint8_t * mask_data = <np.uint8_t*>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 = <Py_ssize_t * >malloc(maxbin * sizeof(Py_ssize_t))
cdef Py_ssize_t * histo = <Py_ssize_t*>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 = <Py_ssize_t * >malloc(max_se * sizeof(Py_ssize_t))
cdef Py_ssize_t * se_e_c = <Py_ssize_t * >malloc(max_se * sizeof(Py_ssize_t))
cdef Py_ssize_t * se_w_r = <Py_ssize_t * >malloc(max_se * sizeof(Py_ssize_t))
cdef Py_ssize_t * se_w_c = <Py_ssize_t * >malloc(max_se * sizeof(Py_ssize_t))
cdef Py_ssize_t * se_n_r = <Py_ssize_t * >malloc(max_se * sizeof(Py_ssize_t))
cdef Py_ssize_t * se_n_c = <Py_ssize_t * >malloc(max_se * sizeof(Py_ssize_t))
cdef Py_ssize_t * se_s_r = <Py_ssize_t * >malloc(max_se * sizeof(Py_ssize_t))
cdef Py_ssize_t * se_s_c = <Py_ssize_t * >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 = <Py_ssize_t*>malloc(max_se * sizeof(Py_ssize_t))
cdef Py_ssize_t * se_e_c = <Py_ssize_t*>malloc(max_se * sizeof(Py_ssize_t))
cdef Py_ssize_t * se_w_r = <Py_ssize_t*>malloc(max_se * sizeof(Py_ssize_t))
cdef Py_ssize_t * se_w_c = <Py_ssize_t*>malloc(max_se * sizeof(Py_ssize_t))
cdef Py_ssize_t * se_n_r = <Py_ssize_t*>malloc(max_se * sizeof(Py_ssize_t))
cdef Py_ssize_t * se_n_c = <Py_ssize_t*>malloc(max_se * sizeof(Py_ssize_t))
cdef Py_ssize_t * se_s_r = <Py_ssize_t*>malloc(max_se * sizeof(Py_ssize_t))
cdef Py_ssize_t * se_s_c = <Py_ssize_t*>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
+16 -11
View File
@@ -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)
+68 -86
View File
@@ -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 = <np.uint8_t * >out.data
cdef np.uint8_t * image_data = <np.uint8_t * >image.data
cdef np.uint8_t * mask_data = <np.uint8_t * >mask.data
cdef np.uint8_t * out_data = <np.uint8_t*>out.data
cdef np.uint8_t * image_data = <np.uint8_t*>image.data
cdef np.uint8_t * mask_data = <np.uint8_t*>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 = <Py_ssize_t * >malloc(256 * sizeof(Py_ssize_t))
cdef Py_ssize_t * histo = <Py_ssize_t*>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 = <Py_ssize_t * >malloc(max_se * sizeof(Py_ssize_t))
cdef Py_ssize_t * se_e_c = <Py_ssize_t * >malloc(max_se * sizeof(Py_ssize_t))
cdef Py_ssize_t * se_w_r = <Py_ssize_t * >malloc(max_se * sizeof(Py_ssize_t))
cdef Py_ssize_t * se_w_c = <Py_ssize_t * >malloc(max_se * sizeof(Py_ssize_t))
cdef Py_ssize_t * se_n_r = <Py_ssize_t * >malloc(max_se * sizeof(Py_ssize_t))
cdef Py_ssize_t * se_n_c = <Py_ssize_t * >malloc(max_se * sizeof(Py_ssize_t))
cdef Py_ssize_t * se_s_r = <Py_ssize_t * >malloc(max_se * sizeof(Py_ssize_t))
cdef Py_ssize_t * se_s_c = <Py_ssize_t * >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 = <Py_ssize_t*>malloc(max_se * sizeof(Py_ssize_t))
cdef Py_ssize_t * se_e_c = <Py_ssize_t*>malloc(max_se * sizeof(Py_ssize_t))
cdef Py_ssize_t * se_w_r = <Py_ssize_t*>malloc(max_se * sizeof(Py_ssize_t))
cdef Py_ssize_t * se_w_c = <Py_ssize_t*>malloc(max_se * sizeof(Py_ssize_t))
cdef Py_ssize_t * se_n_r = <Py_ssize_t*>malloc(max_se * sizeof(Py_ssize_t))
cdef Py_ssize_t * se_n_c = <Py_ssize_t*>malloc(max_se * sizeof(Py_ssize_t))
cdef Py_ssize_t * se_s_r = <Py_ssize_t*>malloc(max_se * sizeof(Py_ssize_t))
cdef Py_ssize_t * se_s_c = <Py_ssize_t*>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
+31 -15
View File
@@ -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, <Py_ssize_t>0, <Py_ssize_t>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, <Py_ssize_t>0, <Py_ssize_t>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, <Py_ssize_t>0, <Py_ssize_t>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, <Py_ssize_t>0, <Py_ssize_t>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, <Py_ssize_t>0, <Py_ssize_t>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, <Py_ssize_t>0, <Py_ssize_t>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, <Py_ssize_t>0, <Py_ssize_t>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, <Py_ssize_t>0, <Py_ssize_t>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, <Py_ssize_t>0, <Py_ssize_t>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, <Py_ssize_t>0, <Py_ssize_t>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, <Py_ssize_t>0, <Py_ssize_t>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, <Py_ssize_t>0, <Py_ssize_t>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, <Py_ssize_t>0, <Py_ssize_t>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, <Py_ssize_t>0, <Py_ssize_t>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, <Py_ssize_t>0, <Py_ssize_t>0)
+4 -2
View File
@@ -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)
+32 -32
View File
@@ -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, <Py_ssize_t>0, <Py_ssize_t>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, <Py_ssize_t>0, <Py_ssize_t>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, <Py_ssize_t>0, <Py_ssize_t>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, <Py_ssize_t>0, <Py_ssize_t>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, <Py_ssize_t>0, <Py_ssize_t>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, <Py_ssize_t>0, <Py_ssize_t>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, <Py_ssize_t>0, <Py_ssize_t>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, <Py_ssize_t>0, <Py_ssize_t>0)
+34 -31
View File
@@ -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, <Py_ssize_t>0, <Py_ssize_t>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, <Py_ssize_t>0, <Py_ssize_t>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, <Py_ssize_t>0, <Py_ssize_t>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, <Py_ssize_t>0, <Py_ssize_t>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, <Py_ssize_t>0, <Py_ssize_t>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, <Py_ssize_t>0, <Py_ssize_t>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, <Py_ssize_t>0, <Py_ssize_t>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, <Py_ssize_t>0, <Py_ssize_t>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, <Py_ssize_t>0, <Py_ssize_t>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, <Py_ssize_t>0, <Py_ssize_t>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, <Py_ssize_t>0, <Py_ssize_t>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, <Py_ssize_t>0, <Py_ssize_t>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,
<Py_ssize_t>0, <Py_ssize_t>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, <Py_ssize_t>0, <Py_ssize_t>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, <Py_ssize_t>0, <Py_ssize_t>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, <Py_ssize_t>0, <Py_ssize_t>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, <Py_ssize_t>0, <Py_ssize_t>0)
+16 -20
View File
@@ -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,
<Py_ssize_t>0, <Py_ssize_t>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,
<Py_ssize_t>0, <Py_ssize_t>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,
<Py_ssize_t>0, <Py_ssize_t>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, <Py_ssize_t>0, <Py_ssize_t>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, <Py_ssize_t>0, <Py_ssize_t>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, <Py_ssize_t>0, <Py_ssize_t>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,
<Py_ssize_t>0, <Py_ssize_t>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,
<Py_ssize_t>0, <Py_ssize_t>0)
+79 -56
View File
@@ -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)
+207 -154
View File
@@ -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)
+266 -209
View File
@@ -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)
return _apply(_crank8.otsu, None, image, selem, out=out,
mask=mask, shift_x=shift_x, shift_y=shift_y)