Add OCR naming and PNG-to-PDF export (modules 5-7, single-page only)
- ocr/: Tesseract-based vendor/date/total extraction. PSM 6 (single uniform text block) instead of the default fixes receipts where item-name/price columns were otherwise split into separate blocks and dropped. Vendor line picked by median (not max) word height within the top fraction of the crop, breaking ties by topmost line - max() was fooled by single descender/ascender glyphs (commas, parens) inflating one word's bounding box. - naming/: merge OCR metadata into YYYY-MM-DD_vendor.pdf filenames, degrading gracefully to UNSORTED_<timestamp>.pdf; per-run dedup. - pdf/: img2pdf-based multi-page-capable assembly (images_to_pdf). - pipeline.run_export(): OCR + name + PDF each detected crop from a detect() report, writes pdf/ and export_summary.csv. - New `paperpod export <video>` CLI command. - Verified against synthetic Home Depot/Metro/Petro-Canada receipts: 3/3 correct vendor, date, and total after tuning. Known limitation (documented in README): no page-flip/multi-page grouping yet (that's events/, still unbuilt) - every detected document becomes its own single-page PDF.
This commit is contained in:
@@ -42,6 +42,34 @@ class SpeechConfig:
|
||||
window_after_s: float = 5.0
|
||||
|
||||
|
||||
@dataclass
|
||||
class OcrConfig:
|
||||
# Tesseract language pack (e.g. "eng", "eng+fra").
|
||||
lang: str = "eng"
|
||||
# Page segmentation mode. 6 = "assume a single uniform block of text",
|
||||
# which (unlike Tesseract's default of 3) keeps each receipt line's
|
||||
# item-name and price together instead of splitting them into separate
|
||||
# column blocks and dropping one. Verified against synthetic Home Depot/
|
||||
# Metro/Petro-Canada receipts; revisit if real receipts have a layout
|
||||
# PSM 6 handles worse (e.g. multi-column letters).
|
||||
psm: int = 6
|
||||
# Vendor name is assumed to live in this top fraction of the crop
|
||||
# (receipt headers / letterheads are typically near the top).
|
||||
vendor_top_fraction: float = 0.4
|
||||
# Words below this Tesseract confidence (0-100) are ignored when
|
||||
# picking the vendor line. Kept low deliberately: header text (larger,
|
||||
# sometimes bold/stylized fonts) can score much lower confidence than
|
||||
# crisp monospace body text despite being read correctly, and the
|
||||
# line-height + topmost heuristic already screens out low-confidence
|
||||
# noise (garbled OCR hallucinations measure much shorter than real text).
|
||||
min_word_confidence: float = 10.0
|
||||
|
||||
|
||||
@dataclass
|
||||
class NamingConfig:
|
||||
max_vendor_len: int = 40
|
||||
|
||||
|
||||
@dataclass
|
||||
class OutputConfig:
|
||||
dir: str = "./output"
|
||||
@@ -55,6 +83,8 @@ class Config:
|
||||
motion: MotionConfig = field(default_factory=MotionConfig)
|
||||
document: DocumentConfig = field(default_factory=DocumentConfig)
|
||||
speech: SpeechConfig = field(default_factory=SpeechConfig)
|
||||
ocr: OcrConfig = field(default_factory=OcrConfig)
|
||||
naming: NamingConfig = field(default_factory=NamingConfig)
|
||||
output: OutputConfig = field(default_factory=OutputConfig)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user