Should be considered a simple proof-of-concept only.
I found a TikTok video from Morley Kert in which a Shaper Trace was used to scan a hand sketch into a vector format, for subsequent modelling and 3D printing. I wanted to play around with the concept immediately and thought I could probably do something similar with a little hacking around in Python.
- Create a page with QR codes placed at known locations (which can be printed out).
- Draw a design (or place a contrasting object) on that page and take a digital photograph of it.
- Analyse that iamge with pyzbar, returning the QR code locations
- Use pillow to perform a perspective transform using the QR code locations, effectively straightening the image (removing any perspective skew introduced when the photograph was taken).
- Use pyautotrace to trace the straightened image
- Allow selection of different paths within the trace.
- Output the selected paths as SG or DXF.
Thanks to the strength of the wonderful Python ecosystem, this works and took only a handful of lines of code. And thanks to Stack Overflow commenters for the perspective transform code.
- Clone the repo.
- Make sure that the dependences are installed via
pip install requirements.txtor similar. (Note: if you're on a Mac, pyzbar may be tricky to install. It requiresbrew install zbarfirst, and for me, also took some searching and hacking around.) - Run
streamlit run open_tracer.pyand open an image file to trace (two are included). - All being well, you'll see the traced vector output; you can de-select/select/zoom in on invidiual paths on the left.
- Lastly save the selected paths to SVG or DXF using the buttons underneath the preview image.
- Note that you can trace both drawings (per test.jpg) and also actual objects placed on a contrasting background (per holbrook arm image.jpg).
- Download and print out page v2.pdf without scaling. Note that one of the shorter sides of the resultant print has a slightly larger margin - this is deliberate, to account for a typical printer's print area. It's A4 only currently - sorry.
- Draw or place something contrasting on the page.
- Place the page in landscape, with the larger margin to the right, and take a careful and clear picture of the page (i.e. with as little skew and blur as possible). If the QR codes are too blurred they may be unreadable and the process will fail.
- Run open_tracer as above, and select your new image file to trace.
- This is beta/proof-of-concept code. There's very little error checking.
- In particular, at present there's no accounting for different rotations of the page, and thus different positioning of the QR codes. The printable page has a larger margin along one of the shorter sides (i.e. the bottom, as printed) to account for the wider print area margin needed there on most printers. Put this part of the page to the right (and therefore in landscape) as you photograph it. What it really needs is to be on the right in the final image that is traced, so you could also rotate the image aftwards.
- The photo needs to be clear, as pyzbar needs to recognise all four QR codes to support subsequent perspective correction. I had issues making this work reliably with an iPhone 13 Pro and 1 cm QR codes, so I increased them to 1.5 cm which seems to be much more reliable.
- Currently, with the page laid out as described above, the scanned area will be the area surrounded by the inner corners of the QR codes, so ~24cm by ~16cm.
- The output dimensions seem pretty accurate. They're output in tenths of a millimeter, so you might need to fix the scaling after importing into your chosen CAD or drawing package.
- If you traced a line drawing, both sides of the line will be traced. You'll probably want to select the path on one of the sides only.
- Fix the rotation issue so any orientation of page/image will work.
- Make the output units sensible and/or selectable.
- Add a US letter page (and maybe other page sizes?) with different QR codes to automate recognition of different dimensions and scalings.
v0.1: command-line PoC v0.2: added streamlit UI and ability to select/deselect individual paths