# Synopse

Label the flat zones of gray-scale images.

• y = ialabelflat(f, Bc=iasecross(), delta=0)
• y: Image
• f: Image
• Bc: Structuring Element ( connectivity).
• delta: Double Connectivity given by .
```01. import numpy as np
02. import ia870 as MT
03. from iasecross import iasecross
04.
05. def ialabelflat(f, Bc=iasecross(), delta=0):
06.     fr = f.astype(np.int) + 1
07.     return ialabelflat_unionfind(fr,Bc,delta)
08.
09. # implementation by union find
10. def Find(x,parents): # uses path compression
11.    if parents[x] == x:
12.       return x
13.    else:
14.       parents[x] = Find(parents[x],parents)
15.       return parents[x]
16.
17. def Union(n, p,parents):
18.    r = Find(n,parents)
19.    if r != p:
20.       parents[r] = p
21.
22. def ialabelflat_unionfind(img,Bc,delta):
23.    imshape = img.shape
24.    imsize  = img.size
25.
26.    # Offsets and neighbors
27.    offsets = MT.iase2off(Bc,'fw')
28.    neighbors = MT.iaNlut(imshape,offsets)
29.
30.    parents = np.arange(imsize,dtype = int)
31.
32.    # Raster image and no-nzero pixels
33.    img = img.ravel()
34.    nonzero_nodes = np.nonzero(img)[0]
35.    img =  np.concatenate((img,np.array([0])))
36.    g = np.zeros(imsize, dtype = int)
37.    cur_label = 0
38.    # pass 1: backward scan, forward neighbors
39.    for p in nonzero_nodes[::-1]:
40.       v = img[p]
41.       for nb in neighbors[p]:
42.          if img[nb] and (abs(v - img[nb]) <= delta):
43.             Union(nb,p,parents)
44.    # pass 2_1: root labeled
45.    pbool = parents[nonzero_nodes] == nonzero_nodes
46.    labels = np.arange(1,pbool.sum()+1)
47.    g[nonzero_nodes[pbool]] = labels
48.    # pass 2_2: labeling root descendants
49.    for p in nonzero_nodes[~pbool]:
50.        g[p] = g[parents[p]]
51.    return g.reshape(imshape)```

# Description

ialabelflat creates the image y by labeling the flat zones of f, according to the connectivity defined by the structuring element Bc. A flat zone is a connected region of the image domain in which all the pixels have the same gray-level (delta=0). When delta is different than zero, a quasi-flat zone is detected where two neighboring pixels belong to the same region if their difference gray-levels is smaller or equal delta. The minimum label of the output image is 1 and the maximum is the number of flat-zones in the image.

# Examples

## Example 1

```01. from ia870 import ialabelflat
02. from ia870 import iasecross
03.
04.
05. f=array([
06.    [5,5,8,3,0],
07.    [5,8,8,0,2]],'uint8')
08. g=ialabelflat(f)
09. print 'g=\n',g
10. g1=ialabelflat(f,iasecross(),2)
11. print 'g1=\n',g1```
```g=
[[1 1 2 3 4]
[1 2 2 5 6]]
g1=
[[1 1 2 3 4]
[1 2 2 4 4]]
```

## Example 2

```01. from ia870 import iadist
02. from ia870 import iasebox
03. from ia870 import iaglblshow
04. import ia636 as ia
05.
06.
08. print 'info:',ia.iaimginfo(f)
10. g= d /8
12. fz=ialabelflat(g,iasebox())
14. print 'n. of labels =', fz.max()```
```info: <type 'numpy.ndarray'> (239, 239) uint8 0 255
n. of labels = 13
```

## Example 3

```1. f=adreadgray('pcb_gray.tif')
2. print 'info:',ia.iaimginfo(f)
3. delta = 3
4. t = time.time()
5. g=ialabelflat(f,iasebox(),delta)
6. print 'time:',time.time()-t,'seconds'
```info: <type 'numpy.ndarray'> (256, 256) uint8 32 255