From b74ea8222d21820b7990e60ec535dd6d7bd2571b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Boulogne?= Date: Wed, 25 May 2016 14:42:38 +0200 Subject: [PATCH 01/19] ENH: add mosaic --- skimage/filters/__init__.py | 1 + skimage/filters/thresholding.py | 145 ++++++++++++++++++++++++++++++++ 2 files changed, 146 insertions(+) diff --git a/skimage/filters/__init__.py b/skimage/filters/__init__.py index 9f722318..be22469f 100644 --- a/skimage/filters/__init__.py +++ b/skimage/filters/__init__.py @@ -44,6 +44,7 @@ __all__ = ['inverse', 'rank_order', 'gabor_kernel', 'gabor', + 'mosaic_threshold', 'threshold_adaptive', 'threshold_otsu', 'threshold_yen', diff --git a/skimage/filters/thresholding.py b/skimage/filters/thresholding.py index 2896c982..fcc51b6f 100644 --- a/skimage/filters/thresholding.py +++ b/skimage/filters/thresholding.py @@ -1,8 +1,153 @@ +__all__ = ['mosaic_threshold', + 'threshold_adaptive', + 'threshold_otsu', + 'threshold_yen', + 'threshold_isodata', + 'threshold_li', + 'threshold_minimum', ] + +import math import numpy as np from scipy import ndimage as ndi from scipy.ndimage import filters as ndif +from matplotlib import pyplot as plt +from collections import OrderedDict from ..exposure import histogram from .._shared.utils import assert_nD, warn +from ..morphology import disk +from ..filters.rank import otsu + + +def _mosaic(image, methods=None, figsize=None, num_cols=2, verbose=True): + """Returns a figure comparing the outputs of different methods. + + Parameters + ---------- + image : (N, M) ndarray + Input image. + methods : dict, optional + Names and associated functions of the algorithms. + The functions must return an image. + figsize : tuple, optional + Figure size (in inches). + num_cols : int, optional + Number of columns. + verbose : bool, optional + Print the function name for each method. + + Returns + ------- + fig, ax : tuple + Matplotlib figure and axes. + """ + num_rows = math.ceil((len(methods) + 1) / 2.) + num_rows = int(num_rows) # Python 2.7 support + fig, ax = plt.subplots(num_rows, num_cols, figsize=figsize, + sharex=True, sharey=True, + subplot_kw={'adjustable': 'box-forced'}) + ax = ax.ravel() + + ax[0].imshow(image) + ax[0].set_title('Original') + + i = 1 + for name, func in methods.items(): + ax[i].imshow(func(image)) + ax[i].set_title(name) + i += 1 + if verbose: + print(func.__orifunc__) + + for a in ax: + a.axis('off') + + fig.tight_layout() + plt.close() + return fig, ax + + +def mosaic_threshold(image, radius=None, figsize=(8, 5), verbose=True): + """Returns a figure comparing the outputs of different thresholding methods. + + Parameters + ---------- + image : (N, M) ndarray + Input image. + radius : int, optinal + Lengthscale used for local methods. + If None, local methods are not called. + figsize : tuple, optional + Figure size (in inches). + verbose : bool, optional + Print the function name for each method. + + Returns + ------- + fig, ax : tuple + Matplotlib figure and axes. + + Notes + ----- + The following algorithms are used: + + * isodata + * otsu + * li + * yen + * adaptive threshold (local) + * rank otsu (local) + + Example + ------- + >>> from skimage.data import text + >>> fig, ax = mosaic_threshold(text(), radius=20, + ... figsize=(10, 6), verbose=None) + """ + + def include_selem(func, *args, **kwargs): + """ + A wrapper function to embed a threshold range. + """ + def wrapper(im): + return func(im, *args, **kwargs) + try: + wrapper.__orifunc__ = func.__orifunc__ + except AttributeError: + wrapper.__orifunc__ = func.__module__ + '.' + func.__name__ + return wrapper + + + def thresh(func): + """ + A wrapper function to return a thresholded image. + """ + def wrapper(im): + return im > func(im) + try: + wrapper.__orifunc__ = func.__orifunc__ + except AttributeError: + wrapper.__orifunc__ = func.__module__ + '.' + func.__name__ + return wrapper + + # Global algorithms. + methods = OrderedDict({'Isodata': thresh(threshold_isodata), + 'Li': thresh(threshold_li), + 'Otsu': thresh(threshold_otsu), + 'Yen': thresh(threshold_yen)}) + + # Local algorithms. + if radius is not None: + selem = disk(radius) + local_otsu = include_selem(otsu, selem) + methods['Local Otsu'] = thresh(local_otsu) + + block_size = 2 * int(radius) + 1 + adaptive_threshold = include_selem(threshold_adaptive, block_size, offset=10) + methods['Adaptive threshold'] = adaptive_threshold + + + return _mosaic(image, figsize=figsize, + methods=methods, verbose=verbose) __all__ = ['threshold_adaptive', 'threshold_otsu', From a7cf3cbd521c376943b3bc51b438b494cbd0ff31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Boulogne?= Date: Sun, 29 May 2016 17:47:48 +0200 Subject: [PATCH 02/19] DOC: rename thresholding example --- doc/examples/segmentation/{plot_otsu.py => plot_thresholding.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename doc/examples/segmentation/{plot_otsu.py => plot_thresholding.py} (100%) diff --git a/doc/examples/segmentation/plot_otsu.py b/doc/examples/segmentation/plot_thresholding.py similarity index 100% rename from doc/examples/segmentation/plot_otsu.py rename to doc/examples/segmentation/plot_thresholding.py From 20f33e18fe247185cf1a4557d6479f703ea5c94c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Boulogne?= Date: Sun, 29 May 2016 18:04:18 +0200 Subject: [PATCH 03/19] DOC: add mosaic_threshold --- .../segmentation/plot_thresholding.py | 33 +++++++++++++++++-- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/doc/examples/segmentation/plot_thresholding.py b/doc/examples/segmentation/plot_thresholding.py index c279a65b..cae58a32 100644 --- a/doc/examples/segmentation/plot_thresholding.py +++ b/doc/examples/segmentation/plot_thresholding.py @@ -3,15 +3,42 @@ Thresholding ============ -Thresholding is used to create a binary image. This example uses Otsu's method -to calculate the threshold value. +Thresholding is used to create a binary image from a grayscale image [1]_. + +Thresholding algorithms can be separated in two categories: + * Global. They are based on the histogram of the pixel intensity of + the image. + * Local. To process a pixel, only the neighboring pixels are used. + These algorithms often require more computation time. + +Scikit-image includes a function to test thresholding algorithms provided +in the library. Therefore, in a glance, you can select the best algorithm +for you data, without a deep understanding of their mechanisms. + +.. [1] https://en.wikipedia.org/wiki/Thresholding_%28image_processing%29 + +""" +from skimage.data import page + +img = page() + +# Here, we specify a radius for local thresholding algorithm. +# If it is not specified, only global algorithms are called. +fig, ax = mosaic_threshold(img, radius=20, figsize=(10,8), verbose=False) +fig + +""" + +.. image:: PLOT2RST.current_figure + +This example uses Otsu's method [2]_ to calculate the threshold value. Otsu's method calculates an "optimal" threshold (marked by a red line in the histogram below) by maximizing the variance between two classes of pixels, which are separated by the threshold. Equivalently, this threshold minimizes the intra-class variance. -.. [1] http://en.wikipedia.org/wiki/Otsu's_method +.. [2] http://en.wikipedia.org/wiki/Otsu's_method """ import matplotlib From ecb84e7362473150980803a7adb8caf6cfee9ab6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Boulogne?= Date: Sun, 29 May 2016 18:52:54 +0200 Subject: [PATCH 04/19] DOC: illustrate mosaic in gallery --- .../segmentation/plot_thresholding.py | 27 +++++++++++++------ skimage/filters/thresholding.py | 2 +- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/doc/examples/segmentation/plot_thresholding.py b/doc/examples/segmentation/plot_thresholding.py index cae58a32..55abf889 100644 --- a/doc/examples/segmentation/plot_thresholding.py +++ b/doc/examples/segmentation/plot_thresholding.py @@ -6,10 +6,12 @@ Thresholding Thresholding is used to create a binary image from a grayscale image [1]_. Thresholding algorithms can be separated in two categories: - * Global. They are based on the histogram of the pixel intensity of - the image. - * Local. To process a pixel, only the neighboring pixels are used. - These algorithms often require more computation time. + +* Histogram-based. The histogram of the pixel intensity is used and +assumptions may be made on the properties of this histogram (e.g. bimodal). + +* Local. To process a pixel, only the neighboring pixels are used. +These algorithms often require more computation time. Scikit-image includes a function to test thresholding algorithms provided in the library. Therefore, in a glance, you can select the best algorithm @@ -18,20 +20,26 @@ for you data, without a deep understanding of their mechanisms. .. [1] https://en.wikipedia.org/wiki/Thresholding_%28image_processing%29 """ +import matplotlib +import matplotlib.pyplot as plt + from skimage.data import page +from skimage.filters import thresholding img = page() # Here, we specify a radius for local thresholding algorithm. # If it is not specified, only global algorithms are called. -fig, ax = mosaic_threshold(img, radius=20, figsize=(10,8), verbose=False) -fig +fig, ax = thresholding.mosaic_threshold(img, radius=20, + figsize=(10,8), verbose=False) +fig.show() """ .. image:: PLOT2RST.current_figure -This example uses Otsu's method [2]_ to calculate the threshold value. +Now, we illustrate how to apply one of these thresholding algorithms +This example uses Otsu's method [2]_. Otsu's method calculates an "optimal" threshold (marked by a red line in the histogram below) by maximizing the variance between two classes of pixels, @@ -55,7 +63,6 @@ image = camera() thresh = threshold_otsu(image) binary = image > thresh -#fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(8, 2.5)) fig = plt.figure(figsize=(8, 2.5)) ax1 = plt.subplot(1, 3, 1, adjustable='box-forced') ax2 = plt.subplot(1, 3, 2) @@ -74,3 +81,7 @@ ax3.set_title('Thresholded') ax3.axis('off') plt.show() + +""" +.. image:: PLOT2RST.current_figure +""" diff --git a/skimage/filters/thresholding.py b/skimage/filters/thresholding.py index fcc51b6f..1df0042a 100644 --- a/skimage/filters/thresholding.py +++ b/skimage/filters/thresholding.py @@ -62,7 +62,7 @@ def _mosaic(image, methods=None, figsize=None, num_cols=2, verbose=True): a.axis('off') fig.tight_layout() - plt.close() + #plt.close() return fig, ax From 12fabff65fa745fa0da6e698b60796850c673f1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Boulogne?= Date: Wed, 1 Jun 2016 09:17:36 +0200 Subject: [PATCH 05/19] Some corrections --- .../segmentation/plot_thresholding.py | 14 ++--- skimage/filters/__init__.py | 2 +- skimage/filters/thresholding.py | 53 +++++++++---------- 3 files changed, 34 insertions(+), 35 deletions(-) diff --git a/doc/examples/segmentation/plot_thresholding.py b/doc/examples/segmentation/plot_thresholding.py index 55abf889..8b1cae13 100644 --- a/doc/examples/segmentation/plot_thresholding.py +++ b/doc/examples/segmentation/plot_thresholding.py @@ -7,11 +7,11 @@ Thresholding is used to create a binary image from a grayscale image [1]_. Thresholding algorithms can be separated in two categories: -* Histogram-based. The histogram of the pixel intensity is used and -assumptions may be made on the properties of this histogram (e.g. bimodal). +- Histogram-based. The histogram of the pixel intensity is used and + assumptions may be made on the properties of this histogram (e.g. bimodal). +- Local. To process a pixel, only the neighboring pixels are used. + These algorithms often require more computation time. -* Local. To process a pixel, only the neighboring pixels are used. -These algorithms often require more computation time. Scikit-image includes a function to test thresholding algorithms provided in the library. Therefore, in a glance, you can select the best algorithm @@ -30,9 +30,9 @@ img = page() # Here, we specify a radius for local thresholding algorithm. # If it is not specified, only global algorithms are called. -fig, ax = thresholding.mosaic_threshold(img, radius=20, - figsize=(10,8), verbose=False) -fig.show() +fig, ax = thresholding.try_all_threshold(img, radius=20, + figsize=(10,8), verbose=False) +plt.show() """ diff --git a/skimage/filters/__init__.py b/skimage/filters/__init__.py index be22469f..9ae67a5c 100644 --- a/skimage/filters/__init__.py +++ b/skimage/filters/__init__.py @@ -44,7 +44,7 @@ __all__ = ['inverse', 'rank_order', 'gabor_kernel', 'gabor', - 'mosaic_threshold', + 'try_all_threshold', 'threshold_adaptive', 'threshold_otsu', 'threshold_yen', diff --git a/skimage/filters/thresholding.py b/skimage/filters/thresholding.py index 1df0042a..eb21ffbb 100644 --- a/skimage/filters/thresholding.py +++ b/skimage/filters/thresholding.py @@ -1,11 +1,3 @@ -__all__ = ['mosaic_threshold', - 'threshold_adaptive', - 'threshold_otsu', - 'threshold_yen', - 'threshold_isodata', - 'threshold_li', - 'threshold_minimum', ] - import math import numpy as np from scipy import ndimage as ndi @@ -18,7 +10,16 @@ from ..morphology import disk from ..filters.rank import otsu -def _mosaic(image, methods=None, figsize=None, num_cols=2, verbose=True): +__all__ = ['try_all_threshold', + 'threshold_adaptive', + 'threshold_otsu', + 'threshold_yen', + 'threshold_isodata', + 'threshold_li', + 'threshold_minimum', ] + + +def _try_all(image, methods=None, figsize=None, num_cols=2, verbose=True): """Returns a figure comparing the outputs of different methods. Parameters @@ -26,14 +27,14 @@ def _mosaic(image, methods=None, figsize=None, num_cols=2, verbose=True): image : (N, M) ndarray Input image. methods : dict, optional - Names and associated functions of the algorithms. - The functions must return an image. + Names and associated functions. + Functions must take and return an image. figsize : tuple, optional Figure size (in inches). num_cols : int, optional Number of columns. verbose : bool, optional - Print the function name for each method. + Print function name for each method. Returns ------- @@ -41,7 +42,7 @@ def _mosaic(image, methods=None, figsize=None, num_cols=2, verbose=True): Matplotlib figure and axes. """ num_rows = math.ceil((len(methods) + 1) / 2.) - num_rows = int(num_rows) # Python 2.7 support + num_rows = int(num_rows) # Python 2.7 support fig, ax = plt.subplots(num_rows, num_cols, figsize=figsize, sharex=True, sharey=True, subplot_kw={'adjustable': 'box-forced'}) @@ -62,11 +63,10 @@ def _mosaic(image, methods=None, figsize=None, num_cols=2, verbose=True): a.axis('off') fig.tight_layout() - #plt.close() return fig, ax -def mosaic_threshold(image, radius=None, figsize=(8, 5), verbose=True): +def try_all_threshold(image, radius=None, figsize=(8, 5), verbose=True): """Returns a figure comparing the outputs of different thresholding methods. Parameters @@ -75,11 +75,11 @@ def mosaic_threshold(image, radius=None, figsize=(8, 5), verbose=True): Input image. radius : int, optinal Lengthscale used for local methods. - If None, local methods are not called. + If None, local methods are ignored. figsize : tuple, optional Figure size (in inches). verbose : bool, optional - Print the function name for each method. + Print function name for each method. Returns ------- @@ -100,23 +100,22 @@ def mosaic_threshold(image, radius=None, figsize=(8, 5), verbose=True): Example ------- >>> from skimage.data import text - >>> fig, ax = mosaic_threshold(text(), radius=20, - ... figsize=(10, 6), verbose=None) + >>> fig, ax = try_all_threshold(text(), radius=20, + ... figsize=(10, 6), verbose=False) """ def include_selem(func, *args, **kwargs): """ - A wrapper function to embed a threshold range. + A wrapper function to embed a threshold range for local algorithms. """ def wrapper(im): return func(im, *args, **kwargs) try: wrapper.__orifunc__ = func.__orifunc__ except AttributeError: - wrapper.__orifunc__ = func.__module__ + '.' + func.__name__ + wrapper.__orifunc__ = func.__module__ + '.' + func.__name__ return wrapper - def thresh(func): """ A wrapper function to return a thresholded image. @@ -126,7 +125,7 @@ def mosaic_threshold(image, radius=None, figsize=(8, 5), verbose=True): try: wrapper.__orifunc__ = func.__orifunc__ except AttributeError: - wrapper.__orifunc__ = func.__module__ + '.' + func.__name__ + wrapper.__orifunc__ = func.__module__ + '.' + func.__name__ return wrapper # Global algorithms. @@ -142,12 +141,12 @@ def mosaic_threshold(image, radius=None, figsize=(8, 5), verbose=True): methods['Local Otsu'] = thresh(local_otsu) block_size = 2 * int(radius) + 1 - adaptive_threshold = include_selem(threshold_adaptive, block_size, offset=10) + adaptive_threshold = include_selem(threshold_adaptive, block_size, + offset=10) methods['Adaptive threshold'] = adaptive_threshold - - return _mosaic(image, figsize=figsize, - methods=methods, verbose=verbose) + return _try_all(image, figsize=figsize, + methods=methods, verbose=verbose) __all__ = ['threshold_adaptive', 'threshold_otsu', From 690db877fd3737c58e4a8f12c6833659afbbcb58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Boulogne?= Date: Thu, 2 Jun 2016 17:43:44 +0200 Subject: [PATCH 06/19] Add threshold_minimum to try_all --- skimage/filters/thresholding.py | 1 + 1 file changed, 1 insertion(+) diff --git a/skimage/filters/thresholding.py b/skimage/filters/thresholding.py index eb21ffbb..06dd5cbc 100644 --- a/skimage/filters/thresholding.py +++ b/skimage/filters/thresholding.py @@ -131,6 +131,7 @@ def try_all_threshold(image, radius=None, figsize=(8, 5), verbose=True): # Global algorithms. methods = OrderedDict({'Isodata': thresh(threshold_isodata), 'Li': thresh(threshold_li), + 'Minimum': thresh(threshold_minimum), 'Otsu': thresh(threshold_otsu), 'Yen': thresh(threshold_yen)}) From 0a19def60c25f95033edf434aac936ade7de1eff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Boulogne?= Date: Sun, 5 Jun 2016 16:02:01 +0200 Subject: [PATCH 07/19] DOC: Gather threshold algo in gallery --- .../filters/plot_threshold_minimum.py | 36 --- doc/examples/segmentation/plot_local_otsu.py | 60 ---- .../segmentation/plot_threshold_adaptive.py | 48 ---- .../segmentation/plot_thresholding.py | 84 ++---- .../xx_applications/plot_thresholding.py | 263 ++++++++++++++++++ 5 files changed, 293 insertions(+), 198 deletions(-) delete mode 100644 doc/examples/filters/plot_threshold_minimum.py delete mode 100644 doc/examples/segmentation/plot_local_otsu.py delete mode 100644 doc/examples/segmentation/plot_threshold_adaptive.py create mode 100644 doc/examples/xx_applications/plot_thresholding.py diff --git a/doc/examples/filters/plot_threshold_minimum.py b/doc/examples/filters/plot_threshold_minimum.py deleted file mode 100644 index 950d34d2..00000000 --- a/doc/examples/filters/plot_threshold_minimum.py +++ /dev/null @@ -1,36 +0,0 @@ -""" -================================== -Minimum Algorithm For Thresholding -================================== - -The minimum algorithm takes a histogram of the image and smooths it -repeatedly until there are only two peaks in the histogram. Then it -finds the minimum value between the two peaks. After smoothing the -histogram, there can be multiple pixel values with the minimum histogram -count, so you can pick the 'min', 'mid', or 'max' of these values. - -""" -import matplotlib.pyplot as plt - -from skimage import data -from skimage.filters.thresholding import threshold_minimum - -image = data.camera() - -threshold = threshold_minimum(image, bias='min') -binarized = image > threshold - -fig, axes = plt.subplots(nrows=2, figsize=(7, 8)) -ax0, ax1 = axes -plt.gray() - -ax0.imshow(image) -ax0.set_title('Original image') - -ax1.imshow(binarized) -ax1.set_title('Result') - -for ax in axes: - ax.axis('off') - -plt.show() diff --git a/doc/examples/segmentation/plot_local_otsu.py b/doc/examples/segmentation/plot_local_otsu.py deleted file mode 100644 index e51ef5e9..00000000 --- a/doc/examples/segmentation/plot_local_otsu.py +++ /dev/null @@ -1,60 +0,0 @@ -""" -==================== -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 is much slower than global thresholding - -.. [1] http://en.wikipedia.org/wiki/Otsu's_method - -""" - -from skimage import data -from skimage.morphology import disk -from skimage.filters import threshold_otsu, rank -from skimage.util import img_as_ubyte - -import matplotlib -import matplotlib.pyplot as plt - -matplotlib.rcParams['font.size'] = 9 -img = img_as_ubyte(data.page()) - -radius = 15 -selem = disk(radius) - -local_otsu = rank.otsu(img, selem) -threshold_global_otsu = threshold_otsu(img) -global_otsu = img >= threshold_global_otsu - -fig, ax = plt.subplots(2, 2, figsize=(8, 5), sharex=True, sharey=True, - subplot_kw={'adjustable': 'box-forced'}) -ax0, ax1, ax2, ax3 = ax.ravel() -plt.tight_layout() - -fig.colorbar(ax0.imshow(img, cmap=plt.cm.gray), - ax=ax0, orientation='horizontal') -ax0.set_title('Original') -ax0.axis('off') - -fig.colorbar(ax1.imshow(local_otsu, cmap=plt.cm.gray), - ax=ax1, orientation='horizontal') -ax1.set_title('Local Otsu (radius=%d)' % radius) -ax1.axis('off') - -ax2.imshow(img >= local_otsu, cmap=plt.cm.gray) -ax2.set_title('Original >= Local Otsu' % threshold_global_otsu) -ax2.axis('off') - -ax3.imshow(global_otsu, cmap=plt.cm.gray) -ax3.set_title('Global Otsu (threshold = %d)' % threshold_global_otsu) -ax3.axis('off') - -plt.show() diff --git a/doc/examples/segmentation/plot_threshold_adaptive.py b/doc/examples/segmentation/plot_threshold_adaptive.py deleted file mode 100644 index 6f473abb..00000000 --- a/doc/examples/segmentation/plot_threshold_adaptive.py +++ /dev/null @@ -1,48 +0,0 @@ -""" -===================== -Adaptive Thresholding -===================== - -Thresholding is the simplest way to segment objects from a background. If that -background is relatively uniform, then you can use a global threshold value to -binarize the image by pixel-intensity. If there's large variation in the -background intensity, however, adaptive thresholding (a.k.a. local or dynamic -thresholding) may produce better results. - -Here, we binarize an image using the `threshold_adaptive` function, which -calculates thresholds in regions of size `block_size` surrounding each pixel -(i.e. local neighborhoods). Each threshold value is the weighted mean of the -local neighborhood minus an offset value. - -""" -import matplotlib.pyplot as plt - -from skimage import data -from skimage.filters import threshold_otsu, threshold_adaptive - - -image = data.page() - -global_thresh = threshold_otsu(image) -binary_global = image > global_thresh - -block_size = 35 -binary_adaptive = threshold_adaptive(image, block_size, offset=10) - -fig, axes = plt.subplots(nrows=3, figsize=(7, 8)) -ax0, ax1, ax2 = axes -plt.gray() - -ax0.imshow(image) -ax0.set_title('Image') - -ax1.imshow(binary_global) -ax1.set_title('Global thresholding') - -ax2.imshow(binary_adaptive) -ax2.set_title('Adaptive thresholding') - -for ax in axes: - ax.axis('off') - -plt.show() diff --git a/doc/examples/segmentation/plot_thresholding.py b/doc/examples/segmentation/plot_thresholding.py index 8b1cae13..b5ca6419 100644 --- a/doc/examples/segmentation/plot_thresholding.py +++ b/doc/examples/segmentation/plot_thresholding.py @@ -4,17 +4,10 @@ Thresholding ============ Thresholding is used to create a binary image from a grayscale image [1]_. - -Thresholding algorithms can be separated in two categories: - -- Histogram-based. The histogram of the pixel intensity is used and - assumptions may be made on the properties of this histogram (e.g. bimodal). -- Local. To process a pixel, only the neighboring pixels are used. - These algorithms often require more computation time. - - -Scikit-image includes a function to test thresholding algorithms provided -in the library. Therefore, in a glance, you can select the best algorithm +If you are not familiar with the details of the different algorithms and the +underlying assumptions, it is often to know which algorithm will give the best +results. Therefore, Scikit-image includes a function to test thresholding algorithms +provided in the library. At a glance, you can select the best algorithm for you data, without a deep understanding of their mechanisms. .. [1] https://en.wikipedia.org/wiki/Thresholding_%28image_processing%29 @@ -23,10 +16,10 @@ for you data, without a deep understanding of their mechanisms. import matplotlib import matplotlib.pyplot as plt -from skimage.data import page +from skimage import data from skimage.filters import thresholding -img = page() +img = data.page() # Here, we specify a radius for local thresholding algorithm. # If it is not specified, only global algorithms are called. @@ -35,52 +28,35 @@ fig, ax = thresholding.try_all_threshold(img, radius=20, plt.show() """ - .. image:: PLOT2RST.current_figure +How to apply a threshold? +========================= + Now, we illustrate how to apply one of these thresholding algorithms -This example uses Otsu's method [2]_. - -Otsu's method calculates an "optimal" threshold (marked by a red line in the -histogram below) by maximizing the variance between two classes of pixels, -which are separated by the threshold. Equivalently, this threshold minimizes -the intra-class variance. - -.. [2] http://en.wikipedia.org/wiki/Otsu's_method - +This example uses the mean value of pixel intensities. It is a simple +and naive threshold value, which is sometimes used as a guess value. """ -import matplotlib -import matplotlib.pyplot as plt -from skimage.data import camera -from skimage.filters import threshold_otsu - - -matplotlib.rcParams['font.size'] = 9 - - -image = camera() -thresh = threshold_otsu(image) -binary = image > thresh - -fig = plt.figure(figsize=(8, 2.5)) -ax1 = plt.subplot(1, 3, 1, adjustable='box-forced') -ax2 = plt.subplot(1, 3, 2) -ax3 = plt.subplot(1, 3, 3, sharex=ax1, sharey=ax1, adjustable='box-forced') - -ax1.imshow(image, cmap=plt.cm.gray) -ax1.set_title('Original') -ax1.axis('off') - -ax2.hist(image) -ax2.set_title('Histogram') -ax2.axvline(thresh, color='r') - -ax3.imshow(binary, cmap=plt.cm.gray) -ax3.set_title('Thresholded') -ax3.axis('off') - -plt.show() +#from skimage.filters.thresholding import threshold_mean +#from skimage import data +#image = data.camera() +#thresh = threshold_mean(image) +#binary = image > thresh +# +#fig, axes = plt.subplots(nrows=2, figsize=(7, 8)) +#ax0, ax1 = axes +# +#ax0.imshow(image) +#ax0.set_title('Original image') +# +#ax1.imshow(binary) +#ax1.set_title('Result') +# +#for ax in axes: +# ax.axis('off') +# +#plt.show() """ .. image:: PLOT2RST.current_figure diff --git a/doc/examples/xx_applications/plot_thresholding.py b/doc/examples/xx_applications/plot_thresholding.py new file mode 100644 index 00000000..1c2ddcf0 --- /dev/null +++ b/doc/examples/xx_applications/plot_thresholding.py @@ -0,0 +1,263 @@ +""" +============ +Thresholding +============ + +Thresholding is used to create a binary image from a grayscale image [1]_. +It is the simplest way to segment objects from a background. + +Thresholding algorithms implemented in scikit-image can be separated in two +categories: + +- Histogram-based. The histogram of the pixel intensity is used and + assumptions may be made on the properties of this histogram (e.g. bimodal). +- Local. To process a pixel, only the neighboring pixels are used. + These algorithms often require more computation time. + + +If you are not familiar with the details of the different algorithms and the +underlying assumptions, it is often to know which algorithm will give the best +results. Therefore, Scikit-image includes a function to test thresholding +algorithms provided in the library. At a glance, you can select the best +algorithm for you data, without a deep understanding of their mechanisms. + +.. [1] https://en.wikipedia.org/wiki/Thresholding_%28image_processing%29 + +""" +import matplotlib +import matplotlib.pyplot as plt + +from skimage import data +from skimage.filters import thresholding + +img = data.page() + +# Here, we specify a radius for local thresholding algorithm. +# If it is not specified, only global algorithms are called. +fig, ax = thresholding.try_all_threshold(img, radius=20, + figsize=(10, 8), verbose=False) +plt.show() + +""" +.. image:: PLOT2RST.current_figure + +How to apply a threshold? +========================= + +Now, we illustrate how to apply one of these thresholding algorithms +This example uses the mean value of pixel intensities. It is a simple +and naive threshold value, which is sometimes used as a guess value. +""" + +#from skimage.filters.thresholding import threshold_mean +#from skimage import data +#image = data.camera() +#thresh = threshold_mean(image) +#binary = image > thresh +# +#fig, axes = plt.subplots(nrows=2, figsize=(7, 8)) +#ax0, ax1 = axes +# +#ax0.imshow(image) +#ax0.set_title('Original image') +# +#ax1.imshow(binary) +#ax1.set_title('Result') +# +#for ax in axes: +# ax.axis('off') +# +#plt.show() + +""" +.. image:: PLOT2RST.current_figure + +Bimodal histogram +================= + +For pictures with a bimodal histogram, more specific algorithms can be used. +For instance, the minimum algorithm takes a histogram of the image and smooths it +repeatedly until there are only two peaks in the histogram. Then it +finds the minimum value between the two peaks. After smoothing the +histogram, there can be multiple pixel values with the minimum histogram +count, so you can pick the 'min', 'mid', or 'max' of these values. + +""" +import matplotlib.pyplot as plt + +from skimage import data +from skimage.filters.thresholding import threshold_minimum + +image = data.camera() + +thresh = threshold_minimum(image, bias='min') +binary = image > thresh + +fig = plt.figure(figsize=(8, 2.5)) +ax1 = plt.subplot(1, 3, 1, adjustable='box-forced') +ax2 = plt.subplot(1, 3, 2) +ax3 = plt.subplot(1, 3, 3, sharex=ax1, sharey=ax1, adjustable='box-forced') + +ax1.imshow(image, cmap=plt.cm.gray) +ax1.set_title('Original') +ax1.axis('off') + +ax2.hist(image) +ax2.set_title('Histogram') +ax2.axvline(thresh, color='r') + +ax3.imshow(binary, cmap=plt.cm.gray) +ax3.set_title('Thresholded') +ax3.axis('off') + +plt.show() + +""" + +.. image:: PLOT2RST.current_figure + +Otsu's method [2]_ calculates an "optimal" threshold (marked by a red line in the +histogram below) by maximizing the variance between two classes of pixels, +which are separated by the threshold. Equivalently, this threshold minimizes +the intra-class variance. + +.. [2] http://en.wikipedia.org/wiki/Otsu's_method + +""" +import matplotlib +import matplotlib.pyplot as plt + +from skimage import data +from skimage.filters import threshold_otsu + + +matplotlib.rcParams['font.size'] = 9 + + +image = data.camera() +thresh = threshold_otsu(image) +binary = image > thresh + +fig = plt.figure(figsize=(8, 2.5)) +ax1 = plt.subplot(1, 3, 1, adjustable='box-forced') +ax2 = plt.subplot(1, 3, 2) +ax3 = plt.subplot(1, 3, 3, sharex=ax1, sharey=ax1, adjustable='box-forced') + +ax1.imshow(image, cmap=plt.cm.gray) +ax1.set_title('Original') +ax1.axis('off') + +ax2.hist(image) +ax2.set_title('Histogram') +ax2.axvline(thresh, color='r') + +ax3.imshow(binary, cmap=plt.cm.gray) +ax3.set_title('Thresholded') +ax3.axis('off') + +plt.show() + +""" +.. image:: PLOT2RST.current_figure + +Local thresholding +================== + +If the image background is relatively uniform, then you can use a global +threshold value as presented above. However, if there is large variation in the +background intensity, adaptive thresholding (a.k.a. local or dynamic +thresholding) may produce better results. Note that local is much slower than +global thresholding + +Here, we binarize an image using the `threshold_adaptive` function, which +calculates thresholds in regions of size `block_size` surrounding each pixel +(i.e. local neighborhoods). Each threshold value is the weighted mean of the +local neighborhood minus an offset value. + +""" +import matplotlib.pyplot as plt + +from skimage import data +from skimage.filters import threshold_otsu, threshold_adaptive + + +image = data.page() + +global_thresh = threshold_otsu(image) +binary_global = image > global_thresh + +block_size = 35 +binary_adaptive = threshold_adaptive(image, block_size, offset=10) + +fig, axes = plt.subplots(nrows=3, figsize=(7, 8)) +ax0, ax1, ax2 = axes +plt.gray() + +ax0.imshow(image) +ax0.set_title('Original') + +ax1.imshow(binary_global) +ax1.set_title('Global thresholding') + +ax2.imshow(binary_adaptive) +ax2.set_title('Adaptive thresholding') + +for ax in axes: + ax.axis('off') + +plt.show() + +""" +.. image:: PLOT2RST.current_figure + +Now, we show how Otsu's threshold [2]_ 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. + +""" + +from skimage import data +from skimage.morphology import disk +from skimage.filters import threshold_otsu, rank +from skimage.util import img_as_ubyte + +import matplotlib +import matplotlib.pyplot as plt + +matplotlib.rcParams['font.size'] = 9 +img = img_as_ubyte(data.page()) + +radius = 15 +selem = disk(radius) + +local_otsu = rank.otsu(img, selem) +threshold_global_otsu = threshold_otsu(img) +global_otsu = img >= threshold_global_otsu + +fig, ax = plt.subplots(2, 2, figsize=(8, 5), sharex=True, sharey=True, + subplot_kw={'adjustable': 'box-forced'}) +ax0, ax1, ax2, ax3 = ax.ravel() +plt.tight_layout() + +fig.colorbar(ax0.imshow(img, cmap=plt.cm.gray), + ax=ax0, orientation='horizontal') +ax0.set_title('Original') +ax0.axis('off') + +fig.colorbar(ax1.imshow(local_otsu, cmap=plt.cm.gray), + ax=ax1, orientation='horizontal') +ax1.set_title('Local Otsu (radius=%d)' % radius) +ax1.axis('off') + +ax2.imshow(img >= local_otsu, cmap=plt.cm.gray) +ax2.set_title('Original >= Local Otsu' % threshold_global_otsu) +ax2.axis('off') + +ax3.imshow(global_otsu, cmap=plt.cm.gray) +ax3.set_title('Global Otsu (threshold = %d)' % threshold_global_otsu) +ax3.axis('off') + +plt.show() From 36d56b956dfb24657ad5533417914477c959ada2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Boulogne?= Date: Sun, 5 Jun 2016 17:17:34 +0200 Subject: [PATCH 08/19] DOC: some improvements --- .../xx_applications/plot_thresholding.py | 51 +++++++++++++------ 1 file changed, 35 insertions(+), 16 deletions(-) diff --git a/doc/examples/xx_applications/plot_thresholding.py b/doc/examples/xx_applications/plot_thresholding.py index 1c2ddcf0..0f4ac45b 100644 --- a/doc/examples/xx_applications/plot_thresholding.py +++ b/doc/examples/xx_applications/plot_thresholding.py @@ -90,26 +90,41 @@ from skimage.filters.thresholding import threshold_minimum image = data.camera() -thresh = threshold_minimum(image, bias='min') -binary = image > thresh +thresh_min = threshold_minimum(image, bias='min') +binary_min = image > thresh_min +thresh_mid = threshold_minimum(image, bias='mid') +binary_mid = image > thresh_mid +thresh_max = threshold_minimum(image, bias='max') +binary_max = image > thresh_max -fig = plt.figure(figsize=(8, 2.5)) -ax1 = plt.subplot(1, 3, 1, adjustable='box-forced') -ax2 = plt.subplot(1, 3, 2) -ax3 = plt.subplot(1, 3, 3, sharex=ax1, sharey=ax1, adjustable='box-forced') +fig, ax = plt.subplots(4, 2, figsize=(10, 10)) +axes = ax.ravel() -ax1.imshow(image, cmap=plt.cm.gray) -ax1.set_title('Original') -ax1.axis('off') +axes[0].imshow(image, cmap=plt.cm.gray) +axes[0].set_title('Original') +axes[0].axis('off') -ax2.hist(image) -ax2.set_title('Histogram') -ax2.axvline(thresh, color='r') +axes[1].hist(image.ravel(), bins=256) +axes[1].set_title('Histogram') -ax3.imshow(binary, cmap=plt.cm.gray) -ax3.set_title('Thresholded') -ax3.axis('off') +axes[2].imshow(binary_min, cmap=plt.cm.gray) +axes[2].set_title('Thresholded (min)') +axes[3].hist(image.ravel(), bins=256) +axes[3].axvline(thresh_min, color='r') + +axes[4].imshow(binary_mid, cmap=plt.cm.gray) +axes[4].set_title('Thresholded (mid)') +axes[5].hist(image.ravel(), bins=256) +axes[5].axvline(thresh_mid, color='r') + +axes[6].imshow(binary_max, cmap=plt.cm.gray) +axes[6].set_title('Thresholded (max)') +axes[7].hist(image.ravel(), bins=256) +axes[7].axvline(thresh_max, color='r') + +for a in axes[::2]: + a.axis('off') plt.show() """ @@ -147,7 +162,7 @@ ax1.imshow(image, cmap=plt.cm.gray) ax1.set_title('Original') ax1.axis('off') -ax2.hist(image) +ax2.hist(image.ravel(), bins=256) ax2.set_title('Histogram') ax2.axvline(thresh, color='r') @@ -261,3 +276,7 @@ ax3.set_title('Global Otsu (threshold = %d)' % threshold_global_otsu) ax3.axis('off') plt.show() +""" +.. image:: PLOT2RST.current_figure + +""" From b66c010eabe7b59f4455b82bd0734ea422cbd6d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Boulogne?= Date: Sun, 5 Jun 2016 17:20:33 +0200 Subject: [PATCH 09/19] DOC: add minimum to the list --- skimage/filters/thresholding.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/skimage/filters/thresholding.py b/skimage/filters/thresholding.py index 06dd5cbc..61ff319d 100644 --- a/skimage/filters/thresholding.py +++ b/skimage/filters/thresholding.py @@ -91,8 +91,9 @@ def try_all_threshold(image, radius=None, figsize=(8, 5), verbose=True): The following algorithms are used: * isodata - * otsu * li + * minimum + * otsu * yen * adaptive threshold (local) * rank otsu (local) From c8f0611a5442c37214c01f4a1a1fcd5824b82466 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Boulogne?= Date: Fri, 10 Jun 2016 11:03:16 +0200 Subject: [PATCH 10/19] ADD mean and triangle thres --- skimage/filters/thresholding.py | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/skimage/filters/thresholding.py b/skimage/filters/thresholding.py index 61ff319d..3b226779 100644 --- a/skimage/filters/thresholding.py +++ b/skimage/filters/thresholding.py @@ -9,14 +9,15 @@ from .._shared.utils import assert_nD, warn from ..morphology import disk from ..filters.rank import otsu - __all__ = ['try_all_threshold', 'threshold_adaptive', 'threshold_otsu', 'threshold_yen', 'threshold_isodata', 'threshold_li', - 'threshold_minimum', ] + 'threshold_minimum', + 'threshold_mean', + 'threshold_triangle'] def _try_all(image, methods=None, figsize=None, num_cols=2, verbose=True): @@ -92,8 +93,10 @@ def try_all_threshold(image, radius=None, figsize=(8, 5), verbose=True): * isodata * li + * mean * minimum * otsu + * triangle * yen * adaptive threshold (local) * rank otsu (local) @@ -132,8 +135,10 @@ def try_all_threshold(image, radius=None, figsize=(8, 5), verbose=True): # Global algorithms. methods = OrderedDict({'Isodata': thresh(threshold_isodata), 'Li': thresh(threshold_li), + 'Mean': thresh(threshold_mean), 'Minimum': thresh(threshold_minimum), 'Otsu': thresh(threshold_otsu), + 'Triangle': thresh(threshold_triangle), 'Yen': thresh(threshold_yen)}) # Local algorithms. @@ -150,15 +155,6 @@ def try_all_threshold(image, radius=None, figsize=(8, 5), verbose=True): return _try_all(image, figsize=figsize, methods=methods, verbose=verbose) -__all__ = ['threshold_adaptive', - 'threshold_otsu', - 'threshold_yen', - 'threshold_isodata', - 'threshold_li', - 'threshold_minimum', - 'threshold_mean', - 'threshold_triangle'] - def threshold_adaptive(image, block_size, method='gaussian', offset=0, mode='reflect', param=None): @@ -288,8 +284,8 @@ def threshold_otsu(image, nbins=256): # Check if the image is multi-colored or not if image.min() == image.max(): - raise ValueError("threshold_otsu is expected to work with images " \ - "having more than one color. The input image seems " \ + raise ValueError("threshold_otsu is expected to work with images " + "having more than one color. The input image seems " "to have just one color {0}.".format(image.min())) hist, bin_centers = histogram(image.ravel(), nbins) From 6442bf5f0c2e8aa4c77438c7e90adf3014e9bc56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Boulogne?= Date: Fri, 10 Jun 2016 11:50:07 +0200 Subject: [PATCH 11/19] Use gray cmap --- skimage/filters/thresholding.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/skimage/filters/thresholding.py b/skimage/filters/thresholding.py index 3b226779..3fac4a26 100644 --- a/skimage/filters/thresholding.py +++ b/skimage/filters/thresholding.py @@ -49,12 +49,12 @@ def _try_all(image, methods=None, figsize=None, num_cols=2, verbose=True): subplot_kw={'adjustable': 'box-forced'}) ax = ax.ravel() - ax[0].imshow(image) + ax[0].imshow(image, cmap=plt.cm.gray) ax[0].set_title('Original') i = 1 for name, func in methods.items(): - ax[i].imshow(func(image)) + ax[i].imshow(func(image), cmap=plt.cm.gray) ax[i].set_title(name) i += 1 if verbose: From 476f6bd8f289a8cbde9f9a27f05e29b2a2a9ee25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Boulogne?= Date: Fri, 10 Jun 2016 11:52:45 +0200 Subject: [PATCH 12/19] switch doc format to sphinx-gallery --- .../segmentation/plot_thresholding.py | 67 ++-- .../xx_applications/plot_thresholding.py | 287 ++++++++---------- 2 files changed, 165 insertions(+), 189 deletions(-) diff --git a/doc/examples/segmentation/plot_thresholding.py b/doc/examples/segmentation/plot_thresholding.py index b5ca6419..51c1324a 100644 --- a/doc/examples/segmentation/plot_thresholding.py +++ b/doc/examples/segmentation/plot_thresholding.py @@ -5,10 +5,11 @@ Thresholding Thresholding is used to create a binary image from a grayscale image [1]_. If you are not familiar with the details of the different algorithms and the -underlying assumptions, it is often to know which algorithm will give the best -results. Therefore, Scikit-image includes a function to test thresholding algorithms -provided in the library. At a glance, you can select the best algorithm -for you data, without a deep understanding of their mechanisms. +underlying assumptions, it is often difficult to know which algorithm will give +the best results. Therefore, Scikit-image includes a function to evaluate +thresholding algorithms provided by the library. At a glance, you can select +the best algorithm for you data without a deep understanding of their +mechanisms. .. [1] https://en.wikipedia.org/wiki/Thresholding_%28image_processing%29 @@ -21,43 +22,37 @@ from skimage.filters import thresholding img = data.page() -# Here, we specify a radius for local thresholding algorithm. +# Here, we specify a radius for local thresholding algorithms. # If it is not specified, only global algorithms are called. fig, ax = thresholding.try_all_threshold(img, radius=20, - figsize=(10,8), verbose=False) + figsize=(10, 8), verbose=False) plt.show() -""" -.. image:: PLOT2RST.current_figure +###################################################################### +# How to apply a threshold? +# ========================= +# +# Now, we illustrate how to apply one of these thresholding algorithms. +# This example uses the mean value of pixel intensities. It is a simple +# and naive threshold value, which is sometimes used as a guess value. -How to apply a threshold? -========================= +from skimage.filters.thresholding import threshold_mean +from skimage import data -Now, we illustrate how to apply one of these thresholding algorithms -This example uses the mean value of pixel intensities. It is a simple -and naive threshold value, which is sometimes used as a guess value. -""" +image = data.camera() +thresh = threshold_mean(image) +binary = image > thresh -#from skimage.filters.thresholding import threshold_mean -#from skimage import data -#image = data.camera() -#thresh = threshold_mean(image) -#binary = image > thresh -# -#fig, axes = plt.subplots(nrows=2, figsize=(7, 8)) -#ax0, ax1 = axes -# -#ax0.imshow(image) -#ax0.set_title('Original image') -# -#ax1.imshow(binary) -#ax1.set_title('Result') -# -#for ax in axes: -# ax.axis('off') -# -#plt.show() +fig, axes = plt.subplots(ncols=2, figsize=(8, 3)) +ax = axes.ravel() -""" -.. image:: PLOT2RST.current_figure -""" +ax[0].imshow(image, cmap=plt.cm.gray) +ax[0].set_title('Original image') + +ax[1].imshow(binary, cmap=plt.cm.gray) +ax[1].set_title('Result') + +for a in ax: + a.axis('off') + +plt.show() diff --git a/doc/examples/xx_applications/plot_thresholding.py b/doc/examples/xx_applications/plot_thresholding.py index 0f4ac45b..e20a51a4 100644 --- a/doc/examples/xx_applications/plot_thresholding.py +++ b/doc/examples/xx_applications/plot_thresholding.py @@ -9,17 +9,18 @@ It is the simplest way to segment objects from a background. Thresholding algorithms implemented in scikit-image can be separated in two categories: -- Histogram-based. The histogram of the pixel intensity is used and - assumptions may be made on the properties of this histogram (e.g. bimodal). +- Histogram-based. The histogram of the pixels' intensity is used and + certain assumptions are made on the properties of this histogram (e.g. bimodal). - Local. To process a pixel, only the neighboring pixels are used. These algorithms often require more computation time. If you are not familiar with the details of the different algorithms and the -underlying assumptions, it is often to know which algorithm will give the best -results. Therefore, Scikit-image includes a function to test thresholding -algorithms provided in the library. At a glance, you can select the best -algorithm for you data, without a deep understanding of their mechanisms. +underlying assumptions, it is often difficult to know which algorithm will give +the best results. Therefore, Scikit-image includes a function to evaluate +thresholding algorithms provided by the library. At a glance, you can select +the best algorithm for you data without a deep understanding of their +mechanisms. .. [1] https://en.wikipedia.org/wiki/Thresholding_%28image_processing%29 @@ -32,62 +33,59 @@ from skimage.filters import thresholding img = data.page() -# Here, we specify a radius for local thresholding algorithm. +# Here, we specify a radius for local thresholding algorithms. # If it is not specified, only global algorithms are called. fig, ax = thresholding.try_all_threshold(img, radius=20, figsize=(10, 8), verbose=False) plt.show() -""" -.. image:: PLOT2RST.current_figure - -How to apply a threshold? -========================= - -Now, we illustrate how to apply one of these thresholding algorithms -This example uses the mean value of pixel intensities. It is a simple -and naive threshold value, which is sometimes used as a guess value. -""" - -#from skimage.filters.thresholding import threshold_mean -#from skimage import data -#image = data.camera() -#thresh = threshold_mean(image) -#binary = image > thresh +###################################################################### +# How to apply a threshold? +# ========================= # -#fig, axes = plt.subplots(nrows=2, figsize=(7, 8)) -#ax0, ax1 = axes -# -#ax0.imshow(image) -#ax0.set_title('Original image') -# -#ax1.imshow(binary) -#ax1.set_title('Result') -# -#for ax in axes: -# ax.axis('off') -# -#plt.show() +# Now, we illustrate how to apply one of these thresholding algorithms. +# This example uses the mean value of pixel intensities. It is a simple +# and naive threshold value, which is sometimes used as a guess value. -""" -.. image:: PLOT2RST.current_figure +from skimage.filters.thresholding import threshold_mean +from skimage import data -Bimodal histogram -================= -For pictures with a bimodal histogram, more specific algorithms can be used. -For instance, the minimum algorithm takes a histogram of the image and smooths it -repeatedly until there are only two peaks in the histogram. Then it -finds the minimum value between the two peaks. After smoothing the -histogram, there can be multiple pixel values with the minimum histogram -count, so you can pick the 'min', 'mid', or 'max' of these values. +image = data.camera() +thresh = threshold_mean(image) +binary = image > thresh + +fig, axes = plt.subplots(ncols=2, figsize=(8, 3)) +ax = axes.ravel() + +ax[0].imshow(image, cmap=plt.cm.gray) +ax[0].set_title('Original image') + +ax[1].imshow(binary, cmap=plt.cm.gray) +ax[1].set_title('Result') + +for a in ax: + a.axis('off') + +plt.show() + +###################################################################### +# Bimodal histogram +# ================= +# +# For pictures with a bimodal histogram, more specific algorithms can be used. +# For instance, the minimum algorithm takes a histogram of the image and smooths it +# repeatedly until there are only two peaks in the histogram. Then it +# finds the minimum value between the two peaks. After smoothing the +# histogram, there can be multiple pixel values with the minimum histogram +# count, so you can pick the 'min', 'mid', or 'max' of these values. -""" import matplotlib.pyplot as plt from skimage import data from skimage.filters.thresholding import threshold_minimum + image = data.camera() thresh_min = threshold_minimum(image, bias='min') @@ -97,48 +95,44 @@ binary_mid = image > thresh_mid thresh_max = threshold_minimum(image, bias='max') binary_max = image > thresh_max -fig, ax = plt.subplots(4, 2, figsize=(10, 10)) -axes = ax.ravel() +fig, axes = plt.subplots(4, 2, figsize=(10, 10)) +ax = axes.ravel() -axes[0].imshow(image, cmap=plt.cm.gray) -axes[0].set_title('Original') -axes[0].axis('off') +ax[0].imshow(image, cmap=plt.cm.gray) +ax[0].set_title('Original') +ax[0].axis('off') -axes[1].hist(image.ravel(), bins=256) -axes[1].set_title('Histogram') +ax[1].hist(image.ravel(), bins=256) +ax[1].set_title('Histogram') -axes[2].imshow(binary_min, cmap=plt.cm.gray) -axes[2].set_title('Thresholded (min)') +ax[2].imshow(binary_min, cmap=plt.cm.gray) +ax[2].set_title('Thresholded (min)') -axes[3].hist(image.ravel(), bins=256) -axes[3].axvline(thresh_min, color='r') +ax[3].hist(image.ravel(), bins=256) +ax[3].axvline(thresh_min, color='r') -axes[4].imshow(binary_mid, cmap=plt.cm.gray) -axes[4].set_title('Thresholded (mid)') -axes[5].hist(image.ravel(), bins=256) -axes[5].axvline(thresh_mid, color='r') +ax[4].imshow(binary_mid, cmap=plt.cm.gray) +ax[4].set_title('Thresholded (mid)') +ax[5].hist(image.ravel(), bins=256) +ax[5].axvline(thresh_mid, color='r') -axes[6].imshow(binary_max, cmap=plt.cm.gray) -axes[6].set_title('Thresholded (max)') -axes[7].hist(image.ravel(), bins=256) -axes[7].axvline(thresh_max, color='r') +ax[6].imshow(binary_max, cmap=plt.cm.gray) +ax[6].set_title('Thresholded (max)') +ax[7].hist(image.ravel(), bins=256) +ax[7].axvline(thresh_max, color='r') -for a in axes[::2]: +for a in ax[::2]: a.axis('off') plt.show() -""" +###################################################################### +# Otsu's method [2]_ calculates an "optimal" threshold (marked by a red line in the +# histogram below) by maximizing the variance between two classes of pixels, +# which are separated by the threshold. Equivalently, this threshold minimizes +# the intra-class variance. +# +# .. [2] http://en.wikipedia.org/wiki/Otsu's_method -.. image:: PLOT2RST.current_figure - -Otsu's method [2]_ calculates an "optimal" threshold (marked by a red line in the -histogram below) by maximizing the variance between two classes of pixels, -which are separated by the threshold. Equivalently, this threshold minimizes -the intra-class variance. - -.. [2] http://en.wikipedia.org/wiki/Otsu's_method - -""" import matplotlib import matplotlib.pyplot as plt @@ -146,50 +140,45 @@ from skimage import data from skimage.filters import threshold_otsu -matplotlib.rcParams['font.size'] = 9 - - image = data.camera() thresh = threshold_otsu(image) binary = image > thresh -fig = plt.figure(figsize=(8, 2.5)) -ax1 = plt.subplot(1, 3, 1, adjustable='box-forced') -ax2 = plt.subplot(1, 3, 2) -ax3 = plt.subplot(1, 3, 3, sharex=ax1, sharey=ax1, adjustable='box-forced') +fig, axes = plt.subplots(ncols=3, figsize=(8, 2.5)) +ax = axes.ravel() +ax[0] = plt.subplot(1, 3, 1, adjustable='box-forced') +ax[1] = plt.subplot(1, 3, 2) +ax[2] = plt.subplot(1, 3, 3, sharex=ax[0], sharey=ax[0], adjustable='box-forced') -ax1.imshow(image, cmap=plt.cm.gray) -ax1.set_title('Original') -ax1.axis('off') +ax[0].imshow(image, cmap=plt.cm.gray) +ax[0].set_title('Original') +ax[0].axis('off') -ax2.hist(image.ravel(), bins=256) -ax2.set_title('Histogram') -ax2.axvline(thresh, color='r') +ax[1].hist(image.ravel(), bins=256) +ax[1].set_title('Histogram') +ax[1].axvline(thresh, color='r') -ax3.imshow(binary, cmap=plt.cm.gray) -ax3.set_title('Thresholded') -ax3.axis('off') +ax[2].imshow(binary, cmap=plt.cm.gray) +ax[2].set_title('Thresholded') +ax[2].axis('off') plt.show() -""" -.. image:: PLOT2RST.current_figure +###################################################################### +# Local thresholding +# ================== +# +# If the image background is relatively uniform, then you can use a global +# threshold value as presented above. However, if there is large variation in the +# background intensity, adaptive thresholding (a.k.a. local or dynamic +# thresholding) may produce better results. Note that local is much slower than +# global thresholding. +# +# Here, we binarize an image using the `threshold_adaptive` function, which +# calculates thresholds in regions with a characteristic size `block_size` surrounding +# each pixel (i.e. local neighborhoods). Each threshold value is the weighted mean +# of the local neighborhood minus an offset value. -Local thresholding -================== - -If the image background is relatively uniform, then you can use a global -threshold value as presented above. However, if there is large variation in the -background intensity, adaptive thresholding (a.k.a. local or dynamic -thresholding) may produce better results. Note that local is much slower than -global thresholding - -Here, we binarize an image using the `threshold_adaptive` function, which -calculates thresholds in regions of size `block_size` surrounding each pixel -(i.e. local neighborhoods). Each threshold value is the weighted mean of the -local neighborhood minus an offset value. - -""" import matplotlib.pyplot as plt from skimage import data @@ -205,34 +194,30 @@ block_size = 35 binary_adaptive = threshold_adaptive(image, block_size, offset=10) fig, axes = plt.subplots(nrows=3, figsize=(7, 8)) -ax0, ax1, ax2 = axes +ax = axes.ravel() plt.gray() -ax0.imshow(image) -ax0.set_title('Original') +ax[0].imshow(image) +ax[0].set_title('Original') -ax1.imshow(binary_global) -ax1.set_title('Global thresholding') +ax[1].imshow(binary_global) +ax[1].set_title('Global thresholding') -ax2.imshow(binary_adaptive) -ax2.set_title('Adaptive thresholding') +ax[2].imshow(binary_adaptive) +ax[2].set_title('Adaptive thresholding') -for ax in axes: - ax.axis('off') +for a in ax: + a.axis('off') plt.show() -""" -.. image:: PLOT2RST.current_figure - -Now, we show how Otsu's threshold [2]_ 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. - -""" +###################################################################### +# Now, we show how Otsu's threshold [2]_ 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. from skimage import data from skimage.morphology import disk @@ -242,7 +227,7 @@ from skimage.util import img_as_ubyte import matplotlib import matplotlib.pyplot as plt -matplotlib.rcParams['font.size'] = 9 + img = img_as_ubyte(data.page()) radius = 15 @@ -252,31 +237,27 @@ local_otsu = rank.otsu(img, selem) threshold_global_otsu = threshold_otsu(img) global_otsu = img >= threshold_global_otsu -fig, ax = plt.subplots(2, 2, figsize=(8, 5), sharex=True, sharey=True, - subplot_kw={'adjustable': 'box-forced'}) -ax0, ax1, ax2, ax3 = ax.ravel() +fig, axes = plt.subplots(2, 2, figsize=(8, 5), sharex=True, sharey=True, + subplot_kw={'adjustable': 'box-forced'}) +ax = axes.ravel() plt.tight_layout() -fig.colorbar(ax0.imshow(img, cmap=plt.cm.gray), - ax=ax0, orientation='horizontal') -ax0.set_title('Original') -ax0.axis('off') +fig.colorbar(ax[0].imshow(img, cmap=plt.cm.gray), + ax=ax[0], orientation='horizontal') +ax[0].set_title('Original') +ax[0].axis('off') -fig.colorbar(ax1.imshow(local_otsu, cmap=plt.cm.gray), - ax=ax1, orientation='horizontal') -ax1.set_title('Local Otsu (radius=%d)' % radius) -ax1.axis('off') +fig.colorbar(ax[1].imshow(local_otsu, cmap=plt.cm.gray), + ax=ax[1], orientation='horizontal') +ax[1].set_title('Local Otsu (radius=%d)' % radius) +ax[1].axis('off') -ax2.imshow(img >= local_otsu, cmap=plt.cm.gray) -ax2.set_title('Original >= Local Otsu' % threshold_global_otsu) -ax2.axis('off') +ax[2].imshow(img >= local_otsu, cmap=plt.cm.gray) +ax[2].set_title('Original >= Local Otsu' % threshold_global_otsu) +ax[2].axis('off') -ax3.imshow(global_otsu, cmap=plt.cm.gray) -ax3.set_title('Global Otsu (threshold = %d)' % threshold_global_otsu) -ax3.axis('off') +ax[3].imshow(global_otsu, cmap=plt.cm.gray) +ax[3].set_title('Global Otsu (threshold = %d)' % threshold_global_otsu) +ax[3].axis('off') plt.show() -""" -.. image:: PLOT2RST.current_figure - -""" From 361eee970b0c45cceb912ba879ffda8f37d77b9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Boulogne?= Date: Sat, 11 Jun 2016 22:07:40 +0200 Subject: [PATCH 13/19] Add thresholding --- CONTRIBUTORS.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 5900487c..ebed896a 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -132,9 +132,10 @@ Dense DAISY feature description, circle perimeter drawing. - François Boulogne - Drawing: Andres Method for circle perimeter, ellipse perimeter drawing, + Drawing: Andres Method for circle perimeter, ellipse perimeter, Bezier curve, anti-aliasing. Circular and elliptical Hough Transforms + Thresholding Various fixes - Thouis Jones From ee42b2bc39eb305e2a351896cec58fd7e665d5ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Boulogne?= Date: Sun, 12 Jun 2016 20:23:09 +0200 Subject: [PATCH 14/19] Import matplotlib inside _try_all --- skimage/filters/thresholding.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/skimage/filters/thresholding.py b/skimage/filters/thresholding.py index 3fac4a26..d3cc8ca5 100644 --- a/skimage/filters/thresholding.py +++ b/skimage/filters/thresholding.py @@ -2,7 +2,6 @@ import math import numpy as np from scipy import ndimage as ndi from scipy.ndimage import filters as ndif -from matplotlib import pyplot as plt from collections import OrderedDict from ..exposure import histogram from .._shared.utils import assert_nD, warn @@ -42,6 +41,8 @@ def _try_all(image, methods=None, figsize=None, num_cols=2, verbose=True): fig, ax : tuple Matplotlib figure and axes. """ + from matplotlib import pyplot as plt + num_rows = math.ceil((len(methods) + 1) / 2.) num_rows = int(num_rows) # Python 2.7 support fig, ax = plt.subplots(num_rows, num_cols, figsize=figsize, From f25d93c511efa37fc355eb88c5a9bbbdfcb4d21b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Boulogne?= Date: Sun, 12 Jun 2016 22:02:26 +0200 Subject: [PATCH 15/19] Add see also --- doc/examples/segmentation/plot_thresholding.py | 3 +++ doc/examples/xx_applications/plot_thresholding.py | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/doc/examples/segmentation/plot_thresholding.py b/doc/examples/segmentation/plot_thresholding.py index 51c1324a..f0bf5871 100644 --- a/doc/examples/segmentation/plot_thresholding.py +++ b/doc/examples/segmentation/plot_thresholding.py @@ -13,6 +13,9 @@ mechanisms. .. [1] https://en.wikipedia.org/wiki/Thresholding_%28image_processing%29 +.. seealso:: + :ref:`sphx_glr_auto_examples_xx_applications_plot_thresholding.py` + """ import matplotlib import matplotlib.pyplot as plt diff --git a/doc/examples/xx_applications/plot_thresholding.py b/doc/examples/xx_applications/plot_thresholding.py index e20a51a4..3fae3c4f 100644 --- a/doc/examples/xx_applications/plot_thresholding.py +++ b/doc/examples/xx_applications/plot_thresholding.py @@ -24,6 +24,9 @@ mechanisms. .. [1] https://en.wikipedia.org/wiki/Thresholding_%28image_processing%29 +.. seealso:: + Presentation on + :ref:`sphx_glr_auto_examples_xx_applications_plot_rank_filters.py`. """ import matplotlib import matplotlib.pyplot as plt @@ -218,6 +221,7 @@ plt.show() # structuring element. # # The example compares the local threshold with the global threshold. +# from skimage import data from skimage.morphology import disk From 2137aed5ec7c9799bb4fade471f45b971203115d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Boulogne?= Date: Sun, 12 Jun 2016 22:09:42 +0200 Subject: [PATCH 16/19] swap examples to show a different image inthe gallery --- .../segmentation/plot_thresholding.py | 52 +++++++++++-------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/doc/examples/segmentation/plot_thresholding.py b/doc/examples/segmentation/plot_thresholding.py index f0bf5871..baa6b0b4 100644 --- a/doc/examples/segmentation/plot_thresholding.py +++ b/doc/examples/segmentation/plot_thresholding.py @@ -4,41 +4,21 @@ Thresholding ============ Thresholding is used to create a binary image from a grayscale image [1]_. -If you are not familiar with the details of the different algorithms and the -underlying assumptions, it is often difficult to know which algorithm will give -the best results. Therefore, Scikit-image includes a function to evaluate -thresholding algorithms provided by the library. At a glance, you can select -the best algorithm for you data without a deep understanding of their -mechanisms. .. [1] https://en.wikipedia.org/wiki/Thresholding_%28image_processing%29 .. seealso:: + A more comprehensive presentation on :ref:`sphx_glr_auto_examples_xx_applications_plot_thresholding.py` """ -import matplotlib -import matplotlib.pyplot as plt - -from skimage import data -from skimage.filters import thresholding - -img = data.page() - -# Here, we specify a radius for local thresholding algorithms. -# If it is not specified, only global algorithms are called. -fig, ax = thresholding.try_all_threshold(img, radius=20, - figsize=(10, 8), verbose=False) -plt.show() ###################################################################### -# How to apply a threshold? -# ========================= -# -# Now, we illustrate how to apply one of these thresholding algorithms. +# We illustrate how to apply one of these thresholding algorithms. # This example uses the mean value of pixel intensities. It is a simple # and naive threshold value, which is sometimes used as a guess value. +import matplotlib.pyplot as plt from skimage.filters.thresholding import threshold_mean from skimage import data @@ -59,3 +39,29 @@ for a in ax: a.axis('off') plt.show() + + +###################################################################### +# If you are not familiar with the details of the different algorithms and the +# underlying assumptions, it is often difficult to know which algorithm will give +# the best results. Therefore, Scikit-image includes a function to evaluate +# thresholding algorithms provided by the library. At a glance, you can select +# the best algorithm for you data without a deep understanding of their +# mechanisms. + +import matplotlib.pyplot as plt + +from skimage import data +from skimage.filters import thresholding + +img = data.page() + +# Here, we specify a radius for local thresholding algorithms. +# If it is not specified, only global algorithms are called. +fig, ax = thresholding.try_all_threshold(img, radius=20, + figsize=(10, 8), verbose=False) +plt.show() + + + + From d870bcc5df5416e29f1eaf445710847bb55f6821 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Boulogne?= Date: Sat, 18 Jun 2016 23:39:09 +0200 Subject: [PATCH 17/19] Minor fixes --- doc/examples/segmentation/plot_thresholding.py | 7 ------- doc/examples/xx_applications/plot_thresholding.py | 11 ----------- skimage/filters/thresholding.py | 4 ++-- 3 files changed, 2 insertions(+), 20 deletions(-) diff --git a/doc/examples/segmentation/plot_thresholding.py b/doc/examples/segmentation/plot_thresholding.py index baa6b0b4..09654b5d 100644 --- a/doc/examples/segmentation/plot_thresholding.py +++ b/doc/examples/segmentation/plot_thresholding.py @@ -49,9 +49,6 @@ plt.show() # the best algorithm for you data without a deep understanding of their # mechanisms. -import matplotlib.pyplot as plt - -from skimage import data from skimage.filters import thresholding img = data.page() @@ -61,7 +58,3 @@ img = data.page() fig, ax = thresholding.try_all_threshold(img, radius=20, figsize=(10, 8), verbose=False) plt.show() - - - - diff --git a/doc/examples/xx_applications/plot_thresholding.py b/doc/examples/xx_applications/plot_thresholding.py index 3fae3c4f..e6a93242 100644 --- a/doc/examples/xx_applications/plot_thresholding.py +++ b/doc/examples/xx_applications/plot_thresholding.py @@ -51,7 +51,6 @@ plt.show() # and naive threshold value, which is sometimes used as a guess value. from skimage.filters.thresholding import threshold_mean -from skimage import data image = data.camera() @@ -83,9 +82,6 @@ plt.show() # histogram, there can be multiple pixel values with the minimum histogram # count, so you can pick the 'min', 'mid', or 'max' of these values. -import matplotlib.pyplot as plt - -from skimage import data from skimage.filters.thresholding import threshold_minimum @@ -182,9 +178,6 @@ plt.show() # each pixel (i.e. local neighborhoods). Each threshold value is the weighted mean # of the local neighborhood minus an offset value. -import matplotlib.pyplot as plt - -from skimage import data from skimage.filters import threshold_otsu, threshold_adaptive @@ -223,14 +216,10 @@ plt.show() # The example compares the local threshold with the global threshold. # -from skimage import data from skimage.morphology import disk from skimage.filters import threshold_otsu, rank from skimage.util import img_as_ubyte -import matplotlib -import matplotlib.pyplot as plt - img = img_as_ubyte(data.page()) diff --git a/skimage/filters/thresholding.py b/skimage/filters/thresholding.py index d3cc8ca5..97b3e5e9 100644 --- a/skimage/filters/thresholding.py +++ b/skimage/filters/thresholding.py @@ -43,7 +43,7 @@ def _try_all(image, methods=None, figsize=None, num_cols=2, verbose=True): """ from matplotlib import pyplot as plt - num_rows = math.ceil((len(methods) + 1) / 2.) + num_rows = math.ceil((len(methods) + 1.) / num_cols) num_rows = int(num_rows) # Python 2.7 support fig, ax = plt.subplots(num_rows, num_cols, figsize=figsize, sharex=True, sharey=True, @@ -75,7 +75,7 @@ def try_all_threshold(image, radius=None, figsize=(8, 5), verbose=True): ---------- image : (N, M) ndarray Input image. - radius : int, optinal + radius : int, optional Lengthscale used for local methods. If None, local methods are ignored. figsize : tuple, optional From 25f5729d570c66e4f55cb23a7a41db9382b9015e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Boulogne?= Date: Sun, 19 Jun 2016 09:35:05 +0200 Subject: [PATCH 18/19] Switch to Otsu instead of mean --- .../segmentation/plot_thresholding.py | 31 +++++++++++++------ 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/doc/examples/segmentation/plot_thresholding.py b/doc/examples/segmentation/plot_thresholding.py index 09654b5d..1324db72 100644 --- a/doc/examples/segmentation/plot_thresholding.py +++ b/doc/examples/segmentation/plot_thresholding.py @@ -15,28 +15,39 @@ Thresholding is used to create a binary image from a grayscale image [1]_. ###################################################################### # We illustrate how to apply one of these thresholding algorithms. -# This example uses the mean value of pixel intensities. It is a simple -# and naive threshold value, which is sometimes used as a guess value. +# Otsu's method [2]_ calculates an "optimal" threshold (marked by a red line in the +# histogram below) by maximizing the variance between two classes of pixels, +# which are separated by the threshold. Equivalently, this threshold minimizes +# the intra-class variance. +# +# .. [2] http://en.wikipedia.org/wiki/Otsu's_method import matplotlib.pyplot as plt -from skimage.filters.thresholding import threshold_mean from skimage import data +from skimage.filters import threshold_otsu + image = data.camera() -thresh = threshold_mean(image) +thresh = threshold_otsu(image) binary = image > thresh -fig, axes = plt.subplots(ncols=2, figsize=(8, 3)) +fig, axes = plt.subplots(ncols=3, figsize=(8, 2.5)) ax = axes.ravel() +ax[0] = plt.subplot(1, 3, 1, adjustable='box-forced') +ax[1] = plt.subplot(1, 3, 2) +ax[2] = plt.subplot(1, 3, 3, sharex=ax[0], sharey=ax[0], adjustable='box-forced') ax[0].imshow(image, cmap=plt.cm.gray) -ax[0].set_title('Original image') +ax[0].set_title('Original') +ax[0].axis('off') -ax[1].imshow(binary, cmap=plt.cm.gray) -ax[1].set_title('Result') +ax[1].hist(image.ravel(), bins=256) +ax[1].set_title('Histogram') +ax[1].axvline(thresh, color='r') -for a in ax: - a.axis('off') +ax[2].imshow(binary, cmap=plt.cm.gray) +ax[2].set_title('Thresholded') +ax[2].axis('off') plt.show() From 9fef985df8ded4f43753f2876a66c267957699a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Boulogne?= Date: Sun, 19 Jun 2016 09:37:26 +0200 Subject: [PATCH 19/19] Various fixes --- .../segmentation/plot_thresholding.py | 8 +++--- .../xx_applications/plot_thresholding.py | 26 +++++++++---------- skimage/filters/__init__.py | 3 ++- skimage/filters/thresholding.py | 4 +-- 4 files changed, 22 insertions(+), 19 deletions(-) diff --git a/doc/examples/segmentation/plot_thresholding.py b/doc/examples/segmentation/plot_thresholding.py index 1324db72..9a3ccb0d 100644 --- a/doc/examples/segmentation/plot_thresholding.py +++ b/doc/examples/segmentation/plot_thresholding.py @@ -21,6 +21,7 @@ Thresholding is used to create a binary image from a grayscale image [1]_. # the intra-class variance. # # .. [2] http://en.wikipedia.org/wiki/Otsu's_method +# import matplotlib.pyplot as plt from skimage import data @@ -59,13 +60,14 @@ plt.show() # thresholding algorithms provided by the library. At a glance, you can select # the best algorithm for you data without a deep understanding of their # mechanisms. +# -from skimage.filters import thresholding +from skimage.filters import try_all_threshold img = data.page() # Here, we specify a radius for local thresholding algorithms. # If it is not specified, only global algorithms are called. -fig, ax = thresholding.try_all_threshold(img, radius=20, - figsize=(10, 8), verbose=False) +fig, ax = try_all_threshold(img, radius=20, + figsize=(10, 8), verbose=False) plt.show() diff --git a/doc/examples/xx_applications/plot_thresholding.py b/doc/examples/xx_applications/plot_thresholding.py index e6a93242..92e4556b 100644 --- a/doc/examples/xx_applications/plot_thresholding.py +++ b/doc/examples/xx_applications/plot_thresholding.py @@ -32,14 +32,14 @@ import matplotlib import matplotlib.pyplot as plt from skimage import data -from skimage.filters import thresholding +from skimage.filters import try_all_threshold img = data.page() # Here, we specify a radius for local thresholding algorithms. # If it is not specified, only global algorithms are called. -fig, ax = thresholding.try_all_threshold(img, radius=20, - figsize=(10, 8), verbose=False) +fig, ax = try_all_threshold(img, radius=20, + figsize=(10, 8), verbose=False) plt.show() ###################################################################### @@ -49,8 +49,9 @@ plt.show() # Now, we illustrate how to apply one of these thresholding algorithms. # This example uses the mean value of pixel intensities. It is a simple # and naive threshold value, which is sometimes used as a guess value. +# -from skimage.filters.thresholding import threshold_mean +from skimage.filters import threshold_mean image = data.camera() @@ -77,12 +78,13 @@ plt.show() # # For pictures with a bimodal histogram, more specific algorithms can be used. # For instance, the minimum algorithm takes a histogram of the image and smooths it -# repeatedly until there are only two peaks in the histogram. Then it -# finds the minimum value between the two peaks. After smoothing the +# repeatedly until there are only two peaks in the histogram. Then it +# finds the minimum value between the two peaks. After smoothing the # histogram, there can be multiple pixel values with the minimum histogram # count, so you can pick the 'min', 'mid', or 'max' of these values. +# -from skimage.filters.thresholding import threshold_minimum +from skimage.filters import threshold_minimum image = data.camera() @@ -131,11 +133,8 @@ plt.show() # the intra-class variance. # # .. [2] http://en.wikipedia.org/wiki/Otsu's_method +# -import matplotlib -import matplotlib.pyplot as plt - -from skimage import data from skimage.filters import threshold_otsu @@ -175,8 +174,9 @@ plt.show() # # Here, we binarize an image using the `threshold_adaptive` function, which # calculates thresholds in regions with a characteristic size `block_size` surrounding -# each pixel (i.e. local neighborhoods). Each threshold value is the weighted mean -# of the local neighborhood minus an offset value. +# each pixel (i.e. local neighborhoods). Each threshold value is the weighted mean +# of the local neighborhood minus an offset value. +# from skimage.filters import threshold_otsu, threshold_adaptive diff --git a/skimage/filters/__init__.py b/skimage/filters/__init__.py index 9ae67a5c..61fc850c 100644 --- a/skimage/filters/__init__.py +++ b/skimage/filters/__init__.py @@ -8,7 +8,8 @@ from .edges import (sobel, sobel_h, sobel_v, from ._rank_order import rank_order from ._gabor import gabor_kernel, gabor from .thresholding import (threshold_adaptive, threshold_otsu, threshold_yen, - threshold_isodata, threshold_li, threshold_minimum) + threshold_isodata, threshold_li, threshold_minimum, + threshold_mean, threshold_triangle, try_all_threshold) from . import rank from .rank import median diff --git a/skimage/filters/thresholding.py b/skimage/filters/thresholding.py index 97b3e5e9..06493880 100644 --- a/skimage/filters/thresholding.py +++ b/skimage/filters/thresholding.py @@ -102,8 +102,8 @@ def try_all_threshold(image, radius=None, figsize=(8, 5), verbose=True): * adaptive threshold (local) * rank otsu (local) - Example - ------- + Examples + -------- >>> from skimage.data import text >>> fig, ax = try_all_threshold(text(), radius=20, ... figsize=(10, 6), verbose=False)