Fix clipped receipt margins, add time-of-day naming, speed up rotation detection
- vision/document.py: pad_quad() expands the detected quad outward before warping so a straight-line contour fit doesn't clip the first character of every line on a slightly curled/wrinkled receipt - ocr/extract.py + llm/vision.py: extract transaction time (HH:MM) so same-day repeat visits to a vendor get distinct filenames (2023-03-20_1525_walmart.pdf vs. a later same-day trip) - vision/orient.py: downscale before Tesseract OSD/confidence-sweep rotation detection — this was the dominant cost in the detection phase (7x speedup: 472s -> 67s on a 36s test video)
This commit is contained in:
@@ -27,6 +27,9 @@ class NamingResult:
|
||||
source: str # "ocr" | "none" (will include "speech" once module 4 exists)
|
||||
|
||||
|
||||
_TIME_RE = re.compile(r"^([01]\d|2[0-3]):([0-5]\d)$")
|
||||
|
||||
|
||||
def build_name(
|
||||
date: str | None,
|
||||
vendor: str | None,
|
||||
@@ -35,11 +38,21 @@ def build_name(
|
||||
form_code: str | None = None,
|
||||
tax_year: str | None = None,
|
||||
org_name: str | None = None,
|
||||
time: str | None = None,
|
||||
) -> NamingResult:
|
||||
"""date must already be normalized to YYYY-MM-DD, or None."""
|
||||
"""date must already be normalized to YYYY-MM-DD, time to HH:MM, or None.
|
||||
|
||||
Time is appended to the date (e.g. 2023-03-20_1525) whenever it was
|
||||
extracted, so two same-day visits to the same vendor (Walmart in the
|
||||
morning and again in the evening) don't collide or silently overwrite.
|
||||
"""
|
||||
vendor_slug = slugify(vendor, max_vendor_len) if vendor else None
|
||||
ts = fallback_dt.strftime("%Y%m%d_%H%M%S")
|
||||
|
||||
date_part = date
|
||||
if date and time and _TIME_RE.match(time):
|
||||
date_part = f"{date}_{time.replace(':', '')}"
|
||||
|
||||
# Tax slips: prefer 2023_T4_York_University over UNSORTED_t4_york_university_<timestamp>.
|
||||
if form_code:
|
||||
org_slug = slugify(org_name, max_vendor_len) if org_name else None
|
||||
@@ -58,10 +71,10 @@ def build_name(
|
||||
return NamingResult(stem=f"{code}_{org_slug}", source="ocr")
|
||||
return NamingResult(stem=code.lower(), source="ocr")
|
||||
|
||||
if date and vendor_slug:
|
||||
return NamingResult(stem=f"{date}_{vendor_slug}", source="ocr")
|
||||
if date:
|
||||
return NamingResult(stem=f"{date}_UNSORTED", source="ocr")
|
||||
if date_part and vendor_slug:
|
||||
return NamingResult(stem=f"{date_part}_{vendor_slug}", source="ocr")
|
||||
if date_part:
|
||||
return NamingResult(stem=f"{date_part}_UNSORTED", source="ocr")
|
||||
if vendor_slug:
|
||||
return NamingResult(stem=f"UNSORTED_{vendor_slug}_{ts}", source="ocr")
|
||||
return NamingResult(stem=f"UNSORTED_{ts}", source="none")
|
||||
|
||||
Reference in New Issue
Block a user