File size: 2,462 Bytes
b31a61d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
"""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),
    }