From fbbe38765d4afa7de1126540c31150a3ba94f862 Mon Sep 17 00:00:00 2001 From: Tony S Yu Date: Thu, 8 Dec 2011 22:58:14 -0500 Subject: [PATCH 01/13] Add thresholding module with Otsu's method to calculate threshold. --- skimage/thresholding/__init__.py | 1 + .../thresholding/tests/test_thresholding.py | 53 +++++++++ skimage/thresholding/thresholding.py | 105 ++++++++++++++++++ 3 files changed, 159 insertions(+) create mode 100644 skimage/thresholding/__init__.py create mode 100644 skimage/thresholding/tests/test_thresholding.py create mode 100644 skimage/thresholding/thresholding.py diff --git a/skimage/thresholding/__init__.py b/skimage/thresholding/__init__.py new file mode 100644 index 00000000..d588eda0 --- /dev/null +++ b/skimage/thresholding/__init__.py @@ -0,0 +1 @@ +from .thresholding import otsu_threshold, binarize diff --git a/skimage/thresholding/tests/test_thresholding.py b/skimage/thresholding/tests/test_thresholding.py new file mode 100644 index 00000000..713defe4 --- /dev/null +++ b/skimage/thresholding/tests/test_thresholding.py @@ -0,0 +1,53 @@ +import numpy as np + +import skimage +from skimage import data +from skimage.thresholding import otsu_threshold, binarize + + +class TestSimpleImage(): + def setup(self): + self.image = np.array([[0, 0, 1, 3, 5], + [0, 1, 4, 3, 4], + [1, 2, 5, 4, 1], + [2, 4, 5, 2, 1], + [4, 5, 1, 0, 0]], dtype=int) + + def test_otsu(self): + assert otsu_threshold(self.image) == 2 + + @np.testing.raises(NotImplementedError) + def test_otsu_raises_error(self): + image = self.image - 2 + otsu_threshold(image) + + def test_otsu_float_image(self): + image = np.float64(self.image) + assert 2 <= otsu_threshold(image) < 3 + + def test_binarize(self): + expected = np.array([[0, 0, 0, 1, 1], + [0, 0, 1, 1, 1], + [0, 0, 1, 1, 0], + [0, 1, 1, 0, 0], + [1, 1, 0, 0, 0]]) + assert np.all(binarize(self.image) == expected) + + +def test_otsu_camera_image(): + assert otsu_threshold(data.camera()) == 87 + +def test_otsu_coins_image(): + assert otsu_threshold(data.coins()) == 107 + +def test_otsu_coins_image_as_float(): + coins = skimage.img_as_float(data.coins()) + assert 0.41 < otsu_threshold(coins) < 0.42 + +def test_otsu_lena_image(): + assert otsu_threshold(data.lena()) == 141 + + +if __name__ == '__main__': + np.testing.run_module_suite() + diff --git a/skimage/thresholding/thresholding.py b/skimage/thresholding/thresholding.py new file mode 100644 index 00000000..b5699f7e --- /dev/null +++ b/skimage/thresholding/thresholding.py @@ -0,0 +1,105 @@ +import numpy as np + + +__all__ = ['otsu_threshold', 'binarize'] + + +def otsu_threshold(image, bins=256): + """Return threshold value based on Otsu's method. + + Parameters + ---------- + image : array + Input image. + bins : int + Number of bins used to calculate histogram. This value is ignored for + integer arrays. + + Returns + ------- + threshold : numeric + Threshold value. int or float depending on input image. + + References + ---------- + .. [1] Wikipedia, http://en.wikipedia.org/wiki/Otsu's_Method + + """ + hist, bin_centers = histogram(image, bins) + hist = hist.astype(float) + + # class probabilities for all possible thresholds + weight1 = np.cumsum(hist) + weight2 = np.cumsum(hist[::-1])[::-1] + # class means for all possible thresholds + mean1 = np.cumsum(hist * bin_centers) / weight1 + mean2 = (np.cumsum((hist * bin_centers)[::-1]) / weight2[::-1])[::-1] + + # Clip ends to align class 1 and class 2 variables: + # The last value of `weight1`/`mean1` should pair with zero values in + # `weight2`/`mean2`, which do not exist. + variance12 = weight1[:-1] * weight2[1:] * (mean1[:-1] - mean2[1:])**2 + + idx = np.argmax(variance12) + threshold = bin_centers[:-1][idx] + return threshold + + +_threshold_funcs = {'otsu': otsu_threshold} +def binarize(image, method='otsu'): + """Return binary image using an automatic thresholding method. + + Parameters + ---------- + image : array + Input array. + method : {'otsu'} + Method used to calculate threshold value. Currently, only Otsu's method + is implemented. + + Returns + ------- + out : array + Thresholded image. + """ + get_threshold = _threshold_funcs[method] + threshold = get_threshold(image) + return image > threshold + + +def histogram(image, bins): + """Return histogram of image. + + Unlike `numpy.histogram`, this function returns the centers of bins and + does not rebin integer arrays. + + Parameters + ---------- + image : array + Input image. + bins : int + Number of bins used to calculate histogram. This value is ignored for + integer arrays. + + Returns + ------- + hist : array + The values of the histogram. + bin_centers : array + The values at the center of the bins. + """ + if np.issubdtype(image.dtype, np.integer): + if np.min(image) < 0: + msg = "Images with negative values not allowed" + raise NotImplementedError(msg) + hist = np.bincount(image.flat) + bin_centers = np.arange(len(hist)) + + # clip histogram to return only non-zero bins + idx = np.nonzero(hist)[0][0] + return hist[idx:], bin_centers[idx:] + else: + hist, bin_edges = np.histogram(image, bins=bins) + bin_centers = (bin_edges[:-1] + bin_edges[1:]) / 2. + return hist, bin_centers + From f3e5a30125c3f1269407be19bc0d9a1430bac1b0 Mon Sep 17 00:00:00 2001 From: Tony S Yu Date: Thu, 8 Dec 2011 23:24:48 -0500 Subject: [PATCH 02/13] Rename otsu_threshold to threshold_otsu --- skimage/thresholding/__init__.py | 2 +- skimage/thresholding/tests/test_thresholding.py | 16 ++++++++-------- skimage/thresholding/thresholding.py | 6 +++--- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/skimage/thresholding/__init__.py b/skimage/thresholding/__init__.py index d588eda0..d5d6eddf 100644 --- a/skimage/thresholding/__init__.py +++ b/skimage/thresholding/__init__.py @@ -1 +1 @@ -from .thresholding import otsu_threshold, binarize +from .thresholding import threshold_otsu, binarize diff --git a/skimage/thresholding/tests/test_thresholding.py b/skimage/thresholding/tests/test_thresholding.py index 713defe4..485ffbca 100644 --- a/skimage/thresholding/tests/test_thresholding.py +++ b/skimage/thresholding/tests/test_thresholding.py @@ -2,7 +2,7 @@ import numpy as np import skimage from skimage import data -from skimage.thresholding import otsu_threshold, binarize +from skimage.thresholding import threshold_otsu, binarize class TestSimpleImage(): @@ -14,16 +14,16 @@ class TestSimpleImage(): [4, 5, 1, 0, 0]], dtype=int) def test_otsu(self): - assert otsu_threshold(self.image) == 2 + assert threshold_otsu(self.image) == 2 @np.testing.raises(NotImplementedError) def test_otsu_raises_error(self): image = self.image - 2 - otsu_threshold(image) + threshold_otsu(image) def test_otsu_float_image(self): image = np.float64(self.image) - assert 2 <= otsu_threshold(image) < 3 + assert 2 <= threshold_otsu(image) < 3 def test_binarize(self): expected = np.array([[0, 0, 0, 1, 1], @@ -35,17 +35,17 @@ class TestSimpleImage(): def test_otsu_camera_image(): - assert otsu_threshold(data.camera()) == 87 + assert threshold_otsu(data.camera()) == 87 def test_otsu_coins_image(): - assert otsu_threshold(data.coins()) == 107 + assert threshold_otsu(data.coins()) == 107 def test_otsu_coins_image_as_float(): coins = skimage.img_as_float(data.coins()) - assert 0.41 < otsu_threshold(coins) < 0.42 + assert 0.41 < threshold_otsu(coins) < 0.42 def test_otsu_lena_image(): - assert otsu_threshold(data.lena()) == 141 + assert threshold_otsu(data.lena()) == 141 if __name__ == '__main__': diff --git a/skimage/thresholding/thresholding.py b/skimage/thresholding/thresholding.py index b5699f7e..62af6d8d 100644 --- a/skimage/thresholding/thresholding.py +++ b/skimage/thresholding/thresholding.py @@ -1,10 +1,10 @@ import numpy as np -__all__ = ['otsu_threshold', 'binarize'] +__all__ = ['threshold_otsu', 'binarize'] -def otsu_threshold(image, bins=256): +def threshold_otsu(image, bins=256): """Return threshold value based on Otsu's method. Parameters @@ -45,7 +45,7 @@ def otsu_threshold(image, bins=256): return threshold -_threshold_funcs = {'otsu': otsu_threshold} +_threshold_funcs = {'otsu': threshold_otsu} def binarize(image, method='otsu'): """Return binary image using an automatic thresholding method. From 9a89fab612cadc46b73a09391d22d401c0e93ac3 Mon Sep 17 00:00:00 2001 From: Tony S Yu Date: Thu, 8 Dec 2011 23:34:08 -0500 Subject: [PATCH 03/13] Add handling for images with negative integers --- skimage/thresholding/tests/test_thresholding.py | 5 ++--- skimage/thresholding/thresholding.py | 8 ++++---- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/skimage/thresholding/tests/test_thresholding.py b/skimage/thresholding/tests/test_thresholding.py index 485ffbca..6fc3f020 100644 --- a/skimage/thresholding/tests/test_thresholding.py +++ b/skimage/thresholding/tests/test_thresholding.py @@ -16,10 +16,9 @@ class TestSimpleImage(): def test_otsu(self): assert threshold_otsu(self.image) == 2 - @np.testing.raises(NotImplementedError) - def test_otsu_raises_error(self): + def test_otsu_negative_int(self): image = self.image - 2 - threshold_otsu(image) + assert threshold_otsu(image) == 0 def test_otsu_float_image(self): image = np.float64(self.image) diff --git a/skimage/thresholding/thresholding.py b/skimage/thresholding/thresholding.py index 62af6d8d..e346efba 100644 --- a/skimage/thresholding/thresholding.py +++ b/skimage/thresholding/thresholding.py @@ -89,11 +89,11 @@ def histogram(image, bins): The values at the center of the bins. """ if np.issubdtype(image.dtype, np.integer): + offset = 0 if np.min(image) < 0: - msg = "Images with negative values not allowed" - raise NotImplementedError(msg) - hist = np.bincount(image.flat) - bin_centers = np.arange(len(hist)) + offset = np.min(image) + hist = np.bincount(image.ravel() - offset) + bin_centers = np.arange(len(hist)) + offset # clip histogram to return only non-zero bins idx = np.nonzero(hist)[0][0] From 10c1f471a0184151e64adb2378713757e324e949 Mon Sep 17 00:00:00 2001 From: Tony S Yu Date: Thu, 8 Dec 2011 23:38:51 -0500 Subject: [PATCH 04/13] Change docstring threshold_otsu output --- skimage/thresholding/thresholding.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/skimage/thresholding/thresholding.py b/skimage/thresholding/thresholding.py index e346efba..131d33e7 100644 --- a/skimage/thresholding/thresholding.py +++ b/skimage/thresholding/thresholding.py @@ -17,8 +17,8 @@ def threshold_otsu(image, bins=256): Returns ------- - threshold : numeric - Threshold value. int or float depending on input image. + threshold : float + Threshold value. References ---------- From 5a171a2bfb413d6c70a02f83a905d05c5e231797 Mon Sep 17 00:00:00 2001 From: Tony S Yu Date: Thu, 8 Dec 2011 23:52:10 -0500 Subject: [PATCH 05/13] Remove binarize function --- skimage/thresholding/__init__.py | 3 ++- .../thresholding/tests/test_thresholding.py | 10 +------- skimage/thresholding/thresholding.py | 24 +------------------ 3 files changed, 4 insertions(+), 33 deletions(-) diff --git a/skimage/thresholding/__init__.py b/skimage/thresholding/__init__.py index d5d6eddf..9b6e229c 100644 --- a/skimage/thresholding/__init__.py +++ b/skimage/thresholding/__init__.py @@ -1 +1,2 @@ -from .thresholding import threshold_otsu, binarize +from .thresholding import threshold_otsu + diff --git a/skimage/thresholding/tests/test_thresholding.py b/skimage/thresholding/tests/test_thresholding.py index 6fc3f020..2ec64da6 100644 --- a/skimage/thresholding/tests/test_thresholding.py +++ b/skimage/thresholding/tests/test_thresholding.py @@ -2,7 +2,7 @@ import numpy as np import skimage from skimage import data -from skimage.thresholding import threshold_otsu, binarize +from skimage.thresholding import threshold_otsu class TestSimpleImage(): @@ -24,14 +24,6 @@ class TestSimpleImage(): image = np.float64(self.image) assert 2 <= threshold_otsu(image) < 3 - def test_binarize(self): - expected = np.array([[0, 0, 0, 1, 1], - [0, 0, 1, 1, 1], - [0, 0, 1, 1, 0], - [0, 1, 1, 0, 0], - [1, 1, 0, 0, 0]]) - assert np.all(binarize(self.image) == expected) - def test_otsu_camera_image(): assert threshold_otsu(data.camera()) == 87 diff --git a/skimage/thresholding/thresholding.py b/skimage/thresholding/thresholding.py index 131d33e7..b274010f 100644 --- a/skimage/thresholding/thresholding.py +++ b/skimage/thresholding/thresholding.py @@ -1,7 +1,7 @@ import numpy as np -__all__ = ['threshold_otsu', 'binarize'] +__all__ = ['threshold_otsu'] def threshold_otsu(image, bins=256): @@ -45,28 +45,6 @@ def threshold_otsu(image, bins=256): return threshold -_threshold_funcs = {'otsu': threshold_otsu} -def binarize(image, method='otsu'): - """Return binary image using an automatic thresholding method. - - Parameters - ---------- - image : array - Input array. - method : {'otsu'} - Method used to calculate threshold value. Currently, only Otsu's method - is implemented. - - Returns - ------- - out : array - Thresholded image. - """ - get_threshold = _threshold_funcs[method] - threshold = get_threshold(image) - return image > threshold - - def histogram(image, bins): """Return histogram of image. From 6872e9cdf3ab5030cc3ccbbac6d614c0656252ac Mon Sep 17 00:00:00 2001 From: Tony S Yu Date: Fri, 9 Dec 2011 00:13:49 -0500 Subject: [PATCH 06/13] Add thresholding example --- doc/examples/plot_otsu.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 doc/examples/plot_otsu.py diff --git a/doc/examples/plot_otsu.py b/doc/examples/plot_otsu.py new file mode 100644 index 00000000..03534bc9 --- /dev/null +++ b/doc/examples/plot_otsu.py @@ -0,0 +1,23 @@ +""" +============ +Thresholding +============ + +Thresholding is used to create a binary image. This example uses Otsu's method to calculate the threshold value. + +""" + +import matplotlib.pyplot as plt + +from skimage.data import camera +from skimage.thresholding import threshold_otsu + + +image = camera() +thresh = threshold_otsu(camera()) +binary = image > thresh + +plt.imshow(binary) +plt.axis('off') +plt.show() + From 6a6e273d0679e35237db877056b4e85e8ca41e56 Mon Sep 17 00:00:00 2001 From: Tony S Yu Date: Fri, 9 Dec 2011 10:16:23 -0500 Subject: [PATCH 07/13] Remove thresholding example from user guide in favor of docstring example. --- doc/examples/plot_otsu.py | 23 ----------------------- skimage/thresholding/thresholding.py | 6 ++++++ 2 files changed, 6 insertions(+), 23 deletions(-) delete mode 100644 doc/examples/plot_otsu.py diff --git a/doc/examples/plot_otsu.py b/doc/examples/plot_otsu.py deleted file mode 100644 index 03534bc9..00000000 --- a/doc/examples/plot_otsu.py +++ /dev/null @@ -1,23 +0,0 @@ -""" -============ -Thresholding -============ - -Thresholding is used to create a binary image. This example uses Otsu's method to calculate the threshold value. - -""" - -import matplotlib.pyplot as plt - -from skimage.data import camera -from skimage.thresholding import threshold_otsu - - -image = camera() -thresh = threshold_otsu(camera()) -binary = image > thresh - -plt.imshow(binary) -plt.axis('off') -plt.show() - diff --git a/skimage/thresholding/thresholding.py b/skimage/thresholding/thresholding.py index b274010f..861d2647 100644 --- a/skimage/thresholding/thresholding.py +++ b/skimage/thresholding/thresholding.py @@ -24,6 +24,12 @@ def threshold_otsu(image, bins=256): ---------- .. [1] Wikipedia, http://en.wikipedia.org/wiki/Otsu's_Method + Examples + -------- + >>> from skimage.data import camera + >>> image = camera() + >>> thresh = threshold_otsu(camera()) + >>> binary = image > thresh """ hist, bin_centers = histogram(image, bins) hist = hist.astype(float) From e7d37997d92b911dd2662112474e8574246e513a Mon Sep 17 00:00:00 2001 From: Tony S Yu Date: Sat, 10 Dec 2011 19:33:29 -0500 Subject: [PATCH 08/13] Fix minor typo in docstring example --- skimage/thresholding/thresholding.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skimage/thresholding/thresholding.py b/skimage/thresholding/thresholding.py index 861d2647..980dfeba 100644 --- a/skimage/thresholding/thresholding.py +++ b/skimage/thresholding/thresholding.py @@ -28,7 +28,7 @@ def threshold_otsu(image, bins=256): -------- >>> from skimage.data import camera >>> image = camera() - >>> thresh = threshold_otsu(camera()) + >>> thresh = threshold_otsu(image) >>> binary = image > thresh """ hist, bin_centers = histogram(image, bins) From d9186c90a1bcc9adf90de8567cb473e4382bc838 Mon Sep 17 00:00:00 2001 From: Tony S Yu Date: Sun, 11 Dec 2011 17:04:46 -0500 Subject: [PATCH 09/13] Remove thresholding subpackage and integrate into filter subpackage. --- skimage/filter/__init__.py | 1 + skimage/{thresholding => filter}/tests/test_thresholding.py | 2 +- skimage/{thresholding => filter}/thresholding.py | 0 skimage/thresholding/__init__.py | 2 -- 4 files changed, 2 insertions(+), 3 deletions(-) rename skimage/{thresholding => filter}/tests/test_thresholding.py (95%) rename skimage/{thresholding => filter}/thresholding.py (100%) delete mode 100644 skimage/thresholding/__init__.py diff --git a/skimage/filter/__init__.py b/skimage/filter/__init__.py index d3baf934..1acc33f2 100644 --- a/skimage/filter/__init__.py +++ b/skimage/filter/__init__.py @@ -4,3 +4,4 @@ from canny import canny from edges import sobel, hsobel, vsobel, hprewitt, vprewitt, prewitt from tv_denoise import tv_denoise from rank_order import rank_order +from thresholding import threshold_otsu diff --git a/skimage/thresholding/tests/test_thresholding.py b/skimage/filter/tests/test_thresholding.py similarity index 95% rename from skimage/thresholding/tests/test_thresholding.py rename to skimage/filter/tests/test_thresholding.py index 2ec64da6..b0044a47 100644 --- a/skimage/thresholding/tests/test_thresholding.py +++ b/skimage/filter/tests/test_thresholding.py @@ -2,7 +2,7 @@ import numpy as np import skimage from skimage import data -from skimage.thresholding import threshold_otsu +from skimage.filter.thresholding import threshold_otsu class TestSimpleImage(): diff --git a/skimage/thresholding/thresholding.py b/skimage/filter/thresholding.py similarity index 100% rename from skimage/thresholding/thresholding.py rename to skimage/filter/thresholding.py diff --git a/skimage/thresholding/__init__.py b/skimage/thresholding/__init__.py deleted file mode 100644 index 9b6e229c..00000000 --- a/skimage/thresholding/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from .thresholding import threshold_otsu - From 756dfd5020eb03447233e7d2dc3b70c4d05b0535 Mon Sep 17 00:00:00 2001 From: Tony S Yu Date: Mon, 12 Dec 2011 13:51:27 -0500 Subject: [PATCH 10/13] Rename `bins` parameter to `nbins`. This change distinguishes it from the `bins` argument in numpy.histogram, which can accept both the number of bins or a sequence bin edges. Also, this name matches other function parameters in the scikit (e.g. `histograms` in io/_plugins/util.py). --- skimage/filter/thresholding.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/skimage/filter/thresholding.py b/skimage/filter/thresholding.py index 980dfeba..800e18b8 100644 --- a/skimage/filter/thresholding.py +++ b/skimage/filter/thresholding.py @@ -4,14 +4,14 @@ import numpy as np __all__ = ['threshold_otsu'] -def threshold_otsu(image, bins=256): +def threshold_otsu(image, nbins=256): """Return threshold value based on Otsu's method. Parameters ---------- image : array Input image. - bins : int + nbins : int Number of bins used to calculate histogram. This value is ignored for integer arrays. @@ -31,7 +31,7 @@ def threshold_otsu(image, bins=256): >>> thresh = threshold_otsu(image) >>> binary = image > thresh """ - hist, bin_centers = histogram(image, bins) + hist, bin_centers = histogram(image, nbins) hist = hist.astype(float) # class probabilities for all possible thresholds @@ -51,7 +51,7 @@ def threshold_otsu(image, bins=256): return threshold -def histogram(image, bins): +def histogram(image, nbins): """Return histogram of image. Unlike `numpy.histogram`, this function returns the centers of bins and @@ -61,7 +61,7 @@ def histogram(image, bins): ---------- image : array Input image. - bins : int + nbins : int Number of bins used to calculate histogram. This value is ignored for integer arrays. @@ -83,7 +83,7 @@ def histogram(image, bins): idx = np.nonzero(hist)[0][0] return hist[idx:], bin_centers[idx:] else: - hist, bin_edges = np.histogram(image, bins=bins) + hist, bin_edges = np.histogram(image, bins=nbins) bin_centers = (bin_edges[:-1] + bin_edges[1:]) / 2. return hist, bin_centers From 8ed834a3ab6651e35ecca487f69d0dc85ee18435 Mon Sep 17 00:00:00 2001 From: Tony S Yu Date: Sat, 17 Dec 2011 22:02:10 -0500 Subject: [PATCH 11/13] Add example for threshoding This example was removed in a previous commit. --- doc/examples/plot_otsu.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 doc/examples/plot_otsu.py diff --git a/doc/examples/plot_otsu.py b/doc/examples/plot_otsu.py new file mode 100644 index 00000000..3557bc2c --- /dev/null +++ b/doc/examples/plot_otsu.py @@ -0,0 +1,23 @@ +""" +============ +Thresholding +============ + +Thresholding is used to create a binary image. This example uses Otsu's method to calculate the threshold value. + +""" + +import matplotlib.pyplot as plt + +from skimage.data import camera +from skimage.filter import threshold_otsu + + +image = camera() +thresh = threshold_otsu(image) +binary = image > thresh + +plt.imshow(binary) +plt.axis('off') +plt.show() + From 1e12ca0044d640e62f06f786d668be2b8b846ff9 Mon Sep 17 00:00:00 2001 From: Tony S Yu Date: Sun, 18 Dec 2011 09:31:10 -0500 Subject: [PATCH 12/13] Improve thresholding example --- doc/examples/plot_otsu.py | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/doc/examples/plot_otsu.py b/doc/examples/plot_otsu.py index 3557bc2c..62bd6836 100644 --- a/doc/examples/plot_otsu.py +++ b/doc/examples/plot_otsu.py @@ -3,7 +3,14 @@ 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. This example uses Otsu's method +to calculate the threshold value. + +Otsu's method calculates an "optimal" threshold by maximizing the variance +between the two classes of pixels, which are separated by the threshold. +Equivalently, the optimal threshold minimizes the intra-class variance. + +.. [1] http://en.wikipedia.org/wiki/Otsu's_method """ @@ -17,7 +24,21 @@ image = camera() thresh = threshold_otsu(image) binary = image > thresh -plt.imshow(binary) +plt.figure(figsize=(10, 3.5)) +plt.subplot(1, 3, 1) +plt.imshow(image) +plt.title('original') plt.axis('off') + +plt.subplot(1, 3, 2) +plt.hist(image) +plt.title('histogram') +plt.axvline(thresh, color='r') + +plt.subplot(1, 3, 3) +plt.imshow(binary) +plt.title('thresholded') +plt.axis('off') + plt.show() From 8941798daf23df1fe3ad6dd6cd652619ae3724d8 Mon Sep 17 00:00:00 2001 From: Tony S Yu Date: Sun, 18 Dec 2011 10:10:00 -0500 Subject: [PATCH 13/13] DOC: emphasize annotation in histogram. --- doc/examples/plot_otsu.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/doc/examples/plot_otsu.py b/doc/examples/plot_otsu.py index 62bd6836..060f54c6 100644 --- a/doc/examples/plot_otsu.py +++ b/doc/examples/plot_otsu.py @@ -6,9 +6,10 @@ Thresholding Thresholding is used to create a binary image. This example uses Otsu's method to calculate the threshold value. -Otsu's method calculates an "optimal" threshold by maximizing the variance -between the two classes of pixels, which are separated by the threshold. -Equivalently, the optimal threshold minimizes the intra-class variance. +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