diff --git a/doc/examples/applications/plot_rank_filters.py b/doc/examples/applications/plot_rank_filters.py index 2ebb7b92..7b28d776 100644 --- a/doc/examples/applications/plot_rank_filters.py +++ b/doc/examples/applications/plot_rank_filters.py @@ -348,6 +348,61 @@ plt.xlabel('morphological gradient') """ .. image:: PLOT2RST.current_figure +Feature extraction +=================== + +Local histogram can be exploited to compute local entropy, which is related to the local image complexity. +Entropy is computed using base 2 logarithm i.e. the filter returns the minimum number of bits needed to encode local +greylevel distribution. + +``skimage.rank.entropy`` returns local entropy on a given structuring element. +The following example shows this filter applied on 8- and 16- bit images. + +.. note:: to better use the available image bit, the function returns 10x entropy for 8-bit images and 1000x entropy + for 16-bit images. + +""" + +from skimage import data +from skimage.filter.rank import entropy +from skimage.morphology import disk +import numpy as np +import matplotlib.pyplot as plt + +# 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 + +# display results +plt.figure(figsize=(10, 10)) + +plt.subplot(2,2,1) +plt.imshow(a8, cmap=plt.cm.gray) +plt.xlabel('8-bit image') +plt.colorbar() + +plt.subplot(2,2,2) +plt.imshow(ent8, cmap=plt.cm.jet) +plt.xlabel('entropy*10') +plt.colorbar() + +plt.subplot(2,2,3) +plt.imshow(a16, cmap=plt.cm.gray) +plt.xlabel('16-bit image') +plt.colorbar() + +plt.subplot(2,2,4) +plt.imshow(ent16, cmap=plt.cm.jet) +plt.xlabel('entropy*1000') +plt.colorbar() +plt.show() + +""" +.. image:: PLOT2RST.current_figure + Implementation ================ diff --git a/doc/examples/plot_entropy.py b/doc/examples/plot_entropy.py new file mode 100644 index 00000000..f019d79c --- /dev/null +++ b/doc/examples/plot_entropy.py @@ -0,0 +1,44 @@ +""" +=================== +Entropy +=================== + + +""" +from skimage import data +from skimage.filter.rank import entropy +from skimage.morphology import disk +import numpy as np +import matplotlib.pyplot as plt + +# 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 + +# display results +plt.figure(figsize=(10, 10)) + +plt.subplot(2,2,1) +plt.imshow(a8, cmap=plt.cm.gray) +plt.xlabel('8-bit image') +plt.colorbar() + +plt.subplot(2,2,2) +plt.imshow(ent8, cmap=plt.cm.jet) +plt.xlabel('entropy*10') +plt.colorbar() + +plt.subplot(2,2,3) +plt.imshow(a16, cmap=plt.cm.gray) +plt.xlabel('16-bit image') +plt.colorbar() + +plt.subplot(2,2,4) +plt.imshow(ent16, cmap=plt.cm.jet) +plt.xlabel('entropy*1000') +plt.colorbar() +plt.show() + diff --git a/skimage/filter/rank/_crank16.pyx b/skimage/filter/rank/_crank16.pyx index f6ad10e4..73e8e0bd 100644 --- a/skimage/filter/rank/_crank16.pyx +++ b/skimage/filter/rank/_crank16.pyx @@ -5,6 +5,7 @@ import numpy as np cimport numpy as np +from libc.math cimport log2 # import main loop from skimage.filter.rank._core16 cimport _core16 @@ -222,6 +223,23 @@ cdef inline np.uint16_t kernel_tophat( return < np.uint16_t > (i - g) + +cdef inline np.uint16_t kernel_entropy( + Py_ssize_t * histo, float pop, np.uint16_t g, + Py_ssize_t bitdepth, Py_ssize_t maxbin, Py_ssize_t midbin, + float p0, float p1, Py_ssize_t s0, Py_ssize_t s1): + cdef Py_ssize_t i + cdef float e,p + + e = 0. + + for i in range(maxbin): + p = histo[i]/pop + if p>0: + e -= p*log2(p) + + return < np.uint16_t > e*1000 + # ----------------------------------------------------------------- # python wrappers # ----------------------------------------------------------------- @@ -232,8 +250,6 @@ 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): - """bottom hat - """ return _core16(kernel_autolevel, image, selem, mask, out, shift_x, shift_y, bitdepth, .0, .0, < Py_ssize_t > 0, < Py_ssize_t > 0) @@ -242,8 +258,6 @@ 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): - """bottom hat - """ return _core16(kernel_bottomhat, image, selem, mask, out, shift_x, shift_y, bitdepth, .0, .0, < Py_ssize_t > 0, < Py_ssize_t > 0) @@ -252,8 +266,6 @@ 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): - """local egalisation of the gray level - """ return _core16(kernel_equalize, image, selem, mask, out, shift_x, shift_y, bitdepth, .0, .0, < Py_ssize_t > 0, < Py_ssize_t > 0) @@ -262,8 +274,6 @@ 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): - """local maximum - local minimum gray level - """ return _core16(kernel_gradient, image, selem, mask, out, shift_x, shift_y, bitdepth, .0, .0, < Py_ssize_t > 0, < Py_ssize_t > 0) @@ -272,8 +282,6 @@ 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): - """local maximum gray level - """ return _core16(kernel_maximum, image, selem, mask, out, shift_x, shift_y, bitdepth, .0, .0, < Py_ssize_t > 0, < Py_ssize_t > 0) @@ -282,8 +290,6 @@ 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): - """average gray level (clipped on uint8) - """ return _core16(kernel_mean, image, selem, mask, out, shift_x, shift_y, bitdepth, .0, .0, < Py_ssize_t > 0, < Py_ssize_t > 0) @@ -292,8 +298,6 @@ 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): - """(g - average gray level)/2+midbin (clipped on uint8) - """ return _core16(kernel_meansubstraction, image, selem, mask, out, shift_x, shift_y, bitdepth, .0, .0, < Py_ssize_t > 0, < Py_ssize_t > 0) @@ -302,8 +306,6 @@ 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): - """local median - """ return _core16(kernel_median, image, selem, mask, out, shift_x, shift_y, bitdepth, .0, .0, < Py_ssize_t > 0, < Py_ssize_t > 0) @@ -312,8 +314,6 @@ 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): - """local minimum gray level - """ return _core16(kernel_minimum, image, selem, mask, out, shift_x, shift_y, bitdepth, .0, .0, < Py_ssize_t > 0, < Py_ssize_t > 0) @@ -322,8 +322,6 @@ 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): - """morphological contrast enhancement - """ 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) @@ -332,8 +330,6 @@ 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): - """local mode - """ return _core16(kernel_modal, image, selem, mask, out, shift_x, shift_y, bitdepth, .0, .0, < Py_ssize_t > 0, < Py_ssize_t > 0) @@ -342,8 +338,6 @@ 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): - """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, < Py_ssize_t > 0, < Py_ssize_t > 0) @@ -352,8 +346,6 @@ 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): - """returns maxbin-1 if gray level higher than local mean, 0 else - """ return _core16(kernel_threshold, image, selem, mask, out, shift_x, shift_y, bitdepth, .0, .0, < Py_ssize_t > 0, < Py_ssize_t > 0) @@ -362,6 +354,11 @@ 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): - """top hat - """ return _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) diff --git a/skimage/filter/rank/_crank8.pyx b/skimage/filter/rank/_crank8.pyx index 5cb0b5ed..84ad9204 100644 --- a/skimage/filter/rank/_crank8.pyx +++ b/skimage/filter/rank/_crank8.pyx @@ -6,6 +6,8 @@ import numpy as np cimport numpy as np +from libc.math cimport log2 + # import main loop from skimage.filter.rank._core8 cimport _core8 @@ -251,17 +253,16 @@ cdef inline np.uint8_t kernel_entropy( Py_ssize_t s1): cdef Py_ssize_t i - cdef Py_ssize_t min_i cdef float e,p - e = 0 + e = 0. for i in range(256): - p = histo[i]/pop + p = histo[i]/pop if p>0: - e -= p*np.log2(p) + e -= p*log2(p) - return < np.uint8_t > e + return < np.uint8_t > e*10 # ----------------------------------------------------------------- # python wrappers diff --git a/skimage/filter/rank/bilateral_rank.pyx b/skimage/filter/rank/bilateral_rank.pyx index 80349b0b..f181735b 100644 --- a/skimage/filter/rank/bilateral_rank.pyx +++ b/skimage/filter/rank/bilateral_rank.pyx @@ -71,8 +71,7 @@ def bilateral_mean(image, selem, out=None, mask=None, shift_x=False, shift_y=Fal selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray - The array to store the result of the morphology. If None is - passed, a new array will be allocated. + 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). @@ -126,8 +125,7 @@ def bilateral_pop(image, selem, out=None, mask=None, shift_x=False, shift_y=Fals selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray - The array to store the result of the morphology. If None is - passed, a new array will be allocated. + 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). diff --git a/skimage/filter/rank/demo/demo_single.py b/skimage/filter/rank/demo/demo_single.py index e3fe9c1e..4afa546b 100644 --- a/skimage/filter/rank/demo/demo_single.py +++ b/skimage/filter/rank/demo/demo_single.py @@ -25,12 +25,15 @@ if __name__ == '__main__': plt.imsave('noise.png',noise,cmap=plt.cm.gray) plt.imsave('cam.png',a8,cmap=plt.cm.gray) + selem = disk(3) + ent = rank.entropy(a16,selem) + plt.figure() plt.subplot(1,2,1) plt.imshow(a8) plt.subplot(1,2,2) - plt.imshow(noise) + plt.imshow(ent) plt.colorbar() plt.show() diff --git a/skimage/filter/rank/percentile_rank.pyx b/skimage/filter/rank/percentile_rank.pyx index d45bcfe3..1bd89eb8 100644 --- a/skimage/filter/rank/percentile_rank.pyx +++ b/skimage/filter/rank/percentile_rank.pyx @@ -55,8 +55,7 @@ def percentile_autolevel(image, selem, out=None, mask=None, shift_x=False, shift selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray - The array to store the result of the morphology. If None is - passed, a new array will be allocated. + 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). @@ -92,8 +91,7 @@ def percentile_gradient(image, selem, out=None, mask=None, shift_x=False, shift_ selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray - The array to store the result of the morphology. If None is - passed, a new array will be allocated. + 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). @@ -130,8 +128,7 @@ def percentile_mean(image, selem, out=None, mask=None, shift_x=False, shift_y=Fa selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray - The array to store the result of the morphology. If None is - passed, a new array will be allocated. + 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). @@ -167,8 +164,7 @@ def percentile_mean_substraction(image, selem, out=None, mask=None, shift_x=Fals selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray - The array to store the result of the morphology. If None is - passed, a new array will be allocated. + 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). @@ -205,8 +201,7 @@ def percentile_morph_contr_enh(image, selem, out=None, mask=None, shift_x=False, selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray - The array to store the result of the morphology. If None is - passed, a new array will be allocated. + 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). @@ -243,8 +238,7 @@ def percentile(image, selem, out=None, mask=None, shift_x=False, shift_y=False, selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray - The array to store the result of the morphology. If None is - passed, a new array will be allocated. + 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). @@ -281,8 +275,7 @@ def percentile_pop(image, selem, out=None, mask=None, shift_x=False, shift_y=Fal selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray - The array to store the result of the morphology. If None is - passed, a new array will be allocated. + 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). @@ -319,8 +312,7 @@ def percentile_threshold(image, selem, out=None, mask=None, shift_x=False, shift selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray - The array to store the result of the morphology. If None is - passed, a new array will be allocated. + 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). diff --git a/skimage/filter/rank/rank.pyx b/skimage/filter/rank/rank.pyx index 12517cfa..2c9b7326 100644 --- a/skimage/filter/rank/rank.pyx +++ b/skimage/filter/rank/rank.pyx @@ -19,7 +19,7 @@ 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'] + 'modal', 'morph_contr_enh', 'pop', 'threshold', 'tophat','noise_filter','entropy'] def _apply(func8, func16, image, selem, out, mask, shift_x, shift_y): @@ -52,8 +52,7 @@ def autolevel(image, selem, out=None, mask=None, shift_x=False, shift_y=False): selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray - The array to store the result of the morphology. If None is - passed, a new array will be allocated. + 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). @@ -94,8 +93,7 @@ def bottomhat(image, selem, out=None, mask=None, shift_x=False, shift_y=False): selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray - The array to store the result of the morphology. If None is - passed, a new array will be allocated. + 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). @@ -127,8 +125,7 @@ def equalize(image, selem, out=None, mask=None, shift_x=False, shift_y=False): selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray - The array to store the result of the morphology. If None is - passed, a new array will be allocated. + 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). @@ -169,8 +166,7 @@ def gradient(image, selem, out=None, mask=None, shift_x=False, shift_y=False): selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray - The array to store the result of the morphology. If None is - passed, a new array will be allocated. + 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). @@ -202,8 +198,7 @@ def maximum(image, selem, out=None, mask=None, shift_x=False, shift_y=False): selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray - The array to store the result of the morphology. If None is - passed, a new array will be allocated. + 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). @@ -242,8 +237,7 @@ def mean(image, selem, out=None, mask=None, shift_x=False, shift_y=False): selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray - The array to store the result of the morphology. If None is - passed, a new array will be allocated. + 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). @@ -281,8 +275,7 @@ def meansubstraction(image, selem, out=None, mask=None, shift_x=False, shift_y=F selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray - The array to store the result of the morphology. If None is - passed, a new array will be allocated. + 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). @@ -316,8 +309,7 @@ def median(image, selem, out=None, mask=None, shift_x=False, shift_y=False): selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray - The array to store the result of the morphology. If None is - passed, a new array will be allocated. + 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). @@ -355,8 +347,7 @@ def minimum(image, selem, out=None, mask=None, shift_x=False, shift_y=False): selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray - The array to store the result of the morphology. If None is - passed, a new array will be allocated. + 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). @@ -395,8 +386,7 @@ def modal(image, selem, out=None, mask=None, shift_x=False, shift_y=False): selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray - The array to store the result of the morphology. If None is - passed, a new array will be allocated. + 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). @@ -427,8 +417,7 @@ def morph_contr_enh(image, selem, out=None, mask=None, shift_x=False, shift_y=Fa selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray - The array to store the result of the morphology. If None is - passed, a new array will be allocated. + 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). @@ -468,8 +457,7 @@ def pop(image, selem, out=None, mask=None, shift_x=False, shift_y=False): selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray - The array to store the result of the morphology. If None is - passed, a new array will be allocated. + 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). @@ -516,8 +504,7 @@ def threshold(image, selem, out=None, mask=None, shift_x=False, shift_y=False): selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray - The array to store the result of the morphology. If None is - passed, a new array will be allocated. + 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). @@ -566,8 +553,7 @@ def tophat(image, selem, out=None, mask=None, shift_x=False, shift_y=False): selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray - The array to store the result of the morphology. If None is - passed, a new array will be allocated. + 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). @@ -595,8 +581,7 @@ def noise_filter(image, selem, out=None, mask=None, shift_x=False, shift_y=False selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray - The array to store the result of the morphology. If None is - passed, a new array will be allocated. + 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). @@ -626,7 +611,12 @@ def noise_filter(image, selem, out=None, mask=None, shift_x=False, shift_y=False 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 (in bit) computed locally (precision is limited due to image type used 8- or 16-bit) + """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) Parameters ---------- @@ -636,8 +626,7 @@ def entropy(image, selem, out=None, mask=None, shift_x=False, shift_y=False): selem : ndarray The neighborhood expressed as a 2-D array of 1's and 0's. out : ndarray - The array to store the result of the morphology. If None is - passed, a new array will be allocated. + 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). @@ -645,12 +634,25 @@ def entropy(image, selem, out=None, mask=None, shift_x=False, shift_y=False): 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) - local entropy (in bit) + entropy x10 (uint8 images) and entropy x1000 (uint16 images) + + + Examples + -------- + + >>> # Local entropy + >>> from skimage import data + >>> from skimage.filter.rank import entropy + >>> from skimage.morphology import disk + >>> # 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 """ - return _apply(_crank8.entropy, None, image, selem_cpy, out=out, mask=mask, shift_x=shift_x, shift_y=shift_y) \ No newline at end of file + return _apply(_crank8.entropy, _crank16.entropy, image, selem, out=out, mask=mask, shift_x=shift_x, shift_y=shift_y) \ No newline at end of file