larmedix / ocr_utils.py
larxius
fix(lab): photo extract that works without vision key
b31a61d
Raw History Blame Contribute Delete
2.46 kB
"""OCR helpers for lab report images (EasyOCR + OpenCV + regex).
13 extracted fields: Gender, Age, Hemoglobin, RBC, WBC, AST, ALT,
Cholesterol, Spirometry, Creatinine, Glucose, Lipase, Troponin.
Missing values are returned as None.
"""
import re
_reader = None
def get_reader():
"""Lazy singleton EasyOCR reader (downloads ~100MB weights on first call)."""
global _reader
if _reader is None:
import easyocr
_reader = easyocr.Reader(['en'], gpu=False)
return _reader
def ocr_image(image_path: str) -> str:
"""Run OCR on an image file and return raw text."""
import cv2
reader = get_reader()
img = cv2.imread(image_path)
if img is None:
raise ValueError("Could not read image. Use JPG/PNG.")
# EasyOCR handles numpy arrays (BGR) directly.
results = reader.readtext(img)
return " ".join([t[1] for t in results])
def _num(patterns, text, cast=float):
for pat in patterns:
m = re.search(pat, text, re.IGNORECASE)
if m:
try:
return cast(m.group(1).replace(',', ''))
except (ValueError, IndexError):
continue
return None
def extract_lab_values(text: str) -> dict:
"""Regex-extract the 13 lab fields from OCR text (None if not found)."""
t = text or ""
gender = None
if re.search(r'\bfemale\b', t, re.IGNORECASE):
gender = "Female"
elif re.search(r'\bmale\b', t, re.IGNORECASE):
gender = "Male"
return {
"Gender": gender,
"Age": _num([r'age\D{0,10}(\d{1,3})'], t, int),
"Hemoglobin": _num([r'h(?:ae)?moglobin\D{0,15}(\d+\.?\d*)', r'\bHb\D{0,10}(\d+\.?\d*)'], t),
"RBC": _num([r'\bRBC\D{0,10}(\d+\.?\d*)'], t),
"WBC": _num([r'\bWBC\D{0,10}([\d,]+\.?\d*)', r'W\.?B\.?C\.?\D{0,10}([\d,]+\.?\d*)'], t),
"AST": _num([r'\bAST\D{0,10}(\d+\.?\d*)', r'\bSGOT\D{0,10}(\d+\.?\d*)'], t),
"ALT": _num([r'\bALT\D{0,10}(\d+\.?\d*)', r'\bSGPT\D{0,10}(\d+\.?\d*)'], t),
"Cholesterol": _num([r'cholesterol\D{0,15}(\d+\.?\d*)'], t),
"Spirometry": _num([r'spirometry\D{0,15}(\d+\.?\d*)', r'\bFEV1?\D{0,10}(\d+\.?\d*)'], t),
"Creatinine": _num([r'creatinine\D{0,15}(\d+\.?\d*)'], t),
"Glucose": _num([r'glucose\D{0,15}(\d+\.?\d*)', r'blood sugar\D{0,15}(\d+\.?\d*)'], t),
"Lipase": _num([r'lipase\D{0,15}(\d+\.?\d*)'], t),
"Troponin": _num([r'troponin\D{0,15}(\d+\.?\d*)'], t),
}