Invoice Reader (OpenVINO): Bills and Invoices to structured data

Point it at a photo, scan or PDF of a bill and get back the seller, buyer, GSTINs, invoice number, date, line items, taxable value, CGST/SGST/IGST/VAT, round off and total, checked with GST arithmetic. It runs fully offline on an ordinary Intel PC (CPU or Intel integrated/Arc GPU) using Intel OpenVINO. No cloud and no API key, and your bills never leave the computer.

> python invoice_reader.py bill.jpg

=== bill.jpg  (... s on CPU, confidence: HIGH)
Seller : MALABAR TRADING COMPANY   GSTIN 32AABCM1234K1ZV  Kerala
Buyer  : Thomas Supermarket   GSTIN 32AAFCT5678P1ZM  Kerala
Invoice: MTC/2026/0457    Date: 2026-10-14
Items:
   Basmati Rice 5kg                         10 x 620.00 = 6,200.00
   Sunflower Oil 1L                         24 x 145.50 = 3,492.00
   Tea Dust 500g                            12 x 210.00 = 2,520.00
Taxable 12,212.00 | CGST 1,099.08 | SGST 1,099.08 | IGST - | Round off -0.16 | TOTAL 14,410.00
   [OK] seller GSTIN checksum: 32AABCM1234K1ZV
   [OK] items add up to taxable value: 12212.00 vs 12212.00
   [OK] taxable + tax = total: 14410.00 vs 14410.00
   [OK] CGST equals SGST: 1099.08 / 1099.08
   [OK] tax type matches states: same state: CGST+SGST expected

Quick start (Windows)

  1. Install Python 3.9+ from python.org.
  2. Double-click setup.bat. It creates a private Python environment (.venv, so your other projects' packages are not changed), installs OpenVINO and OpenCV, downloads the two OCR models once (about 15 MB), converts them to OpenVINO IR and runs a self-test on the sample bills.
  3. Then use it in either of two ways:
    • Drag and drop: double-click run_app.bat. A page opens in your browser; drop bills on it.
    • Folder of bills: drag a bill or a folder onto read_bills.bat.
    • Command line (inside the environment: .venv\Scripts\activate first):
      python invoice_reader.py bill.jpg                  # one bill -> bill.json
      python invoice_reader.py D:\Bills                  # a folder -> invoices.csv + items.csv (opens in Excel)
      python invoice_reader.py bill.pdf --device GPU     # Intel graphics; AUTO also works
      python invoice_reader.py bill.jpg --text           # also show the raw OCR lines
      

From Python:

from invoice_reader import read_invoice
r = read_invoice("bill.jpg")
print(r["seller"]["gstin"], r["total"], r["confidence"])

How it works

image / PDF โ”€โ”€โ–บ OpenVINO text detection (DBNet) โ”€โ”€โ–บ OpenVINO text recognition (CRNN + CTC) โ”€โ”€โ–บ lines โ”€โ”€โ–บ GST field extractor โ”€โ”€โ–บ checks โ”€โ”€โ–บ JSON / CSV

1. OCR on OpenVINO (ocr_openvino.py)

  • Uses the PaddleOCR PP-OCRv4 detection and recognition networks, converted to OpenVINO IR (FP16).
  • Detection: the page is resized to a multiple of 32, and the probability map is turned into rotated text boxes.
  • Each box is straightened with a perspective transform, then read by the recognition network with greedy CTC decoding.
  • Crops of similar width are batched together, which keeps it fast on a CPU.

2. Field extraction (invoice_parser.py, pure Python)

  • Groups OCR boxes into lines by position.
  • Finds labels such as Taxable Value, CGST @ 9%, Grand Total, Bill To and Invoice No.
  • Reads the item table (description, qty, rate, amount) using qty ร— rate = amount to pick the right numbers.
  • Understands Indian number formats (1,23,456.00, โ‚น, Rs.) and many date formats (14/10/2026, 05-Oct-2026).

3. GSTIN repair and validation

  • A GSTIN has a fixed pattern (2 digits, 5 letters, 4 digits, โ€ฆ) and a mod-36 check character.
  • OCR mix-ups such as Oโ†”0, Iโ†”1, Sโ†”5 and Bโ†”8 are corrected position by position, and the result is accepted only if the checksum is valid.
  • The state is decoded from the first two digits.

4. Cross-checks

  • Items add up to the taxable value.
  • Taxable value + tax + round off = total.
  • CGST = SGST.
  • The tax type matches the states: IGST for inter-state supply, CGST+SGST within a state.

The result has a confidence of high, medium or low, so you know which bills to check by hand.

Output fields

seller{name,gstin,state}, buyer{name,gstin,state}, invoice_no, date (ISO), items[{description,qty,rate,amount}], taxable_value, cgst, sgst, igst, cess, discount, round_off, total, checks[{name,ok,detail}], confidence, lines (raw OCR text), seconds, device.

Tests

  • python test_parser.py: 4 invoice layouts (intra-state GST, inter-state IGST, retail receipt, service invoice), each clean and with 12 kinds of simulated OCR noise:

    • GSTIN digits read as letters,
    • missing or changed currency signs,
    • cells split into words,
    • uneven baselines,
    • shuffled order.

    52/52 pass.

  • python test_ocr_pipeline.py: checks the OCR pre- and post-processing (resize, box extraction, crops, CTC decoding).

  • python invoice_reader.py --selftest: the full pipeline on the real models with the bundled sample bills.

Limits

  • Printed English bills work best. Handwritten bills and regional-language text are not supported (the recognizer is English).
  • Photos should be reasonably flat, sharp and well lit. A slight tilt is fine.
  • Unusual layouts can still be missed. Check bills marked low or medium confidence.
  • This model needs Python and OpenVINO on your PC, so there is no free online demo: Hugging Face static Spaces cannot run it.

Credits

The OCR networks are PaddleOCR PP-OCR models (Apache-2.0), run with OpenVINO. The field extractor, GSTIN repair and checks are original to this repo.

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. ๐Ÿ™‹ Ask for provider support