Building My Own Tool Scanner — Part 11: Z Has Entered the Chat

By this point I'd eliminated quite a few suspects.

The camera was fixed.

The original C920 lens was back.

The scanning surface was now glass.

The calibration had been rebuilt around a genuinely flat reference plane.

And measurements made directly on that plane were extremely good.

Which meant I could finally investigate the problem I'd been circling for a while:

Tools aren't flat.

My calibration exists at Z = 0.

Unfortunately, the things I actually want to scan exist in three dimensions.

And once the edge being detected rises above the calibrated plane, perspective starts changing what the camera sees.

The problem with Z

Imagine placing a rectangular block on the scanner.

Its footprint sits on the glass at Z = 0.

But the camera doesn't necessarily see that footprint.

It sees the uppermost visible edge of the object.

If that edge is 10, 20 or 30 mm above the glass, it's physically closer to the camera.

And because of perspective, it appears larger.

For a photograph, you'd never care.

For a scanner where fractions of a millimetre matter?

You care quite a lot.

This also explained something I'd seen throughout the physical testing.

The flat calibration could be excellent while measurements of real tools were consistently oversized.

The calibration wasn't necessarily wrong.

I was measuring geometry that wasn't sitting on the calibrated plane.

Proving it deliberately

Rather than immediately trying to correct the problem, I wanted to characterise it.

So I started testing objects at known heights above the glass.

The plan was fairly straightforward:

Measure something at the calibrated plane.

Raise it by a known amount.

Measure it again.

Move it around the workspace.

Rotate it.

Repeat.

If the apparent dimensional change followed a predictable relationship with height, I could potentially reverse it.

And it did.

As the object moved towards the camera, its measured dimensions increased.

The effect became progressively larger as Z increased.

So now I had something much better than:

“The scanner sometimes measures tall things too big.”

I had a measurable relationship between object height and apparent size.

A ratchet makes a considerably better test

Calibration blocks are useful.

But ultimately I'm not building a calibration-block scanner.

I'm building a tool scanner.

So one of the more useful real-world tests became a ratchet.

Its actual measured dimensions were:

144.89 × 24.84 mm

with a height range of approximately:

0–12.2 mm.

And without any height correction, the scanner measured it at:

148.00 × 25.60 mm

That's an error of:

+3.11 mm in length

and:

+0.76 mm in width.

A repeated scan came back even larger:

148.50 × 25.80 mm

or:

+3.61 mm in length

and:

+0.96 mm in width.

That's far beyond the error I'd seen during flat-plane calibration.

But now I knew why.

The scanner was accurately mapping what the camera could see.

The problem was that what the camera could see wasn't at Z = 0.

Correcting for effective height

The ratchet isn't uniformly 12.2 mm tall.

Different sections sit at different heights.

And the silhouette visible to the camera isn't necessarily generated by the maximum height of the object either.

So simply saying:

“The ratchet is 12.2 mm tall”

and correcting the entire outline using that value wouldn't necessarily be right.

For the initial correction, I used an effective Z of 6.1 mm.

Half the measured height range.

That immediately changed the result from:

148.00 × 25.60 mm

to:

145.60 × 25.20 mm.

Length error had fallen from:

+3.11 mm

to:

+0.71 mm.

A massive improvement from one additional piece of information:

How far above the calibration plane is the geometry I'm actually looking at?

But there was still more going on.

Position still matters

Perspective isn't purely a function of height.

Where the object sits relative to the camera matters too.

A point directly underneath the optical centre behaves differently from one towards the edge of the workspace.

So I started moving the ratchet around.

Same tool.

Same effective Z.

Different positions.

One of the spatial tests in the bottom-left of the scanner produced:

144.90 × 25.00 mm.

Remember, the actual ratchet was:

144.89 × 24.84 mm.

That's:

+0.01 mm in length

and:

+0.16 mm in width.

At that point I had to measure it again because frankly +0.01 mm looked suspiciously good. 😂

I wasn't expecting the scanner to magically become a laboratory metrology system.

And one extremely good result doesn't mean every scan is accurate to one hundredth of a millimetre.

But it demonstrated something important.

The several-millimetre error I'd started with wasn't random.

It could be corrected.

From more than 3 mm to hundredths

That's probably the most satisfying comparison from the entire project.

Same physical ratchet.

Actual length:

144.89 mm

Uncorrected scan:

148.00 mm

Error:

+3.11 mm

After height and spatial correction:

144.90 mm

Error:

+0.01 mm

Again, I'm absolutely not claiming the scanner has ±0.01 mm accuracy.

It doesn't.

That particular result is simply one very good measurement.

The important result is the scale of the improvement.

The systematic error caused by measuring geometry above the calibration plane had gone from being measured in millimetres to something comfortably inside the tolerance required for the job.

And that's all I actually needed.

Know when to stop

This is also where I decided not to chase the numbers any further.

Could I build a more sophisticated 3D correction model?

Yes.

Could I characterise every part of the workspace at multiple heights?

Probably.

Could I try to infer different Z values across a tool automatically?

Possibly.

Could I spend another three months doing it?

Absolutely.

😂

But I'd reached the point where the engineering question wasn't:

“Can I make this more accurate?”

Of course I can.

The question was:

“Would making it more accurate actually improve the thing I'm trying to manufacture?”

For Gridfinity tool inserts, the answer was increasingly:

Not really.

The remaining errors were already comfortably inside the clearance required for a 3D-printed pocket.

I'd crossed the line from solving a useful problem into chasing numbers because I could.

And after several months of doing exactly that...

It was probably time to stop.

What the scanner became

What started as:

“I really can't be bothered measuring all these tools.”

had somehow become a system involving:

Camera calibration.

Thousands of reference points.

Polynomial mapping.

Hold-out validation.

Checkerboard testing.

Lighting experiments.

Image segmentation.

Vectorisation.

Lens experiments.

Multiple cameras.

A glass reference plane.

Height correction.

Spatial correction.

A custom Gridfinity Generator.

And rather a lot of Python.

All so I could put a ratchet in a drawer.

Completely reasonable. 😂

But the important bit is:

It works.

I can place a tool on the scanner, extract its physical profile, take that geometry into the Gridfinity Generator, specify the information the camera can't know, and produce a printable insert.

That's the system I originally wanted.

It just took a considerably more interesting route to get there.


Next: Part 12 — What I Learned Building the Titan Scanner

There isn't another calibration model in Part 12.

No new camera.

No replacement lens.

And, hopefully, no discovery that the glass isn't actually made of glass. 😂

After roughly three to four months of building, testing, breaking, rebuilding and repeatedly disappearing down engineering rabbit holes, the final part isn't really about the scanner.

It's about what I learned from building it.

Some of those lessons are technical.

Some are about software.

Some are about knowing when hardware is the actual problem.

And quite a few are about recognising when something is already good enough to do the job it was designed to do.

So I'm going to finish this series slightly differently.

Part 12 is the retrospective.

What worked.

What didn't.

What I'd do differently.

What surprised me.

And what started as an excuse to avoid manually measuring my toolbox ended up teaching me along the way.