Skip to content

PCB Matching

firepick1 (localhost) edited this page Oct 30, 2016 · 25 revisions

Generating computer vision PCB matching templates

A common pick and place (PnP) challenge is to pinpoint the printed circuit board location with respect to the PnP machine. PCB calibration is commonly accomplished using computer vision to match a fiducial marker, which can be simply be a screw hole centered on a copper circular pad. To support PnP automation, the industry normally requires that the board designer place multiple PCB fiducials on a board so that the PnP machines can calibrate PCB position. (as a side note, one wonders if the assymetry of screwholes in PCBs is from their use as fiducial markers)

For DIY hobbyists, creating ad hoc tiny PCBs in low volumes, it may be interesting to skip PCB fiducials and just use the PCB itself as a matching template. Specifically, we can use jspcb to generate a computer vision matching template from the Gerber files alone.

Let's take the AdaFruit PCB Ruler as an example:

We run jspcb with gerber-template.json:

jspcb -j json/gerber-template.json

We don't want to use the entire PCB as a matching template. Instead, we want to use just a small section. The bounds attribute of the jspcb JSON transformation file lets us choose that PCB subsection easily. Using the Gerber files, jspcb quickly generates an image of the PCB that looks surprisingly realistic:

With template in hand, we can use FireSight to locate our template in the camera image:

firesight -p json/matchtemplate.json -i doc/ruler-cam.jpg -Dtmplt=/tmp/ruler-tmplt.png -o /tmp/match.png

FireSight quickly matches the PCB subsection and tells us that a single match occurred at (160,229). The match was in FireSight stage match0, which matches the template rotated by 0 degrees. Other stages match different angles (i.e., 90, 180, 270):

{
  "s1":{},
  "match0":{
    "rects":[
      {
        "x":160.0,
        "y":229.0,
        "width":100.0,
        "height":100.0,
        "angle":-0.0,
        "corr":"1"
      }
    ],
    "maxVal":"0.687064",
    "matches":1
  },
  "match90":{
    "rects":[],
    "maxVal":"0.218009",
    "matches":0
  },
  "match180":{
    "rects":[],
    "maxVal":"0.237052",
    "matches":0
  },
  "match270":{
    "rects":[],
    "maxVal":"0.17339",
    "matches":0
  },
  "s6":{},
  "s7":{},
  "s8":{},
  "s9":{}
}

Yay! We located our PCB!

Considerations

Scale

FireSight uses OpenCV matchTemplate to match a template within an image. It does so by "sliding the template over the image", and will return the position with the highest pixel-to-pixel correspondence. Because the correspondence is pixel-by-pixel, we have to make sure that our matching template is the same pixels/mm scale as the image. In other words, we need to know how far away the PCB is so that we can calculate its image width. That image width allows us to calculate the PNG width of our template for jspcb.

Angle

Another consideration is template angle. For successful matching, the template must be rotated to match the imaged PCB. It's usually easy to fix the angle of the imaged PCB by simply clamping it to a fixed straight-edge. Fixing the PCB in this manner will reduce the number of possibly matching templates to at most four templates which can be tried in sequence. In fact, FireSight will automatically rotate your template, so you only need a single template at four angles. Here's an example of a 270 degree match with the above template. Note that the FireSight pipeline color codes the match for each angle (white is 270 degrees):

Silkscreen vs. Copper

Michael Anton pointed out that silkscreen layers are frequently off by about 0.25mm from the copper layer. Because of this misalignment, it is best to use just two layers for creating a PCB matching template:

  • GKO to define board dimensions
  • GTP to match just the SMD pads

For example, compare a silkscreen+copper template (sfe-gto.png) with a smd-pads-only template (sfe-gtp.png):

sfe-gto.png→ sfe-gtp.png→

These two templates will both match the same PCB region, but they match at slightly different positions. In fact, they are off by one pixel, which at this scale is about 0.25mm

sfe-gto.png sfe-gtp.png
matched at ( x:166.0, y:159.0 } matched at { x:167.0, y:159.0 }

Notice that silkscreen in camera image is indeed shifted left slightly from Gerber template image.

Clone this wiki locally