{ "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "code", "language": "python", "outputs": [], "collapsed": false, "input": [ "%matplotlib inline" ], "metadata": {} }, { "source": "
\n

# Watershed segmentation

\n

The watershed is a classical algorithm used for segmentation, that\nis, for separating different objects in an image.

\n

Starting from user-defined markers, the watershed algorithm treats\npixels values as a local topography (elevation). The algorithm floods\nbasins from the markers, until basins attributed to different markers\nmeet on watershed lines. In many cases, markers are chosen as local\nminima of the image, from which basins are flooded.

\n

In the example below, two overlapping circles are to be separated. To\ndo so, one computes an image that is the distance to the\nbackground. The maxima of this distance (i.e., the minima of the\nopposite of the distance) are chosen as markers, and the flooding of\nbasins from such markers separates the two circles along a watershed\nline.

\n

See Wikipedia for more details on the algorithm.

\n
\n", "cell_type": "markdown", "metadata": {} }, { "cell_type": "code", "language": "python", "outputs": [], "collapsed": false, "input": "import numpy as np\nimport matplotlib.pyplot as plt\nfrom scipy import ndimage\n\nfrom skimage.morphology import watershed\nfrom skimage.feature import peak_local_max\n\n\n# Generate an initial image with two overlapping circles\nx, y = np.indices((80, 80))\nx1, y1, x2, y2 = 28, 28, 44, 52\nr1, r2 = 16, 20\nmask_circle1 = (x - x1)**2 + (y - y1)**2 < r1**2\nmask_circle2 = (x - x2)**2 + (y - y2)**2 < r2**2\nimage = np.logical_or(mask_circle1, mask_circle2)\n\n# Now we want to separate the two objects in image\n# Generate the markers as local maxima of the distance to the background\ndistance = ndimage.distance_transform_edt(image)\nlocal_maxi = peak_local_max(distance, indices=False, footprint=np.ones((3, 3)),\n labels=image)\nmarkers = ndimage.label(local_maxi)\nlabels = watershed(-distance, markers, mask=image)\n\nfig, axes = plt.subplots(ncols=3, figsize=(8, 2.7))\nax0, ax1, ax2 = axes\n\nax0.imshow(image, cmap=plt.cm.gray, interpolation='nearest')\nax0.set_title('Overlapping objects')\nax1.imshow(-distance, cmap=plt.cm.jet, interpolation='nearest')\nax1.set_title('Distances')\nax2.imshow(labels, cmap=plt.cm.spectral, interpolation='nearest')\nax2.set_title('Separated objects')\n\nfor ax in axes:\n ax.axis('off')\n\nfig.subplots_adjust(hspace=0.01, wspace=0.01, top=1, bottom=0, left=0,\n right=1)\nplt.show()", "metadata": {} } ], "metadata": {} } ], "metadata": { "name": "" } }