Toolbox ia870 | List of Figures | Fig. 2.14 | Fig. 2.17

Figure 2.16 - PCB component detection

Description

Here we present a complete demonstration of a real-world example using the MT. The input image is a binary image of a printed circuit board (PCB). The goal is to identify the various components of the PCB: holes, different types of islands and different types of tracks. The shape decomposition is created mainly using openings by structuring elements that depend on the geometry of the components.

Image reading - The binary image of a printed circuit board is read (a).

Detecting holes - A new image is created by filling the holes (b), which will be described in the next chapter. The input image is subtracted from this new image without holes. The resulting residues are the holes (c).

Detecting square islands - The square islands are detected using an opening by a square of size 17 x 17 (d). The result is dilated and intersected with the input image to show the square PCB pads (e).

Detecting circle islands - A residues image (f) is created by subtracting the already detected square pads from the input image. The circle islands are detected using an opening by a Euclidean disk on the residues image (g). The result is dilated and intersected with the input image (h).

Detecting rectangular islands - The rectangular islands are detected using an opening by a rectangle of size 25 x 8 on a residues image (k). The rectangle structuring element is built from the composition of vertical and horizontal lines.

Detecting thick connections - The thick connections are detected using an opening by a 5 x 5 square on a residues image (n).

Detecting thin connections - The thin connections are detected using an opening by a 3 x 3 square on a residues image (q).

Combining all together - The main components of the circuit are combined in a single image. Each image is converted to gray scale using a unique label and unioned afterwards. (image r)

Demo Script

 1 import numpy as np
 2 import ia870 as MT
 3 from handson.lib import iabggmodel, draw_se_axis
 4 
 5 a = adreadgray('pcb1bin.tif') > 0
 6 adshow(MT.iapad(MT.ianeg(a)), '(a)')
 7 
 8 b = MT.iaclohole(a)
 9 c = MT.iasubm(b,a) # holes
10 
11 adshow(MT.iapad(MT.ianeg(b)), '(b)')
12 adshow(MT.iapad(MT.ianeg(c)), '(c)')
13 
14 d = MT.iaopen(b,MT.iasebox(8))
15 e = MT.iacdil(d, a) # square
16 
17 adshow(MT.iapad(MT.ianeg(d)), '(d)')
18 adshow(MT.iapad(MT.ianeg(e)), '(e)')
19 
20 f = MT.iasubm(b, d)
21 g = MT.iaopen(f, MT.iasedisk(8))
22 h = MT.iacdil(g,a) # circle
23 
24 adshow(MT.iapad(MT.ianeg(f)), '(f)')
25 adshow(MT.iapad(MT.ianeg(g)), '(g)')
26 adshow(MT.iapad(MT.ianeg(h)), '(h)')
27 
28 i = MT.iasubm(f, g)
29 j = MT.iaopen(i, MT.iasedil(MT.iaseline(8,90), MT.iaseline(25)))
30 k = MT.iacdil(j,a)
31 
32 adshow(MT.iapad(MT.ianeg(i)), '(i)')
33 adshow(MT.iapad(MT.ianeg(j)), '(j)')
34 adshow(MT.iapad(MT.ianeg(k)), '(k)')
35 
36 l = MT.iasubm(i,j)
37 m = MT.iaopen(l, MT.iasebox(2))
38 n = MT.iacdil(m,a) # thick tracks
39 
40 adshow(MT.iapad(MT.ianeg(l)), '(l)')
41 adshow(MT.iapad(MT.ianeg(m)), '(m)')
42 adshow(MT.iapad(MT.ianeg(n)), '(n)')
43 
44 o = MT.iasubm(l,m)
45 p = MT.iaopen(o, MT.iasebox())
46 q = MT.iacdil(p,a)  # thin tracks
47 
48 adshow(MT.iapad(MT.ianeg(o)), '(o)')
49 adshow(MT.iapad(MT.ianeg(p)), '(p)')
50 adshow(MT.iapad(MT.ianeg(q)), '(q)')
51 
52 r = MT.iaunion(MT.iagray(c,'uint8',1),MT.iagray(e,'uint8',2),
53         MT.iagray(h,'uint8',3),MT.iagray(k,'uint8',4),
54         MT.iagray(n,'uint8',5))
55 
56 r =  MT.iaunion(r,MT.iagray(q,'uint8',6))
57 
58 adshow(MT.ianeg(MT.iaglblshow(r,'BORDER')), '(r)')

(a)

(b)

(c)

(d)

(e)

(f)

(g)

(h)

(i)

(j)

(k)

(l)

(m)

(n)

(o)

(p)

(q)

(r)