From 08b748c379bf468dad76bb1f56a802fe437a104b Mon Sep 17 00:00:00 2001 From: odebeir Date: Sun, 11 Nov 2012 14:39:09 +0100 Subject: [PATCH] local Otsu returns now the threshold values --- .../applications/plot_rank_filters.py | 50 +++++++++++++++++++ doc/examples/plot_local_otsu.py | 49 ++++++++++++++++++ skimage/filter/rank/_crank8.pyx | 6 +-- skimage/filter/rank/demo/demo_single.py | 29 +++++++---- skimage/filter/rank/rank.pyx | 5 +- 5 files changed, 121 insertions(+), 18 deletions(-) create mode 100644 doc/examples/plot_local_otsu.py diff --git a/doc/examples/applications/plot_rank_filters.py b/doc/examples/applications/plot_rank_filters.py index d52595f2..0efaf17b 100644 --- a/doc/examples/applications/plot_rank_filters.py +++ b/doc/examples/applications/plot_rank_filters.py @@ -308,6 +308,56 @@ plt.imshow(ima[200:350,350:450],cmap=plt.cm.gray) plt.subplot(2,2,4) plt.imshow(penh[200:350,350:450],cmap=plt.cm.gray) +""" +.. image:: PLOT2RST.current_figure + +Image threshold +=============== +The Otsu's threshold [1]_ method can be applied locally using local greylevel distribution. +In the example below, for each pixel, an "optimal" threshold is determined by maximizing +the variance between two classes of pixels of the local neighborhood defined by a structuring element. + +The example compares the local threshold with the global threshold `skimage.filter.threshold_otsu``. + +.. note: local threshold is much slower than global one. + +.. [1] http://en.wikipedia.org/wiki/Otsu's_method + +""" +from skimage.filter.rank import otsu +from skimage.filter import threshold_otsu + +p8 = data.page() + +radius = 10 +selem = disk(radius) + +# t_loc_otsu is an image +t_loc_otsu = otsu(p8,selem) +loc_otsu = p8>=t_loc_otsu + +# t_glob_otsu is a scalar +t_glob_otsu = threshold_otsu(p8) +glob_otsu = p8>=t_glob_otsu + +plt.figure() +plt.subplot(2,2,1) +plt.imshow(p8,cmap=plt.cm.gray) +plt.xlabel('original') +plt.colorbar() +plt.subplot(2,2,2) +plt.imshow(loc_otsu,cmap=plt.cm.gray) +plt.xlabel('local Otsu ($radius=%d$)'%radius) +plt.colorbar() +plt.subplot(2,2,3) +plt.imshow(p8>=loc_otsu,cmap=plt.cm.gray) +plt.xlabel('original>=local Otsu'%t_glob_otsu) +plt.subplot(2,2,4) +plt.imshow(glob_otsu,cmap=plt.cm.gray) +plt.xlabel('global Otsu ($t=%d$)'%t_glob_otsu) +plt.show() + + """ .. image:: PLOT2RST.current_figure diff --git a/doc/examples/plot_local_otsu.py b/doc/examples/plot_local_otsu.py new file mode 100644 index 00000000..ae1ead48 --- /dev/null +++ b/doc/examples/plot_local_otsu.py @@ -0,0 +1,49 @@ +""" +===================== +Local Otsu Threshold +===================== +This example shows how Otsu's threshold [1]_ method can be applied locally. +For each pixel, an "optimal" threshold is determined by maximizing the variance between two classes of pixels +of the local neighborhood defined by a structuring element. + +The example compares the local threshold with the global threshold. + +.. note: local threshold is much slower than global one. + +.. [1] http://en.wikipedia.org/wiki/Otsu's_method + +""" +import matplotlib.pyplot as plt + +from skimage import data +from skimage.morphology.selem import disk +import skimage.filter.rank as rank +from skimage.filter import threshold_otsu + + +p8 = data.page() + +radius = 10 +selem = disk(radius) + +loc_otsu = rank.otsu(p8,selem) +t_glob_otsu = threshold_otsu(p8) +glob_otsu = p8>=t_glob_otsu + + +plt.figure() +plt.subplot(2,2,1) +plt.imshow(p8,cmap=plt.cm.gray) +plt.xlabel('original') +plt.colorbar() +plt.subplot(2,2,2) +plt.imshow(loc_otsu,cmap=plt.cm.gray) +plt.xlabel('local Otsu ($radius=%d$)'%radius) +plt.colorbar() +plt.subplot(2,2,3) +plt.imshow(p8>=loc_otsu,cmap=plt.cm.gray) +plt.xlabel('original>=local Otsu'%t_glob_otsu) +plt.subplot(2,2,4) +plt.imshow(glob_otsu,cmap=plt.cm.gray) +plt.xlabel('global Otsu ($t=%d$)'%t_glob_otsu) +plt.show() diff --git a/skimage/filter/rank/_crank8.pyx b/skimage/filter/rank/_crank8.pyx index 7398b26f..53076217 100644 --- a/skimage/filter/rank/_crank8.pyx +++ b/skimage/filter/rank/_crank8.pyx @@ -312,11 +312,7 @@ cdef inline np.uint8_t kernel_otsu(Py_ssize_t * histo, float pop, np.uint8_t g, max_i = i q1 = new_q1 - if g > max_i: - return 255 - else: - return 0 - + return max_i # ----------------------------------------------------------------- diff --git a/skimage/filter/rank/demo/demo_single.py b/skimage/filter/rank/demo/demo_single.py index 7e4ef405..053f7328 100644 --- a/skimage/filter/rank/demo/demo_single.py +++ b/skimage/filter/rank/demo/demo_single.py @@ -4,27 +4,34 @@ import matplotlib.pyplot as plt from skimage import data from skimage.morphology.selem import disk import skimage.filter.rank as rank - -from skimage.filter import denoise_bilateral +from skimage.filter import threshold_otsu if __name__ == '__main__': - a8 = data.camera() - a16 = data.camera().astype(np.uint16)*4 - p8 = data.page() - selem = disk(20) + radius = 10 + selem = disk(radius) - otsu = rank.otsu(p8,selem) + loc_otsu = rank.otsu(p8,selem) + t_glob_otsu = threshold_otsu(p8) + glob_otsu = p8>=t_glob_otsu plt.figure() - plt.subplot(1,2,1) - plt.imshow(p8) + plt.subplot(2,2,1) + plt.imshow(p8,cmap=plt.cm.gray) + plt.xlabel('original') plt.colorbar() - plt.subplot(1,2,2) - plt.imshow(otsu) + plt.subplot(2,2,2) + plt.imshow(loc_otsu,cmap=plt.cm.gray) + plt.xlabel('local Otsu ($radius=%d$)'%radius) plt.colorbar() + plt.subplot(2,2,3) + plt.imshow(p8>=loc_otsu,cmap=plt.cm.gray) + plt.xlabel('original>=local Otsu'%t_glob_otsu) + plt.subplot(2,2,4) + plt.imshow(glob_otsu,cmap=plt.cm.gray) + plt.xlabel('global Otsu ($t=%d$)'%t_glob_otsu) plt.show() diff --git a/skimage/filter/rank/rank.pyx b/skimage/filter/rank/rank.pyx index 74add3d7..763a702f 100644 --- a/skimage/filter/rank/rank.pyx +++ b/skimage/filter/rank/rank.pyx @@ -715,7 +715,7 @@ def entropy(image, selem, out=None, mask=None, shift_x=False, shift_y=False): 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 . + """Returns the Otsu's threshold value for each pixel. Parameters ---------- @@ -738,7 +738,7 @@ def otsu(image, selem, out=None, mask=None, shift_x=False, shift_y=False): Returns ------- out : uint8 array or uint16 array (same as input image) - threshold image + Otsu's threshold values References ---------- @@ -753,6 +753,7 @@ def otsu(image, selem, out=None, mask=None, shift_x=False, shift_y=False): >>> # defining a 8- and a 16-bit test images >>> a8 = data.camera() >>> loc_otsu = otsu(a8,disk(5)) + >>> thresh_image = a8 >= loc_otsu """