Toolbox ia870 | List of Figures | Fig. 7.13 | Fig. 7.17

Figure 7.14 - Segmentation of cornea cells from a noise image


The second example of watershed segmentation using inner and outer markers is slightly more complicated because the image is quite noisy and the inner and outer markers may touch in some places, but in essence the methodology is the same as the one used in the keyboard segmentation. The image in this example is a very poor quality microscopic image of a cornea tissue, shown in part (a) of Fig. 7.14. The cell markers are extracted by the regional maxima of the opening by a disk of the input image

We can model each cell as a small hill and we want to mark the top of each hill that has a base larger than the disk used in the opening. Parts (b) and (c) of the figure show the opened image and its regional maxima, respectively.

The regional maxima constitute the inner markers. For the outer markers, instead of using the SKIZ as in the previous example, it is better to compute the watershed on the negation of the input image because we are interested in finding the influence zone of each cell. Negating the input image, the cells become basins, and taking the watershed transform from the inner markers yields the influence zones of the basins, as shown in part (d). These compose the background (outer) marker. One needs to be careful in combining both markers as they can touch each other at some points. We first label the inner markers with integers and then label the outer marker by 1 greater than the maximum inner-marker label. The final watershed lines are computed on the morphological gradient, shown in part (e). Although it is a very noisy gradient, the final watershed lines, which are overlaid on the input image and displayed in part (f), provide a satisfactory segmentation.

Demo Script

 1 import ia870 as MT
 3 aux = adreadgray('corneacells.tif')
 4 a = aux[:aux.shape[0]/2,:aux.shape[1]/2]
 5 c = MT.iaopen(a,MT.iasedisk(2))
 6 d = MT.iaregmax(c)
 7 e = MT.ianeg(a)
 8 f = MT.iacwatershed(e, d, MT.iasebox())
 9 g = MT.iagray(f, 'uint16', 1)
10 h1 = MT.iaaddm(MT.ialabel(d), uint16(1))
11 h = MT.iaintersec(MT.iagray(d,'uint16'), h1)
12 i = MT.iaunion(g, h)
13 j = MT.iagradm(a)
14 k = MT.iacwatershed(j, i)
16 adshow(a, '(a)')
17 adshow(c, '(b)')
18 adshow(MT.iapad(MT.ianeg(d)), '(c)')
19 adshow(MT.iagshow(f,d), '(d)')
20 adshow(MT.iapad(MT.ianeg(j)), '(e)')
21 adshow(MT.iagshow(a,k), '(f)')