Function ialabel

Synopse

Label a binary image.

  • y = ialabel(f, Bc=iasecross()
    • y: Image
    • f: Image
    • Bc: Structuring Element ( connectivity).
01. import numpy as np
02. import ia870 as MT
03. from iasecross import iasecross
04. 
05. def ialabel(f, Bc=iasecross()):
06.     return ialabel_unionfind(f,Bc)
07. 
08. # Implementation using morphological reconstruction iainfrec
09. def ialabel_rec(f, Bc=iasecross()):
10.     assert MT.iaisbinary(f),'Can only label binary image'
11.     faux=f.copy()
12.     label = 1
13.     y = MT.iagray( f,'uint16',0)          # zero image (output)
14.     x = faux.ravel().nonzero()            # get list of unlabeled pixel
15.     while len(x[0]):
16.         fmark = np.zeros_like(f)
17.         fmark.flat[x[0][0]] = 1           # get the first unlabeled pixel
18.         r = MT.iainfrec( fmark, faux, Bc) # detects all pixels connected to it
19.         faux -= r                         # remove them from faux
20.         r = MT.iagray( r,'uint16',label)  # label them with the value label
21.         y = MT.iaunion( y, r)             # merge them with the labeled image
22.         label = label + 1
23.         x = faux.ravel().nonzero()        # get list of unlabeled pixel
24.     return y
25. 
26. # implementation by union find
27. def Find(x,parents): # uses path compression
28.    if parents[x] == x:
29.       return x
30.    else:
31.       parents[x] = Find(parents[x],parents)
32.       return parents[x]
33. 
34. def Union(n, p,parents):
35.    r = Find(n,parents)
36.    if r != p:
37.       parents[r] = p
38. 
39. def ialabel_unionfind(img,Bc):
40.    imshape = img.shape
41.    imsize  = img.size
42. 
43.    # Offsets and neighbors
44.    offsets = MT.iase2off(Bc,'fw')
45.    neighbors = MT.iaNlut(imshape,offsets)
46. 
47.    parents = np.arange(imsize,dtype = int)
48. 
49.    # Raster image and no-nzero pixels
50.    img = img.ravel()
51.    nonzero_nodes = np.nonzero(img)[0]
52.    img =  np.concatenate((img,np.array([0])))
53.    O = np.zeros(imsize, dtype = int)
54.    cur_label = 0
55.    # pass 1: backward scan, forward neighbors
56.    for p in nonzero_nodes[::-1]:
57.       for nb in neighbors[p]:
58.          if img[nb]:
59.             Union(nb,p,parents)
60.    # pass 2_1: root labeled
61.    pbool = parents[nonzero_nodes] == nonzero_nodes
62.    labels = np.arange(1,pbool.sum()+1)
63.    O[nonzero_nodes[pbool]] = labels
64.    # pass 2_2: labeling root descendants
65.    for p in nonzero_nodes[~pbool]:
66.        O[p] = O[parents[p]]
67.    return O.reshape(imshape)

Description

ialabel creates the image y by labeling the connect components of a binary image f, according to the connectivity defined by the structuring element Bc. The background pixels (with value 0) are not labeled. The maximum label value in the output image gives the number of its connected components.

Examples

Example 1

1. import numpy as np
2. import ia870 as MT
3. 
4. f=np.array([[0,1,0,1,1],
5.             [1,0,0,1,0]],bool)
6. g=MT.ialabel(f)
7. print 'f=\n',f
8. print 'g=\n',g
f=
[[False  True False  True  True]
 [ True False False  True False]]
g=
[[0 1 0 2 2]
 [3 0 0 2 0]]

Example 2

1. import ia636 as ia
2. 
3. f = adreadgray('blob3.tif') > 0
4. g = MT.ialabel(f,MT.iasebox())
5. nblobs = g.max()
6. print 'Number of connected components:', nblobs
7. adshow(f)
8. adshow(ia.ianormalize(g))
9. adshow(MT.iaglblshow(g))
Number of connected components: 18

Equation

Where

H is the number of image rows, and y1 and y2 are the row and column coordinates respectively.

See Also

  • iase2off - Create neighbor offsets from an structuring element
  • iaNlut - Precompute the neighbors 1D raster offsets for all pixels in an image
  • iagray - convert to grayscale image
  • iainfrec - inf-reconstruction
  • iaunion - union of images