01Live02Batch03About
/ About · three rewrites

Same problem.
Three versions.
Each one
taught me
the next.

This project started in 2022 as a weekend detour — a friend wanted to solve shot detection in hardware, and I wanted to find out if software could do it instead. It has been rewritten twice since. Each rewrite was wrong about something important, which is the only reason the current one gets to exist.

OriginA hardware idea, flipped into a software one.
TodayClaude Vision + OpenCV, shipped as a real pipeline.
v12022
Python · OpenCV

The proof-of-concept.

How do humans score a target? Eyes, then brain. Can we teach the program to do the same?

A friend working on target-detection hardware wanted to measure shot location with an impact sensor — a load-cell array that triangulates force. I didn't really follow the hardware side, so instead of arguing I flipped the question: how do we humans do this? We look at the paper, find the hole, and read off the ring. That's it. Two steps, both doable in software.

So I tried to break those two steps down and hand them to a program. A weekend of OpenCV later, it more or less worked — not gracefully, but enough to prove a phone camera could stand in for the load cells.

why v2 had to exist →
v22024–25
C++ · OpenCV

The port to production.

Performance first. Portability second. Reality third.

The obvious next step was iOS — if this was ever going to live on a phone at the range, C++ was the sane foundation. I ported everything: feature detection, homography, ring geometry. Along the way I tried shape-based approaches, ORB descriptors, a handful of matcher variants.

Performance improved meaningfully. Robustness did not. The core problem was stubborn: the algorithm worked beautifully on the test images it was tuned against, and broke on anything else. Every new lighting condition, every new paper texture, every new phone meant another round of threshold tuning.

As a one-person project, I was running out of dials to turn. I could feel the ceiling and I wasn't going to break through it by tuning harder.

why v3 had to exist →
v32025 → now
Python · Claude · OpenCV · FastAPI

The hybrid.

Let the LLM do judgment. Let pixel math do precision.

My first instinct with AI tools in my workflow was to ask: can Claude just score the shot, end-to-end, no OpenCV? Refine the prompt enough and maybe it's done.

It wasn't. Early prompts confirmed the failure mode — big vision models aren't brittle like my C++, but they also can't give you a centroid. Claude would eyeball the shot and bias toward the bullseye. Around 80% accurate. Not bad. Not acceptable.

Workshopping it with Claude Code and Gemini, the split clarified: LLMs answer the semantic question ("which hole is new?"), OpenCV answers the geometric one ("exactly where?"). I already had the OpenCV muscle memory from the C++ years. Wiring it up was the easy part.

Best of all — when alignment or signal fails, the system falls back to LLM-only scoring. An AI eyeballing the shot is still better than the program breaking.

Field notes · the test rig

Also: I built a backyard range
to generate training data.

A portfolio page is only as honest as its inputs. Every shot you see on this site came from here — a wooden bench, a phone on a tripod, paper targets in a plywood box. Nothing staged.

Backyard test rig — wooden bench, phone on tripod, target box against black backstopwide · full setup
backstop · bench · phone tripod · target box · 10m to the shooter
Close-up of the target box showing phone framing and paper targetclose · phone pov
phone pre-framed · target pinned · same coordinates frame-to-frame
every image in this portfolio originated here
/ about the engineer

Day job: Java.
Weekends: whatever looks interesting.

I’m a Java engineer by day — prod-ready services, deployments, testing, the whole lifecycle. Lately a lot of my focus is on the automation side: using LLMs to generate closed-source client code from OpenAPI specs, and generally turning the boring, repetitive parts of the job into something a program can do instead. That’s the sweet spot for me.

Off the clock I like things that don’t obviously pay back: reading, learning languages (the spoken kind too), and building a target-scoring algorithm in my back yard across three rewrites. None of it is strictly useful. All of it teaches me something, and every so often one turns into the main project, which is how this site exists.