Ciclop: a scanner made of printer parts

8 minute read

Published:

Last month at Quark, our table held three machines: the submarine, the wall-drawing robot, and a 3D scanner built mostly out of 3D printed parts. This post is about the scanner, and about the part of the project the kit documentation never mentions, which is everything after the assembly.

Our Quark booth: the scanner with its checkerboard calibration target on a white tablecloth, the handwritten spec poster on the wall

The handwritten poster claims 0.5 mm resolution, two to three minutes per scan, a 250 x 250 x 205 mm scanning volume, and scanning in the dark. Every one of those claims survived a festival crowd poking at the machine, and the last one is my favorite, for reasons below.

Why build a scanner

The Aerodynamics Club printer will make you any part you can model. The bottleneck is the modeling, because most of what you want to copy already exists as an object on your desk. A scanner closes the loop: digitize the thing, edit the mesh, print the edit. Rapid prototyping stops being about geometry you can describe and starts being about geometry you can hold.

We picked Ciclop, BQ’s open-source laser scanner, released with its files under Creative Commons, over Atlas and FabScan, after reading more scanner documentation than any of the three projects probably expected of an undergraduate. FabScan’s bachelor thesis is genuinely good reading. The design is printed parts and M8 threaded rod, an Arduino UNO under a ZUM shield, one stepper on a turntable, a Logitech webcam, and two line lasers that cost one hundred rupees.

The geometry does the work

The principle is triangulation. A line laser projects a vertical plane of light; the webcam watches from a known angle; wherever the line lands on the object, its sideways displacement in the image encodes depth, one slice per exposure. The turntable rotates the object through a known step angle between slices, and because the rotation is commanded, registration comes free: every slice already knows its angle, and no alignment algorithm ever runs.

The scanner mid-scan in the hostel room: red laser line striping a shampoo bottle on the turntable, the ZUM board glowing in the printed tower

The capture software is Horus, BQ’s open-source companion, which drives the board, streams the webcam, and assembles the point cloud live on screen. Watching the first cloud wrap itself around nothing in the shape of a shampoo bottle converts everyone in the room instantly.

What the kit does not tell you

Assembly is an afternoon. Getting scans worth keeping took months, and that work is the actual project.

The webcam fights you first. A stock Logitech runs autoexposure and autofocus, and both are poison for laser detection: the exposure breathes with the room, the laser line blooms and thins between frames, and the segmentation threshold that worked at noon fails at six. Locking exposure, focus, and white balance manually was the single biggest jump in scan quality we found, and no assembly guide mentions it.

The lights go off second. Horus segments the laser by thresholding what the camera sees, and the strongest move is to remove the competition: in a dark room the laser is the only red thing in the frame, background subtraction becomes trivial, and the poster’s strangest claim, scanning in the dark, is really a description of the scanner at its best.

Surfaces cheat third. A red line laser dies on shiny, dark, and translucent objects: specular surfaces throw the line somewhere else, dark ones absorb it, and translucent ones glow with it from inside. The community fix is a light dusting of talcum powder, so a talc tin lived next to the scanner, and everything difficult got scanned in matte white.

The mechanics show up in the data. A cheap turntable bearing has wobble, and wobble does its damage as a ripple around every scan at exactly the rotation frequency, which is how we learned to read point clouds the way we had learned to read failed prints. And the step angle is a real trade: finer steps mean denser slices and longer scans, which is where the poster’s two-to-three-minute range comes from.

We also ran the comparison experiments the kit never asks for. One laser or two is a genuine question, because the second laser halves occlusion shadows and doubles the calibration burden, and a slightly misaligned second plane ghosts every surface twice. The archive keeps a dibba_singlelaser.ply from the night we settled it. We tried photogrammetry on the side, and the laser won on repeatability at this budget.

The checkerboard calibration target standing on the turntable, the webcam and both laser mounts facing it

Underneath all of it sits calibration. That checkerboard is not decoration: it calibrates the camera intrinsics, then the laser planes, then the turntable axis, and the printed structure is really just a jig for holding those three calibrations steady. Bump a laser mount and the hardware is fine while every scan is garbage. The scanner is the calibration; the plastic is packaging.

Inside the software

Horus is a Python desktop application built on OpenCV, and it runs the machine over a serial line: G-code-style commands switch each laser and step the turntable one fixed angular increment per slice. For every slice the capture loop grabs a frame with the laser on and one with it off, subtracts the pair to erase the room, thresholds what survives in the red channel, and collapses the stripe to a per-row weighted centroid, which places the line’s center between pixels, at a fraction of a pixel’s width.

Horus mid-scan on the laptop: the camera pane with the laser line on the left, the point cloud growing on the right

Every centroid then becomes geometry. The intrinsics from the checkerboard turn a pixel into a ray, the ray meets the calibrated laser plane at exactly one point, that intersection is a 3D coordinate in the camera’s frame, and a rotation by the turntable’s commanded angle files it into the model. The whole scanner is three coordinate transforms run eight hundred times per revolution.

Our additions live around the edges of that loop. A camera script forces exposure, focus, and white balance to fixed values before every session, because segmentation constants are worthless while the webcam keeps renegotiating the image. Threshold presets per material class, matte, dark, and shiny-after-talc, saved retuning from scratch every night. And the cleanup moved into meshlabserver, MeshLab’s headless mode, so outlier removal, normal estimation, and Poisson reconstruction ran with identical parameters on every cloud, and two scans of the same object stayed comparable.

From cloud to print

Horus exports .ply point clouds, and clouds are not printable. The pipeline runs through MeshLab: statistical outlier removal for the stray points the threshold let through, normal estimation, Poisson surface reconstruction to close the surface, then export to STL for the printer. The file names in the scans folder tell the project’s whole emotional history, from test_toi and first_deo, a deodorant can, to the night one file got saved as insane.ply, which is what you name a scan when it finally works.

The jar under the laser line beside its finished point cloud rendered from insane.ply

That file is the jar. 891,105 colored points, the lid still red, and a faint double shell where the second laser disagreed with the first by a hair, which is a calibration lecture frozen into the data.

The bill for the whole machine came to about ₹14,000, and the ledger has a joke in it: the two lasers cost a hundred rupees, and the printed structure cost more than all the electronics combined. The parts came off the same class of machine the scanner now feeds, so the loop is closed in both directions: the printer made the scanner, and the scanner makes files for the printer. A copy of a thing on my desk, edited on the way through, is a strange kind of superpower, and it cost less than a textbook.

What the scanner taught

  1. Lock the sensor before trusting the math. Every segmentation constant assumes yesterday’s exposure, and an autoexposure webcam renegotiates that assumption every frame; the calibration is only as stable as the camera settings under it.
  2. Read the failure’s shape. A double wall in the cloud is a misaligned second laser, ripple at exactly once per revolution is the bearing, and fuzz everywhere is the threshold. The geometry of a defect names its culprit.
  3. Fixed parameters turn a toy into an instrument. The same meshlabserver script on every cloud means two scans of one object differ only by the scanner, and comparability is the entire point of measuring.
  4. Resolution is a chain and the coarsest link wins. Our 0.5 mm came from the pixel footprint at standoff distance; polishing the subpixel centroid past that was decoration.
  5. A festival crowd is a free abuse test. Two days of strangers spinning the turntable by hand found weaknesses that two months of careful sessions never touched.
  6. The STL files are open source, and the folklore is the part a repository cannot hold: which talc on which surface, which threshold for which evening light. Write that down too.