Computer vision2024

Rare Coin Scanner

Computer vision + a numismatic rules engine. One jar of change, one 30-second scan, one short list of coins actually worth pulling.

Why this exists

My grandfather left a coffee can full of change. Every serious coin collector I know has a jar like it, or five. Every not-serious coin collector has the can from their grandfather. The friction between “this jar might have something interesting in it” and “I have actually looked” is enormous, because the gap between a coin and a notable coinis measured in dates, mint marks, and errors that are nearly invisible at arm's length.

The traditional workflow is: dump jar, put on a magnifier, thumb through 400 coins, pull the silver, check each Lincoln cent for the 1955 double die, flip every wheat-back penny and check the mint mark, occasionally catch something. Most people do this for an hour, find nothing, and put the jar back on the shelf.

I wanted the 30-second version. Point a camera at the jar. Get back a short list of “these are the coins worth pulling out.”

What the scanner actually does

The pipeline is three stages. The hardware is a cheap overhead USB camera and a flat tray with a matte black background. The software runs locally on my laptop — everything happens on-device, nothing goes to a cloud.

Overhead shotUSB camera + traySegmentationfine-tuned SAM→ N coin cropsClassifier Adenom · country · yearResNet-50 fine-tuneClassifier Bmint mark + rotationsmall CNN on ROIRules enginenumismatic rules→ flagged list

Three-stage pipeline. Segmentation isolates coins, two classifiers run in parallel per coin, a rules engine decides what's worth flagging.

Stage 1: segmentation.A coin jar dumped onto a tray is a surprisingly hard computer-vision problem — coins overlap, stack, cast shadows onto each other, and come in five denominations with wildly different sizes. I use a fine-tuned Segment Anything (SAM) checkpoint trained on a small custom dataset of overhead coin shots. It outputs a tight mask per coin and kicks them out as separate crops. Roughly 95% recall on visible coins in reasonable light; the failures are almost always “coin touching another coin on a dark side.”

Stage 2: dual classifiers. Each cropped coin runs through two models in parallel. One is a denomination / country / year classifier I trained on ~40,000 images scraped and labeled from open numismatic databases. The other is an orientation + mint-mark detector that crops the tiny region where the mint mark lives and reads it with a second, much smaller model. Running them separately keeps each one accurate on its narrow job — a single model trying to do both got tangled up on coins where the year was clear but the mint mark was worn.

Stage 3: the numismatic rules engine.This is the part that matters and the part every generic “coin identifier” app gets wrong. Having a label is not the same as knowing what's valuable. The rules engine is hand-written: a few hundred lines of Python that encodes real numismatic knowledge.

The rules that actually find value

Most old coins are worth face value. The scanner isn't trying to value every coin — it's trying to pull the ~2% of any given jar that's actually worth a second look. The rules come from a few specific pockets of numismatic knowledge:

SignalRuleWhy flag
Silver contentPre-1965 US dimes, quarters, halves~90% silver by weight, worth $2–$20+
Key dates1909-S VDB, 1914-D, 1943 copper, 1922 plainRare mint/year combos worth hundreds
Error coinsDouble dies, off-center strikes, wrong planchetCollector premium, $20–$1000+
Wheat centsAny cent dated 1909–1958Not all valuable, but worth a manual check
Foreign silverPre-1968 CAD, older UK / AU silver coinsFrequently mixed into US jars
ConditionHigh-grade finds in circulated jarsWorth grading for resale

The rules table is not exhaustive. It is, deliberately, the set of flags where a false positive costs me 30 seconds of looking more closely, and a false negative means I throw away $60. That's an asymmetric tradeoff, so the rules are tuned toward high recall at the expense of precision. Flag generously, let a human confirm.

The counter-intuitive detail

The hardest part of this build was not the computer vision. It was the coin-by-coin re-identification problem: I don't want to scan the same coin twice and count it twice when I'm working through a jar in batches. But coins don't have IDs. They're fungible by design. How do you tell one 1987 D quarter from another, identical, 1987 D quarter on the next pass?

The answer, which embarrassingly took me a weekend to figure out: wear patterns. No two circulated coins are physically identical at high-enough resolution. A perceptual hash (pHash) computed on each coin crop is stable enough to re-identify the same coin across sessions, with >99% accuracy in my test set. The scanner stores a pHash per scanned coin in a tiny SQLite database, and if a new pHash matches an old one within a hamming-distance threshold, it's the same coin.

This turns the scanner from a one-shot tool into a continuous-inventory tool. I can run a jar in batches, dump another bag into it, scan again, and only get the new coins as output. The insight — wear is identity — generalizes to a lot of physical-object tracking problems, and I have not seen it written up elsewhere.

What I’d do differently

I over-invested in the classifier training data early on and under-invested in the segmentation stage. The classifier is almost always right when given a good crop; the segmentation is what actually bounds the quality of the end-to-end system. If I were starting over I'd spend 80% of the time on getting clean crops and 20% on the classifier, not the other way around.

The generalizable lesson: for any ML pipeline, measure which stage has the highest error rate and spend your time there. Do not spend your time on the stage you find most fun to work on. (Everybody wants to do the classifier. Almost nobody wants to do the segmentation.)

The jar results so far

After running it on roughly a dozen jars of family-member change, the pull rate is about what I expected: the scanner flags 2-4% of any given jar as “worth a closer look,” and of those, maybe a third turn out to be actually valuable once I eyeball them. Found so far: a 1955 wheat penny with a decent obverse double, a small stack of pre-1965 silver dimes hiding in a coffee can, a Canadian nickel from 1944 that had slipped in, and a 1921 silver dollar I would've missed completely because the date was partially worn.

None of those finds paid for the build in dollars. They paid for it the way all of these projects pay for themselves — they turn a thing I was avoiding into a thing I actually do, and that is the whole point.