Back Original

My phone replaced a brass plug

For months, I spent my Wednesday evenings in a tin tunnel just outside Edinburgh, wearing a ridiculously looking (and equally uncomfortable) jacket. I'd lie on the floor and count breaths, then walk down the range, ducking under ceiling beams. The floor says DUCK in white paint every five metres, the beams have posters saying "DUCK" as well, but occasionally I still hit my head, too busy checking the scoring cards.

If you're unlucky, a shot lands near a ring line and you need help. You walk up to a tray of Greggs sausage rolls1. Best gourmet pastries this side of the pond (and they also do doughnuts!). - we're in the North, and so are our sponsors - find a wooden box which holds brass plugs in every size, choose the right one, carefully push it into the hole (ideally only once, to avoid tearing), and where it sits is your score.

An example of using a scoring gauge; via A Primer on Scoring Gauges by Gary Anderson, DCM
The bullet pushes paper inwards, so even if ring lines are untouched, as long as the flange extends beyond the outer ring you get a lower score.

The shooting part is fun. The score-counting-head-hitting-plug-pushing ritual had to end.


The reason I was there was cooking.

I got into it decades ago and gradually became more obsessed: from shy attempts at recreating dishes from every fine-dining restaurant I'd visited to building automated curing chambers. Not buying koji but growing the mold, hydrating ramen dough in a chamber vacuum, heating protease and grasshoppers in an immersion circulator to make garum.

Then I got into charcuterie, which meant getting whole animal carcasses and butchering them myself. As I decided to get serious about cooking meat I figured I should learn to hunt. I'd never really held a gun, and while in the UK we love licences and don't like guns (we prefer knives), deer hunting requires neither a hunting nor a rifle licence2. The Firearms Act lets a landowner hand you one of theirs if they "supervise" you using it, which is how folks have hunted on their estates for centuries (on that note, it's deer stalking - hunting is for rich twats on horses, shooting is for rich twats in tweeds).. Red deer are essentially pests - they eat woodland faster than it regrows and have no natural predators, so culling them comes with almost no restrictions.

You do need the rifle though, and preferably know how to use it3. I shot myself in the foot too many times writing code, imagine what I could do with a firearm. - so there I was, on a mat twice a week. Not quite the same discipline as stalking a deer: shoot, change cards, have a doughnut, repeat. Half a year later I had gained a few pounds on my way to a venison steak I was yet to shoot, and spent most evenings searching for the right-sized scoring gauge.

Bored as I was, I figured I might as well automate it.

Negative space

I am an iOS engineer, so I started with vanilla iOS: Apple's Vision framework is around for a while, and has ready-to-use detectors for objects, person segmentation, text recognition, and even barcode scanning, but it kept tagging random parts of the image as bullet holes - from the dot in the target's centre to pieces of one of the scoring rings.

A bullet hole is a negative space. Object detectors are trained on the thing that should be there, so it's not very straightforward how to use them for finding something that was there before and then got removed.

A close-up of a single NSRA bull card with pink computer-vision overlays drawn across every detected feature: the concentric scoring rings, the central aiming cross, the small printed scoring numerals, and the annotation squares at the cardinal points. Actual bullet holes on the card are small and mostly unmarked.
Vision's ring and object detectors applied to an NSRA card.

I tried a few more obvious things: grayscale, inverting the image, adding and removing noise, but even when everything else worked, shots landing on ring lines were turning into fragments too small to register.

A better approach would be to treat the target as an object with known geometry: find the ring structure first, then look for holes inside it. I accepted I won't be reinventing the wheel this time, and looked up alternatives.

Port and whatnot

A 2012 paper

Scored shooting targets are boring enough as a computer-vision problem that somebody has published on it. I found Automatic Scoring of Shooting Targets with Tournament Precision, by Rudzinski and Luckner at Warsaw University of Technology, published in 2012 and promising 99% of holes detected.

There were a few caveats: the approach was optimised for low-resolution pictures but required flat ISSF targets 4. Comparing to NSRA, ISSF targets have different size of bulls and amount of rings, different rings, and different background, low camera angle, annotations not similar to holes, and was generally designed for pellet shooting. Air-rifle pellets make a cookie-cutter hole in paper, while a .22 bullet at twenty-five yards leaves ragged edges.

I reproduced the paper step-by-step. If you don't fancy reading the publication, it boils down to four steps: erase the ring lines, flood-fill to find the hole shapes, run a Prewitt edge detector, and fit circles with a Hough transform.

Grayscale of the bull: a white scoring ring line runs straight across two bullet holes.
Starting with a grayscale target
Ring lines removed: each bullet hole is now two crescent fragments on either side of where the ring used to be.
1. Erase ring lines: these holes split into two crescents.
Flood-fill result: four small dark fragments on white, each below the minimum-region threshold.
2. Flood-fill
Prewitt edges of the fragments: only their outlines, no complete circles for Hough to fit.
3. Detect edges and 4. Use Hough transform to fit circles.