Using Transform Matrix for PCB Drilling – Part 2

It has been a long time since last time I wrote on this blog. I finally decided to complete this project because I need to make a small bunch of pcb and I want the possibility to review the boards whenever I want, so I cannot depend on an external manufacturing company. As I described in the first part I coded a little tool in Python to achieve my goal. I also added a basilar Excellon support so it is possible to load the file generated by Eagle and it allows to compute an affine transformation in order to make an accurate drilling. I used Numpy and OpenCV libraries to get straight to te result but let’s take a look at the setup. I needed a camera to locate the pads and I went for the Logitech C270, a nice HD resolution webcam for the price. The zoom is fixed but it is easily adjustable with its own focus ring.


The camera comes with a fancy support so I made a new one from scratch to attach the camera to the spindle holder


The first thing to do is to set the camera offset. For convenience I drill a reference hole touching off at X0 Y0 and I locate it through the camera view. The coordinate now displayed on the machine is the actual offset.

Offset Screen

Now I can pick up three points and locate the relative pads center trough the camera. It is common sense to not choose points that lay on a straight line. Of course the farther the points are, the better the result could be.

Point 1


Finally I can let the software do its job. As you can see every hole is just where it should be. Below you can find the download links for Windows/ Mac OS X binaries. Let me know if it’s working for you and please notify me if you find any bugs  :-)

Final Result

Windows Binaries (64-bit) (3559 downloads) Mac OS X Installer (865 downloads)

Warning: count(): Parameter must be an array or an object that implements Countable in /home/mhd-01/ on line 399

14 thoughts on “Using Transform Matrix for PCB Drilling – Part 2

  1. Steve

    Hey, this is really great! I would like to apply these techniques for some automated measuring of some flat 2D things, but I’m not as good with math as you and am just learning python. Is there any chance you can make the source code available? Thanks for sharing your knowledge…
    – Steve

    1. alex89rm Post author

      Hi Steve ! I’m surely going to share the source code but not before I have it reorganized in a more readable way. That could take some time, mail me if you need help. 😉

      1. Steve

        You have been a help already :-) I’m just beginning Python (I know C allright) and wasn’t aware of the CV libs for Python. And you mentioned another python lib that will save me some digging…

        I’ll be awaiting your code release, and brushing up on CV through Python in the meantime!

        – Steve

  2. Kevin Ward

    This is really fantastic.

    At my university we don’t have any CNC equipment available for students, so I do all the work for my projects in a manual machine shop. In order to do accurate work, I have to spend a lot of time just lining up the work-piece to the axes of the milling machine, and yet more time locating the spindle in reference to features of the part.

    Therefore I am very impressed by your process which automates some of that process, effectively aligning the machine to the part, instead of the other way around.


    Greetings from the USA, in the middle of the hill & hollers of West Virginia!

    I just got back from Staples, an office supply about 24 miles up the interstate hyway from here, and brought back a webcam that looks as if it may be suitable to do this. On plugging it in, this was logged on my linux machine:
    Aug 14 17:16:14 coyote kernel: [965175.048693] usb 1-6.3: new high speed USB device using ehci_hcd and address 19
    Aug 14 17:16:14 coyote kernel: [965175.191686] usb 1-6.3: configuration #1 chosen from 1 choice
    Aug 14 17:16:15 coyote kernel: [965176.544145] 19:3:1: cannot get freq at ep 0x82
    Aug 14 17:16:15 coyote kernel: [965176.616784] generic-usb 0003:045E:0772.0008: hiddev100,hidraw7: USB HID v1.01 Device [Microsoft Microsoft® LifeCam Studio(TM)] on usb-0000:00:02.1-6.3/input4
    Aug 14 17:16:15 coyote kernel: [965176.616889] uvcvideo: Unknown video format 3032344d-0000-0010-8000-00aa00389b71
    Aug 14 17:16:15 coyote kernel: [965176.616903] uvcvideo: Found UVC 1.00 device Microsoft® LifeCam Studio(TM) (045e:0772)
    Aug 14 17:16:16 coyote kernel: [965176.675133] input: Microsoft® LifeCam Studio(TM) as /devices/pci0000:00/0000:00:02.1/usb1/1-6/1-6.3/1-6.3:1.0/input/input10
    Aug 14 17:16:16 coyote kernel: [965176.675212] usbcore: registered new interface driver uvcvideo
    Aug 14 17:16:16 coyote kernel: [965176.675216] USB Video Class driver (v0.1.0)

    And, on running cheese, a photobooth sort of an application, cheese found it and displays a truly great picture.
    Its round, about 3cm in diameter, and appears to be able to autofocus down to about the 80mm range which should be usable. So my question for you, is how did you go about getting the crossed hairs display superimposed on your video?

    Cheese has some effects that can be used to modify the image, but of the choices, there aren’t any crossed hairs.
    From the looks of what is sitting in /usr/share/cheese/effects, they are all .png’s.

    But I am unsure of how to go about adding a set of crossed hairs with a transparent background to the cheese effects menu.
    Your code in is OS independent so I don’t expect to have any problems incorporating those bits & pieces into LinuxCNC.

    Do have any suggestions?

    Thank you very much Alissio

    Cheers, Gene

  4. Gene Heskett

    Thank you very much, Allessio, I think I almost have it by following along
    with the above link unless I skipped something.

    Here is the error I log to the console, on a Lucid (10.04.4 LTS) machine,
    with the camera plugged in and showing a good pix if cheese is being used.

    Starting LinuxCNC…
    parse error?
    Unable to instantiate [input.v4l:0]
    Traceback (most recent call last):
    File “/usr/bin/camview-emc”, line 291, in
    view = EmcView(options)
    File “/usr/bin/camview-emc”, line 84, in __init__
    RuntimeError: Unable to instantiate [input.v4l:0]
    Shutting down and cleaning up LinuxCNC…
    Cleanup done

    And the Cam View tab is blank. And the buttons below the window are missing

    However, an ls -R of /dev/v4l returns this:

    gene@shop:~/linuxcnc/configs/my-mill-atom$ ls -R /dev/v4l
    by-id by-path



    So it looks like a very minor configuration error.


    Cheers & thank you very much, Gene

  5. Dany

    Hi Alessio, good work!

    In your video, at the end, I can see you make the final board cutout, and the PCB it’s aligned in the same way you did the holes.
    Do you have another routine to transform the coordinates from the cut-out g-code ?
    Maybe it’s an easy one and I’m not seeing it how to do it…

    Keep up the great work, look forward to seeing more :)


    1. alex89rm Post author

      Hi Daniel, it’s nice to hear from you. You can process the cutout gcode in the same way, opening it in the utility. Just be careful to avoid circular interpolation cause it is not supported, use the split curves into segment option from the post processor instead 😉

  6. Pingback: Using Transform Matrix for PCB Drilling – Part 1 |

  7. Gene Heskett

    Yup, I finally got me a new domain name registered! No more screwing around with dyndns for a static address.

    Its been some time & experiments with various cameras, currently I have an endoscope wannabe mounted and it looks usable. A screenshot has been put in the tmppix link of the above web page.

    But ATM, the HALUI vs various buttons seems to be out of synch, apparently it enums the MDI commands. I have installed a small offset in both direction in the tool.tbl at T99 P99, but that isn’t causing any motion when I check or uncheck the G43H99 checkbox although the check marker is drawn or cleared. I have also installed (msg, this is “filename”) in those files, however none of the “align” related buttons appear to be linked with any of this. The buttons shade when clicked, but ANAICT nothing is happening. From reading the code in camstore.ngc, I am assuming that is what should be executed when I click the Save XYZ button, but that isn’t what I am getting.

    Some guidance on getting all these buttons back in synch would be a great help.

    However (doh!) I see that I have not been editing the files by the same name in the nc_files directory.

    Suggestion: Can we assign a different directory for all these extra files to reside in with a new phrase in the main .ini file? and then use this $VAR/filename in the HALUI stanza? My nc_files directory has been in service 7 or 8 years, and has collected tons of cruft, and I’d like to put this stuff in its own ~/gene/linuxcnc/camview.stf directory, making it much easier to track.

    Thank you very much.

    Cheers, Gene aka

  8. pancary

    Hello .
    Great Job.
    I’m working on a project where I will use image recognition to drill automatically the pcb.
    I am working on software by now, but my hardware setup wil be like yours.


Leave a Reply

Your email address will not be published. Required fields are marked *