Function ialabel

Synopse

Label a binary image.

  • y = ialabel(f, Bc=iasecross()
    • y: Image
    • f: Image
    • Bc: Structuring Element ( connectivity).
 1 import numpy as np
 2 import ia870 as MT
 3 from iasecross import iasecross
 4 
 5 def ialabel(f, Bc=iasecross()):
 6     return ialabel_unionfind(f,Bc)
 7 
 8 # Implementation using morphological reconstruction iainfrec
 9 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 = np.int32)
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 = np.int32)
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)
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