Residue

Testing, explained from the start

How Residue was tested, and what the numbers mean

One concept at a time, with a checkpoint after each. If you can say the checkpoint sentences in a room, you understand the test well enough to defend it.

Read first

This page covers the Residue Station benchmark. The Residue Photo product has its own benchmark on real Library of Congress card scans, 1,222 real impostor pairs with zero false accepts, shown on the vault demo. Every number on this page comes from a physical model of a surface: published roughness statistics, three-light capture, real sensor noise, wear as removed depth. The model is stated in full so it can be attacked, and every method ran on identical data.

01The objects

Forty identical parts, built in software to the physics of the real ones. Each object is a patch of surface, 512 pixels square at 10 microns per pixel, about 5 mm across, made of bumps at six sizes from 40 microns to 480 microns. The bump heights follow the same statistics real machined and moulded surfaces show.

Two things make the simulated objects realistic:

The model is in pebbleid/surface.py in the private project and is restated in the browser inside every demo.

CheckpointForty simulated surfaces, half of each one shared with all the others, worn by removing depth rather than by blurring.

02The test

Every object is photographed once under clean conditions. That photo is its record, the same thing a plant would capture at enrolment. Then every object is photographed three more times, each with its own fresh wear, dust film, camera noise and a random light direction. Those are the reads.

Each read is shown to a matcher together with all forty records and the matcher is asked: which one is this? There are 40 objects and 3 reads each, so 120 answers per method per condition. Each read is also scored against the 39 records it does not belong to, which gives 4,680 "wrong pair" comparisons per method per condition. Those wrong pairs are what tell you how often a method would confuse two different objects.

One read is one 5 mm tile. A real camera view of a part covers about 78 such tiles, so the single-tile result is the hard version of the test.

Checkpoint40 objects, 3 reads each: 120 chances to name the wrong object, and 4,680 pairs that must not look alike.

03The 13 conditions

One condition would prove nothing, because we chose the difficulty. So the test is a grid. A centre point is held fixed and one thing is changed at a time, then one cell turns everything bad at once.

AxisCentreValues sweptWhat it stands for
Material removed10 µm0, 1, 3, 10, 30Wear between record and read. One reactor pass is about 1 µm; a bead blast is tens
Kappa0.50.1, 0.5How shallow the surface features are. 0.1 is the pessimistic end of the published evidence
Shared fraction0.50.3, 0.5, 0.9How much of the surface the whole batch has in common. 0.9 is a near-perfect mould
Dust0.20, 0.2, 0.5A film dimming the read unevenly
Sampling10 µm/px5, 10, 20Camera resolution at the surface
Corner30 µm, kappa 0.1, shared 0.9, dust 0.5Everything bad at once

Twelve one-axis cells plus the corner is 13. Every method runs in every cell on identical data.

CheckpointThirteen conditions, one knob at a time plus a worst case, so a method cannot win by luck in the one condition we happened to pick.

04The 28 methods

"28 methods" means 28 matcher variants ran the same test. They fall into five families. All but the last two families see a single photo under one oblique light at a random direction, which is what a competitor without three-light hardware has.

FamilyMembersWhy it is in the test
Keypoint matchingORB, SIFT, AKAZE, BRISKWhat published surface-fingerprint methods rely on. Finds distinctive points and counts how many agree on one shift
Texture codesLBP histogram; Gabor code at 1 scale and at 6 scalesThe iris-recognition construction and the classic texture descriptor
Plain correlationraw correlation; phase correlation then correlation; windowed band-limited phase correlationThe obvious engineer's shortcut: line the pictures up and compare them
Correlation with the batch removedraw correlation, shared pattern subtractedTests whether subtraction alone is the trick
Three-light with the batch removedPCA subspace, equal weights and fitted weights; our legacy residual; ours v1; ours v2 and its variants (fixed weights, trimmed mean, median with per-read gain, LDA weights)Everything that has our capture hardware, so the comparison isolates the matcher

The PCA rows matter most. PCA is a textbook technique anyone can implement in an afternoon. Giving it our three-light photos and our band filters asks the fair question: once a rival has the hardware, is our matcher worth anything on top?

CheckpointFive families, same photos, same conditions. The strongest rival is a textbook method given our own hardware.

05Reading a score

d′, the separation

Each method gives a number for how alike two pictures are. Look at the numbers it gives for same-object pairs and for different-object pairs. d′ is the gap between those two averages, divided by their spread. Under 1 means the two piles overlap and the method is near a coin flip. In the tens, the piles are far apart. In the hundreds, the model is saying the margin is enormous, not that anyone would measure that exact figure.

Rank-1 errors

Simpler: of 120 reads, how many times was the top-scoring record the wrong object? Where a method makes zero errors we do not report zero. With 120 trials the true rate could still be as high as 3 in 120, so 2.5% is what is shown. That is the rule of three, and it is the right way to report a clean run.

Confidence intervals

Every d′ carries a 95% interval from a bootstrap that resamples whole objects, not individual reads, because three reads of one object are not independent of each other.

A statistic dropped during the run

Dividing the gap only by the spread of the different-object scores makes keypoint methods look superb: SIFT scores 26.7 that way while naming the wrong object 87% of the time, because almost all of its different-object scores are exactly zero. That number is kept in the full tables and nothing is ranked on it.

Checkpointd′ is the gap between "same" and "different" in units of spread. Zero errors in 120 is reported as "under 2.5%", never as zero.

06Who wins where

Three findings, in the order we learned them.

  1. The keypoint tools fail. ORB, SIFT, AKAZE and BRISK name the wrong object 8 or 9 times in 10 on nominally identical parts. Rank-1 accuracy at the centre: ORB 8%, SIFT 13%. Their d′ sits at 0.4. This is the toolkit the published literature leans on.
  2. Our first matcher lost to PCA. Given the same three-light photos, the textbook PCA method beat our v1 in 10 of 13 conditions, by a small margin at the centre (d′ 41.9 against 40.9) and by a large one under heavy dust (24.2 against 19.5). In the corner cell v1 named 56 of 120 wrong; PCA named 32 wrong. A benchmark that only confirmed what we hoped would be worthless; this one sent us back to work.
  3. v2 fixed the reason. v1 gave every scale of texture the same vote. Fine texture is reliable and coarse texture is almost useless, so equal votes watered down the good signal. v2 weights the bands by their measured separation and corrects for dust dimming the picture. Result: 0 of 120 wrong in every condition, including the corner, and d′ about 10 times higher than v1 at the centre.
MethodCentre30 µm wear90% shared50% dustCorner
Ours v239116836737217.0
PCA, same weighting35817033433414.4
Ours v1, equal weights40.931.825.519.52.0
Raw correlation, shared subtracted533823131.2
SIFT keypoints0.410.380.290.25negative
ORB keypoints0.390.350.310.09negative

d′ per 5 mm tile. One real camera view composes about 78 tiles.

The size of the lead. If the PCA rival is also given our band weighting, v2 is 10% to 30% ahead, and level in 3 of 13 conditions. That is the matcher's margin on its own, and it is why the moat is the system around the matcher: the capture rig, closed-inventory tracking, scan-again-never-guess, and the error budget.

CheckpointStandard tools: wrong 8 or 9 in 10. Ours: 0 wrong in 120, every condition. A textbook rival with our hardware lands within 30%.

07Ablation, what each ingredient is worth

"Ablation" means removing one part of the design at a time and rerunning the test, so you learn which part bought which share of the result. Our pipeline is three moves on the image, plus the decision rule. Here is each move taken out, at the centre condition.

Ingredient removedd′ with itd′ without itWorth
Three-light capture (use one oblique photo at a random light direction)40.91.229 to 39 times. The big one. Without it, 47 of 120 reads name the wrong object
Shared-pattern subtraction40.927.81.4 to 1.6 times at the centre; 3.5 times when 90% of the surface is shared
Band filters, equal weights40.980.6Negative. Unweighted, the filters cost a factor of 2. This is the v1 flaw
Band filters, fitted weights (v2)39180.64.5 to 5.2 times. The filters earn their place once weighted

Ratios are paired bootstrap intervals: the same objects go through both versions.

The third row is the one to notice. An ablation that only ever says "every part helps" is suspect. This one found a part that hurt, and the fix for it became v2.

CheckpointThree lights are worth 30 times. Subtraction is worth up to 3.5 times. Band filters were worth less than nothing until they were weighted, and then 5 times.

08The worst-case physics

Kappa is the one input no literature gives us. So a second run holds everything else at the centre and sweeps kappa down to the pessimistic end while material is removed, using a full camera view (78 tiles) and realistic sensor noise: photon shot noise, read noise, 10-bit quantisation, a random sub-pixel shift on every read. The bar is d′ 9.8, which is what under one false match a year requires in the pebble-reactor case, the hardest application we have sized.

Material removedkappa 0.1kappa 0.25kappa 1.0
1 µm, about one reactor pass340353361
3 µm299335356
10 µm212282340
30 µm118196299
Requirement9.89.89.8

d′ per view, 24 objects per cell, all bands. Fine features die first: the 40 µm band alone falls from 2,556 to 153 over this sweep while the 160 µm band falls from 924 to 275.

Two corrections were made during this run and are recorded, because a test that never found a bug in itself is not being read carefully. A band-pass filter nominally tuned to 40 µm was mostly reporting 600 µm content, which made fine scales look far more wear-resistant than they are. And any shared pattern the subtraction failed to remove was being credited to the genuine score; separation is now measured from the impostor mean, not from zero.

What d′ in the hundreds means. The margin, not a headline accuracy. In a running system the binding event is a retaken capture, not a false match, which is why every demo shows its retake rate.

CheckpointAt the flattest features the evidence allows and five times the working wear, the margin is still 12 times the requirement. Nothing in the physics gets near the line.

09Stress tests, the ways a read can go wrong

The grid varies the surface. A third run varies the capture, applied to the read only while enrolment stays clean, since that is what a plant sees.

Two mechanisms came out of it. A quality detector on the capture side, blind to the truth, flags saturated, dark and abnormally textured pixels, and the read is taken again when too much of the window is flagged. On clean reads it flags 0.00% of the window, so it does not send good captures back. And a registration step that uses the shared batch pattern as a landmark recovers rotation to about 0.01 degrees, scale to 0.1% and shift to 0.05 px, including the 216 px case, in about half a second per read.

The one inherited shortcut is stated in the log: the benchmark estimates the shared pattern while excluding the read's true object, which a plant cannot know. The effect shrinks as the batch grows and is listed as an open item rather than hidden.

CheckpointBad captures are caught before matching and retaken. Rotated, rescaled and barely overlapping reads are registered back. The one oracle element left in the test is named.

10Reported to the industry standard

For any system that answers "is this the same one?", the standard is ISO/IEC 19795, biometric performance testing and reporting. It asks for the false-match rate and the false-non-match rate at a stated threshold, on data you did not tune on, with confidence intervals, and ideally run by someone who is not the vendor. The gold example is NIST's face-recognition vendor test: vendors submit, NIST runs it, everyone sees the same curve. In surface fingerprinting nobody publishes to that standard; the incumbent's public figure is a marketing line ("99.9%, zero false positives") with no test behind it that a reader can check.

The standard asks forWhat we reportStatus
False-match and false-non-match rates at a stated thresholdd′, rank-1 error, and in every demo a threshold derived from the application's comparison count with the retake rate shownModel rates, every demo
Confidence intervals95% bootstrap over objects; rule of three for clean runsNone
Test data independent of tuningDesign choices made on one random seed, final numbers reported on anotherSeparate seeds, thirteen conditions
Held-out, representative dataThirteen conditions spanning the published range of the unknownsCovers the published range
Independent executionReproducible from the project: one command regenerates the gridOpen to an outside run
Failure-to-acquire reported separatelyThe quality gate sends the read back for another view and the retake rate is shown in each demoShown in every demo

Every rate on this site is reported in the standard's vocabulary and its arithmetic: benchmarked on a physical model, reported in ISO/IEC 19795 terms, reproducible by anyone who runs the command.

CheckpointISO/IEC 19795 wants rates, intervals and held-out data. All three are reported, and the benchmark is one command to rerun.