From d5994c67153583a1babc94307349fdaed0654b2d Mon Sep 17 00:00:00 2001 From: emmanuelle Date: Wed, 7 Dec 2011 20:57:29 +0100 Subject: [PATCH 1/4] Short tutorial on segmentation for the user guide + example on the same subject used to generate the figures --- doc/examples/applications/README.txt | 2 + .../applications/plot_coins_segmentation.py | 135 +++++++++++++++++ doc/source/user_guide.txt | 1 + doc/source/user_guide/elevation_map.jpg | Bin 0 -> 75691 bytes doc/source/user_guide/segmentation.txt | 141 ++++++++++++++++++ 5 files changed, 279 insertions(+) create mode 100644 doc/examples/applications/README.txt create mode 100644 doc/examples/applications/plot_coins_segmentation.py create mode 100644 doc/source/user_guide/elevation_map.jpg create mode 100644 doc/source/user_guide/segmentation.txt diff --git a/doc/examples/applications/README.txt b/doc/examples/applications/README.txt new file mode 100644 index 00000000..8f40133f --- /dev/null +++ b/doc/examples/applications/README.txt @@ -0,0 +1,2 @@ +Longer examples and demonstrations +---------------------------------- diff --git a/doc/examples/applications/plot_coins_segmentation.py b/doc/examples/applications/plot_coins_segmentation.py new file mode 100644 index 00000000..5b3c9de7 --- /dev/null +++ b/doc/examples/applications/plot_coins_segmentation.py @@ -0,0 +1,135 @@ +""" +=============================================================== +Comparing edge-based segmentation and region-based segmentation +=============================================================== + +In this example, we will see how to segment objects from a background. +We use the ``coins`` image from ``skimage.data``. This image shows +several coins outlined against a darker background. The segmentation of +the coins cannot be done directly from the histogram of grey values, +because the background shares enough grey levels with the coins that a +thresholding segmentation is not sufficient. Simply thresholding the image +leads either to missing significant parts of the coins, or to getting parts +of the background together with the coins. + +We first try an edge-based segmentation. We use the Canny detector to +delineate the contours of the coins. These contours are filled using +mathematical morphology (``scipy.ndimage.binary_fill_holes``). Small spurious +objects are easily removed by applying a threshold on the size of +unconnected objects. However, this method is not very robust, since contours +that are not perfectly closed are not filled correctly. This happens for one +of the coins. + +We therefore try a second method, that is region-based. Here we use the +watershed transform. An elevation map is provided by the Sobel gradient +of the image. Markers of the background and the coins are determined from +the extreme parts of the histogram of grey values. + +This second method works even better, and the coins can be segmented and +labeled individually. + +""" + + +import numpy as np +from scipy import ndimage +import matplotlib.pyplot as plt +import skimage +from skimage.filter import canny, sobel +from skimage.morphology import watershed + +#------------------ Loading data -------------------------------- +from skimage import data +coins = data.coins() + +#------------ Histogram of grey values --------------------------- +histo = np.histogram(coins, bins=np.arange(0, 256)) + +plt.figure(figsize=(8, 3)) +plt.subplot(121) +plt.imshow(coins, cmap=plt.cm.gray, interpolation='nearest') +plt.axis('off') +plt.subplot(122) +plt.plot(histo[1][:-1], histo[0], lw=2) +plt.title('histogram of grey values') + +#------------------ Tentative thresholding -------------------------------- +plt.figure(figsize=(6, 3)) +plt.subplot(121) +plt.imshow(coins > 100, cmap=plt.cm.gray, interpolation='nearest') +plt.title('coins > 100') +plt.axis('off') +plt.subplot(122) +plt.imshow(coins > 150, cmap=plt.cm.gray, interpolation='nearest') +plt.title('coins > 150') +plt.axis('off') + +plt.subplots_adjust(hspace=0.01, wspace=0.01, top=1, bottom=0, left=0, + right=1) + + +#------------------ Edge-based segmentation -------------------------------- +edges = canny(coins/255.) + +fill_coins = ndimage.binary_fill_holes(edges) + +label_objects, nb_labels = ndimage.label(fill_coins) +sizes = np.bincount(label_objects.ravel()) +mask_sizes = sizes > 20 +mask_sizes[0] = 0 +coins_cleaned = mask_sizes[label_objects] + +plt.figure(figsize=(7, 3.)) +plt.subplot(131) +plt.imshow(edges, cmap=plt.cm.gray, interpolation='nearest') +plt.axis('off') +plt.title('Canny detector') +plt.subplot(132) +plt.imshow(fill_coins, cmap=plt.cm.gray, interpolation='nearest') +plt.axis('off') +plt.title('Filling the holes') +plt.subplot(133) +plt.imshow(coins_cleaned, cmap=plt.cm.gray, interpolation='nearest') +plt.axis('off') +plt.title('Removing small objects') +plt.subplots_adjust(hspace=0.01, wspace=0.01, top=1, bottom=0, left=0, + right=1) + + +#------------------ Region-based segmentation -------------------------------- + +markers = np.zeros_like(coins) +markers[coins < 30] = 1 +markers[coins > 150] = 2 + +elevation_map = sobel(coins) + + +segmentation = watershed(elevation_map, markers) + +plt.figure(figsize=(7, 3)) +plt.subplot(131) +plt.imshow(markers, cmap=plt.cm.spectral, interpolation='nearest') +plt.axis('off') +plt.title('markers') +plt.subplot(132) +plt.imshow(elevation_map, cmap=plt.cm.jet, interpolation='nearest') +plt.axis('off') +plt.title('elevation_map') +plt.subplot(133) +plt.imshow(segmentation, cmap=plt.cm.gray, interpolation='nearest') +plt.axis('off') +plt.title('segmentation') + +plt.subplots_adjust(hspace=0.01, wspace=0.01, top=1, bottom=0, left=0, + right=1) + + +#------------------ Labeling the coins -------------------------------- +labeled_coins, _ = ndimage.label(segmentation - 1) + +plt.figure(figsize=(6, 4)) +plt.imshow(labeled_coins, cmap=plt.cm.spectral, interpolation='nearest') +plt.axis('off') + +plt.show() diff --git a/doc/source/user_guide.txt b/doc/source/user_guide.txt index 7e0cd761..c4e7a8ff 100644 --- a/doc/source/user_guide.txt +++ b/doc/source/user_guide.txt @@ -5,4 +5,5 @@ User Guide :maxdepth: 1 user_guide/data_types + user_guide/segmentation user_guide/plugins diff --git a/doc/source/user_guide/elevation_map.jpg b/doc/source/user_guide/elevation_map.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3aca807e29e93375d69a6a55e2b3e3d6cd2d1407 GIT binary patch literal 75691 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

{hrqAbU5U$JENB>;s!}9u8#1@ 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 import numpy as np + >>> from skimage import data + >>> coins = data.coins() + >>> histo = np.histogram(coins, bins=np.arange(0, 256)) + +Simply thresholding the image leads either to missing significant parts +of the coins, or to getting parts of the background together with the +coins. This is due to the inhomogeneous lighting of the image. + +.. image:: ../../_images/plot_coins_segmentation_2.png + :target: ../auto_examples/applications/plot_coins_segmentation.html + :align: center + +A first idea is to take advantage of the local contrast, that is, to +use the gradients rather than the grey values. + +Edge-based segmentation +~~~~~~~~~~~~~~~~~~~~~~~ + +Let us first try to detect edges than enclose the coins. For edge +detection, we use the `Canny detector +`_ of ``skimage.filter.canny`` + +:: + + >>> from skimage.filter import canny + >>> edges = canny(coins/255.) + +As the background is very smooth, almost all edges are found at the +boundary of the coins, or inside the coins. +Now that we have contours that delineate the outer boundary of the coins, +we fill the inner part of the coins using the +``ndimage.binary_fill_holes`` function, that uses mathematical morphology +to fill the holes. + +:: + + >>> from scipy import ndimage + >>> fill_coins = ndimage.binary_fill_holes(edges) + +.. image:: ../../_images/plot_coins_segmentation_3.png + :target: ../auto_examples/applications/plot_coins_segmentation.html + :align: center + +Most coins are well segmented out of the background. Small objects from +the background can be easily removed using the ``ndimage.label`` +function, and removing objects smaller than a small threshold. + +:: + + >>> label_objects, nb_labels = ndimage.label(fill_coins) + >>> sizes = np.bincount(label_objects.ravel()) + >>> mask_sizes = sizes > 20 + >>> mask_sizes[0] = 0 + >>> coins_cleaned = mask_sizes[label_objects] + +However, the segmentation is not very satisfying, since one of the coins +has not been segmented correctly at all. The reason is that the contour +that we got from the Canny detector was not completely closed, therefore +the filling function did not fill the inner part of the coin. + +Therefore, this segmentation method is not very robust: if we miss a +single pixel of the contour of the object, we will not be able to fill +it. Of course, we could try first to dilate the contours in order to +close them. However, it is preferable to try a more robust method. + +Region-based segmentation +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Let us first determine markers of the coins and the background. These +markers are pixels that we can label unambiguously with one of the +phases. Here, the markers are found at the two extreme parts of the +histogram of grey values: + +:: + + >>> markers = np.zeros_like(coins) + >>> markers[coins < 30] = 1 + >>> markers[coins > 150] = 2 + +We will use these markers in a watershed segmentation. The name watershed +comes from an analogy with hydrology. The `watershed transform +`_ floods +an image of elevation from markers, in order to determine the catchment +basins of these markers. Watershed lines separate these catchment basins, +and correspond to the segmentation that is looked for. + +The choice of the elevation map is critical for a good segmentation. +Here, the amplitude of the gradient provides a good elevation map. We +use the Sobel operator for computing the amplitude of the gradient:: + + >>> from skimage.filter import sobel + >>> elevation_map = sobel(coins) + +From the 3-D surface plot shown below, we see that high barriers separate +well the coins from the background. + +.. image:: elevation_map.jpg + :align: center + +Let us now compute the watershed transform:: + + >>> from skimage.morphology import watershed + >>> segmentation = watershed(elevation_map, markers) + +.. image:: ../../_images/plot_coins_segmentation_4.png + :target: ../auto_examples/applications/plot_coins_segmentation.html + :align: center + +With this method, the result is satisfying for all coins. Even if the +markers for the background were not well distributed, the barriers in the +elevation map were high enough for these markers to flood the entire +background. + +We can now label all the coins one by one using ``ndimage.label``:: + + >>> labeled_coins, _ = ndimage.label(segmentation - 1) + +.. image:: ../../_images/plot_coins_segmentation_5.png + :target: ../auto_examples/applications/plot_coins_segmentation.html + :align: center + From 4e3895b44b63c2ff9e0555143d14ac2d6b739966 Mon Sep 17 00:00:00 2001 From: emmanuelle Date: Thu, 8 Dec 2011 11:04:34 +0100 Subject: [PATCH 2/4] ENH contours of segmentation in segmentation tutorial --- .../applications/plot_coins_segmentation.py | 17 +++++++++++++++-- doc/source/user_guide/segmentation.txt | 6 +++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/doc/examples/applications/plot_coins_segmentation.py b/doc/examples/applications/plot_coins_segmentation.py index 5b3c9de7..f572b5b6 100644 --- a/doc/examples/applications/plot_coins_segmentation.py +++ b/doc/examples/applications/plot_coins_segmentation.py @@ -107,6 +107,7 @@ elevation_map = sobel(coins) segmentation = watershed(elevation_map, markers) + plt.figure(figsize=(7, 3)) plt.subplot(131) plt.imshow(markers, cmap=plt.cm.spectral, interpolation='nearest') @@ -124,12 +125,24 @@ plt.title('segmentation') plt.subplots_adjust(hspace=0.01, wspace=0.01, top=1, bottom=0, left=0, right=1) +# ------------------- Removing a few small holes --------------------- + +segmentation = ndimage.binary_fill_holes(segmentation - 1) #------------------ Labeling the coins -------------------------------- -labeled_coins, _ = ndimage.label(segmentation - 1) +labeled_coins, _ = ndimage.label(segmentation) -plt.figure(figsize=(6, 4)) +plt.figure(figsize=(6, 3)) +plt.subplot(121) +plt.imshow(coins, cmap=plt.cm.gray, interpolation='nearest') +plt.contour(segmentation, [0.5], linewidths=1.2, colors='y') +plt.axis('off') +plt.subplot(122) plt.imshow(labeled_coins, cmap=plt.cm.spectral, interpolation='nearest') plt.axis('off') +plt.subplots_adjust(hspace=0.01, wspace=0.01, top=1, bottom=0, left=0, + right=1) + + plt.show() diff --git a/doc/source/user_guide/segmentation.txt b/doc/source/user_guide/segmentation.txt index fe820612..b61f3025 100644 --- a/doc/source/user_guide/segmentation.txt +++ b/doc/source/user_guide/segmentation.txt @@ -131,9 +131,13 @@ markers for the background were not well distributed, the barriers in the elevation map were high enough for these markers to flood the entire background. +We remove a few small holes with mathematical morphology:: + + >>> segmentation = ndimage.binary_fill_holes(segmentation - 1) + We can now label all the coins one by one using ``ndimage.label``:: - >>> labeled_coins, _ = ndimage.label(segmentation - 1) + >>> labeled_coins, _ = ndimage.label(segmentation) .. image:: ../../_images/plot_coins_segmentation_5.png :target: ../auto_examples/applications/plot_coins_segmentation.html From 1fb89aff0f891c760bc0034927fb00ca236fd1e2 Mon Sep 17 00:00:00 2001 From: Tony S Yu Date: Sun, 11 Dec 2011 18:07:43 -0500 Subject: [PATCH 3/4] Minor changes in wording. --- .../applications/plot_coins_segmentation.py | 4 ++-- doc/source/user_guide/segmentation.txt | 24 +++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/doc/examples/applications/plot_coins_segmentation.py b/doc/examples/applications/plot_coins_segmentation.py index f572b5b6..f2d65658 100644 --- a/doc/examples/applications/plot_coins_segmentation.py +++ b/doc/examples/applications/plot_coins_segmentation.py @@ -9,8 +9,8 @@ several coins outlined against a darker background. The segmentation of the coins cannot be done directly from the histogram of grey values, because the background shares enough grey levels with the coins that a thresholding segmentation is not sufficient. Simply thresholding the image -leads either to missing significant parts of the coins, or to getting parts -of the background together with the coins. +leads either to missing significant parts of the coins, or to merging parts +of the background with the coins. We first try an edge-based segmentation. We use the Canny detector to delineate the contours of the coins. These contours are filled using diff --git a/doc/source/user_guide/segmentation.txt b/doc/source/user_guide/segmentation.txt index b61f3025..657ed8c4 100644 --- a/doc/source/user_guide/segmentation.txt +++ b/doc/source/user_guide/segmentation.txt @@ -23,7 +23,7 @@ thresholding segmentation is not sufficient. >>> histo = np.histogram(coins, bins=np.arange(0, 256)) Simply thresholding the image leads either to missing significant parts -of the coins, or to getting parts of the background together with the +of the coins, or to merging parts of the background with the coins. This is due to the inhomogeneous lighting of the image. .. image:: ../../_images/plot_coins_segmentation_2.png @@ -36,7 +36,7 @@ use the gradients rather than the grey values. Edge-based segmentation ~~~~~~~~~~~~~~~~~~~~~~~ -Let us first try to detect edges than enclose the coins. For edge +Let us first try to detect edges that enclose the coins. For edge detection, we use the `Canny detector `_ of ``skimage.filter.canny`` @@ -49,7 +49,7 @@ As the background is very smooth, almost all edges are found at the boundary of the coins, or inside the coins. Now that we have contours that delineate the outer boundary of the coins, we fill the inner part of the coins using the -``ndimage.binary_fill_holes`` function, that uses mathematical morphology +``ndimage.binary_fill_holes`` function, which uses mathematical morphology to fill the holes. :: @@ -63,7 +63,7 @@ to fill the holes. Most coins are well segmented out of the background. Small objects from the background can be easily removed using the ``ndimage.label`` -function, and removing objects smaller than a small threshold. +function to remove objects smaller than a small threshold. :: @@ -80,15 +80,15 @@ the filling function did not fill the inner part of the coin. Therefore, this segmentation method is not very robust: if we miss a single pixel of the contour of the object, we will not be able to fill -it. Of course, we could try first to dilate the contours in order to +it. Of course, we could try to dilate the contours in order to close them. However, it is preferable to try a more robust method. Region-based segmentation ~~~~~~~~~~~~~~~~~~~~~~~~~ Let us first determine markers of the coins and the background. These -markers are pixels that we can label unambiguously with one of the -phases. Here, the markers are found at the two extreme parts of the +markers are pixels that we can label unambiguously as either object or +background. Here, the markers are found at the two extreme parts of the histogram of grey values: :: @@ -100,19 +100,19 @@ histogram of grey values: We will use these markers in a watershed segmentation. The name watershed comes from an analogy with hydrology. The `watershed transform `_ floods -an image of elevation from markers, in order to determine the catchment +an image of elevation starting from markers, in order to determine the catchment basins of these markers. Watershed lines separate these catchment basins, -and correspond to the segmentation that is looked for. +and correspond to the desired segmentation. -The choice of the elevation map is critical for a good segmentation. +The choice of the elevation map is critical for good segmentation. Here, the amplitude of the gradient provides a good elevation map. We use the Sobel operator for computing the amplitude of the gradient:: >>> from skimage.filter import sobel >>> elevation_map = sobel(coins) -From the 3-D surface plot shown below, we see that high barriers separate -well the coins from the background. +From the 3-D surface plot shown below, we see that high barriers effectively +separate the coins from the background. .. image:: elevation_map.jpg :align: center From 9ee513ca1026b9361e06e0c95e922d9419a22891 Mon Sep 17 00:00:00 2001 From: Stefan van der Walt Date: Sat, 17 Dec 2011 01:30:35 -0800 Subject: [PATCH 4/4] DOC: Add index of tutorials to user guide. --- doc/source/user_guide.txt | 4 ++-- doc/source/user_guide/{ => data}/elevation_map.jpg | Bin .../{segmentation.txt => tutorial_segmentation.txt} | 4 ++-- doc/source/user_guide/tutorials.txt | 7 +++++++ 4 files changed, 11 insertions(+), 4 deletions(-) rename doc/source/user_guide/{ => data}/elevation_map.jpg (100%) rename doc/source/user_guide/{segmentation.txt => tutorial_segmentation.txt} (99%) create mode 100644 doc/source/user_guide/tutorials.txt diff --git a/doc/source/user_guide.txt b/doc/source/user_guide.txt index c4e7a8ff..b262581c 100644 --- a/doc/source/user_guide.txt +++ b/doc/source/user_guide.txt @@ -2,8 +2,8 @@ User Guide ========== .. toctree:: - :maxdepth: 1 + :maxdepth: 2 user_guide/data_types - user_guide/segmentation user_guide/plugins + user_guide/tutorials diff --git a/doc/source/user_guide/elevation_map.jpg b/doc/source/user_guide/data/elevation_map.jpg similarity index 100% rename from doc/source/user_guide/elevation_map.jpg rename to doc/source/user_guide/data/elevation_map.jpg diff --git a/doc/source/user_guide/segmentation.txt b/doc/source/user_guide/tutorial_segmentation.txt similarity index 99% rename from doc/source/user_guide/segmentation.txt rename to doc/source/user_guide/tutorial_segmentation.txt index 657ed8c4..eda202d9 100644 --- a/doc/source/user_guide/segmentation.txt +++ b/doc/source/user_guide/tutorial_segmentation.txt @@ -114,9 +114,9 @@ use the Sobel operator for computing the amplitude of the gradient:: From the 3-D surface plot shown below, we see that high barriers effectively separate the coins from the background. -.. image:: elevation_map.jpg +.. image:: data/elevation_map.jpg :align: center - + Let us now compute the watershed transform:: >>> from skimage.morphology import watershed diff --git a/doc/source/user_guide/tutorials.txt b/doc/source/user_guide/tutorials.txt new file mode 100644 index 00000000..be724a63 --- /dev/null +++ b/doc/source/user_guide/tutorials.txt @@ -0,0 +1,7 @@ +Tutorials +========= + +.. toctree:: + :maxdepth: 1 + + tutorial_segmentation