[mmdgear] [Up] [mmdleaf] | Demonstrations |
This demonstration illustrates the estimation of the eccentricity of the holes on the pads of a PCB, and the estimation of the narrowest copper around the holes.
Use the close hole function to remove the holes. Note that one hole is open. This is not considered in this experiment. The regional maxima of the distance transform gives the radius of the largest disk inside the pad. We are interested only in radius larger than 20 pixels.
>>> b = mmclohole(a)
>>> mmshow(b)
>>> d = mmdist(b,mmsecross(),'EUCLIDEAN')
>>> e = mmregmax(d,mmsebox())
>>> f = mmthreshad(d, uint16([20])) # radius larger than 20 pixels
>>> g = mmintersec(e,f)
>>> h = mmblob(mmlabel(g,mmsebox()),'CENTROID'); # pad center
>>> mmshow(b,mmdil(h))
![]() |
![]() |
|
b | b,mmdil(h) |
The holes are given by the difference of the pad image from the original image. Repeat the same procedure to find the center of the pads to find now the center of the holes.
>>> i = mmsubm(b,a)
>>> mmshow(i)
>>> j = mmdist(i,mmsecross(),'EUCLIDEAN')
>>> k = mmregmax(j,mmsebox())
>>> l = mmblob(mmlabel(k,mmsebox()),'CENTROID') # hole center
>>> mmshow(i,mmdil(l))
![]() |
![]() |
|
i | i,mmdil(l) |
First both centers (pads and holes) are displayed together. Then the actual misalignment is computed using the distance from one point to the other.
>>> from Numeric import nonzero
>>> mmshow(a,h,l)
>>> m = mmdist(mmneg(l),mmsecross(),'EUCLIDEAN')
>>> n = mmintersec(mmgray(h),uint8(m))
>>> mmshow(n,a)
>>> i = nonzero(n.flat)
>>> x = i / n.shape[1]
>>> y = i % n.shape[1]
>>> for k in range(len(i)): print 'displacement of %d at (%d,%d)\n' %(n[x[k],y[k]],x[k],y[k])
displacement of 3 at (43,88) displacement of 8 at (44,191) displacement of 6 at (153,187)
![]() |
![]() |
|
a,h,l | n,a |
First, the thinning to compute the skeleton of the PCB image, then remove iteratively all the end points of the skeleton so just the skeleton loop around the holes remains. Find the minimum distance of these loops to the border and display their location.
>>> o=mmthin(a)
>>> p=mmthin(o,mmendpoints())
>>> mmshow(a,p)
>>> q = mmdist(a,mmsecross(),'EUCLIDEAN')
>>> r = mmgrain(mmlabel(p,mmsebox()),q,'min') # minimum
>>> s = mmgrain(mmlabel(p,mmsebox()),q,'min','data') # minimum
>>> from Numeric import ravel
>>> for k in ravel(s): print 'Minimum distance: %d pixels' %(2*k+1)
Minimum distance: 7 pixels Minimum distance: 7 pixels Minimum distance: 3 pixels
>>> t = mmintersec(mmcmp(r,'==',q),a)
>>> mmshow(a,mmdil(t))
![]() |
![]() |
|
a,p | a,mmdil(t) |
[mmdgear] [Up] [mmdleaf] | ![]() |
Copyright (c) 2003, Roberto A. Lotufo, UNICAMP-University of Campinas; Rubens C. Machado, CenPRA-Renato Archer Research Center. |