Skip to content
Godson.Build · v0.1

Case study · build v0.1

RCPT

A receipt is a photograph of a table that somebody printed badly, folded, and then kept in a wallet for three weeks. RCPT turns that into rows on the phone with the radio off — not because offline is fashionable, but because a receipt is the one document you are holding at the exact moment you have no signal.

Platform
Android
Stack
Kotlin · PaddleOCR · TFLite · SQLite
Network
Not required
Output
Merchant, total, tax, date, lines
Status
Under build
Source
rcpt-public on GitHub

01

The constraint

Offline-first is a budget, not a feature. Every model, every lookup table, every megabyte has to fit on the device and finish inside the time a person will hold a phone over a counter. There is no server to hide behind and no second pass to fix an answer later.

So the pipeline is fixed at capture: camera, preprocessing, OCR, parsing, storage. Each stage can only use what the previous one produced, which sounds limiting and is the reason a bad result can be traced to one stage instead of five.

02

The pipeline

Capture
Camera into a single image buffer. Everything downstream is deterministic, which is what makes a failure reproducible.
Preprocess
Deskew, crop and a contrast pass before anything reads the image. Accuracy on a crumpled thermal receipt is decided here more than in the model.
Read
PaddleOCR on-device through TensorFlow Lite. Detection order is preserved, because a receipt is a document with a reading order, not a bag of words.
Parse
Rule-based extraction for merchant, total, tax, date and line items. Rules, not a model, at this size.
Store
SQLite. One local database, no sync, no account, and no upload button to remember not to press.

03

Why the parsing is rules

Parsing looks like the small half and is not. A model for field extraction needs labelled receipts per merchant, and the long tail of merchants is exactly the part you cannot label in advance. A rule set needs an afternoon per chain and fails legibly: when it gets a total wrong you can read the rule and see why.

The trade-off is honest. Rules do not generalise to a merchant nobody has written a rule for. At one merchant at a time that is a smaller problem than a model that is quietly wrong about a little of everything, and cannot tell you which little.

04

Where it breaks

Thermal paper fades
Within months it is grey. There is a contrast floor below which no amount of preprocessing recovers a glyph.
The total moves
TOTAL, TOTAL:, Amount Due, Grand Total — and on some prints, a number at the bottom with no label at all.
Tax is not one thing
Sometimes a rate, sometimes an amount, and discounts land before tax on some prints and after it on others.
Glyph collisions
Zero and capital O come out of the same font slot on some printers. That is an OCR problem that becomes a parsing problem.

05

Next

A labelled corpus first, then a small model for the fields the rules lose on. Not the other way round. A corpus is worth something on its own; a model without one is a guess with a build step.

OCR is the easy half. It reads every character correctly and still has no idea what the number at the bottom of the page means.