Files
fuelish/tooling-container/src/ocr.py
T
matthias 7678d28717 Add containerized OCR pipeline for fuel receipts
Self-hosted, verifiable pipeline for extracting structured data (station,
date/time, price per litre, litres, discount, total) from German fuel
receipt photos: grayscale + mild bilateral filter + contrast stretch,
Tesseract OCR, then LLM structuring via a small local model (Qwen 2.5,
served by Ollama). Each step is independently runnable and inspectable
through numbered scripts against a shared tooling container.

Ollama runs as its own long-lived container (0_run_ollama.sh), separate
from the stateless per-receipt pipeline steps, so the model stays loaded
in memory between runs. Includes a containerized ground-truth batch test
(test_batch.sh) that reproduces the full pipeline over the test receipts
and reports per-field accuracy.

Targets eventual deployment on a Raspberry Pi 4 k3s cluster.
2026-09-28 19:35:29 +02:00

35 lines
928 B
Python

#!/usr/bin/env python3
"""Step 2: run Tesseract OCR (German) over a preprocessed receipt image,
writing the raw recognized text to the output directory for inspection
before it is handed to the structuring step."""
import argparse
import os
import pytesseract
from PIL import Image
def ocr(path: str, out_dir: str) -> str:
os.makedirs(out_dir, exist_ok=True)
img = Image.open(path)
text = pytesseract.image_to_string(img, lang="deu", config="--psm 3")
out_path = os.path.join(out_dir, "ocr.txt")
with open(out_path, "w", encoding="utf-8") as f:
f.write(text)
return out_path
def main():
parser = argparse.ArgumentParser()
parser.add_argument("-in", dest="in_path", required=True)
parser.add_argument("-out", dest="out_dir", required=True)
args = parser.parse_args()
out_path = ocr(args.in_path, args.out_dir)
print(out_path)
if __name__ == "__main__":
main()