The WATERSHED function applies the morphological watershed operator to a grayscale image. This operator segments images into watershed regions and their boundaries. Considering the gray scale image as a surface, each local minimum can be thought of as the point to which water falling on the surrounding region drains. The boundaries of the watersheds lie on the tops of the ridges. This operator labels each watershed region with a unique index, and sets the boundaries to zero.
Typically, morphological gradients, or images containing extracted edges are used for input to the watershed operator. Noise and small unimportant fluctuations in the original image can produce spurious minima in the gradients, which leads to oversegmentation. Smoothing, or manually marking the seed points are two approaches to overcoming this problem. For further reading, see Dougherty, “An Introduction to Morphological Image Processing”, SPIE Optical Engineering Press, 1992.
The following code crudely segments the grains in the data file in the IDL Demo data directory containing a magnified image of grains of pollen. Note that the IDL Demos must be installed in order to read the image used in this example.
It inverts the image, because the watershed operator finds holes, brightening the grains of pollen. Next, the morphological closing operator is applied with a disc of radius 9, contained within a 19 by 19 kernel, to eliminate holes in the image smaller than the disc. The watershed operator is then applied to segment this image. The borders of the watershed images, which have pixel values of zero, are then merged with the original image and displayed as white.
; Define the radius of a disc
r = 9
; Create a disc of radius r
disc = SHIFT(DIST(2*r+1), r, r) LE r
; Read the image
READ_JPEG, FILEPATH('pollens.jpg', $
; Invert the image
b = MAX(a) - a
TVSCL, b, 0
; Remove holes of radii less than r
c = MORPH_CLOSE(b, disc, /GRAY)
TVSCL, c, 1
; Create watershed image
d = WATERSHED(c)
; Display it, showing the watershed regions
TVSCL, d, 2
; Merge original image with boundaries of watershed regions
e = a > (MAX(a) * (d EQ 0b))
TVSCL, e, 3
Returns an integer array of the same dimensions as the input image. An element of the Result array contains the integer identifier of the watershed region in which the corresponding pixel falls, or a zero if the corresponding pixel falls along the separation between regions.
Note: If the LONG keyword is set, Result is an array of long integers; otherwise it is an array of short integers. If the LONG keyword is not set, Result will be clipped to a maximum of 65530 regions. (Regions above 32767 will have negative values; if you have more than 32767 regions you may want to convert your Result to unsigned integers using UINT). Use the NREGIONS keyword to determine the actual number of regions.
The two-dimensional image to be segmented. Image is converted to byte type if necessary.
Set this keyword to either 4 (to select 4-neighbor connectivity) or 8 (to select 8-neighbor connectivity). Connectivity indicates which pixels in the neighborhood of a given pixel are sampled during the segmentation process. 4-neighbor connectivity samples only the pixels that are immediately adjacent horizontally and vertically. 8-neighbor connectivity samples the diagonally adjacent neighbors in addition to the immediate horizontal and vertical neighbors. The default is 4-neighbor connectivity.
Set this keyword to return an array of long integers, instead of short integers. This keyword is useful if your image contains more than 32766 regions.
Set this keyword to a named variable that will contain the total number of regions within Image. In most cases, this will be equal to the maximum value of Result.
Tip: If the LONG keyword is not set, and NREGIONS is greater than 32766, then the Result overflowed the maximum. If this occurs, you may wish to re-run WATERSHED with the LONG keyword set.
Added LONG and NREGIONS keywords