File size: 2,014 Bytes
75cf37f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import re
import cv2
import numpy as np
from medical_domain import medical_keywords

# =========================
# IMAGE PRE-PROCESSING
# =========================
def preprocess_image_for_ocr(image_path):
    img = cv2.imread(image_path)
    if img is None: return None
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    denoised = cv2.fastNlMeansDenoising(gray, h=10)
    _, thresh = cv2.threshold(denoised, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
    return thresh

# =========================
# CLEANING & FORMATTING
# =========================
def clean_text(text):
    """Basic whitespace cleanup."""
    text = re.sub(r'\s+', ' ', text)
    return text.strip()

def strict_clean_ocr(text):
    """Fixes common OCR misreads for medical units and numbers."""
    corrections = {
        "O2": "O₂",
        "mm Hg": "mmHg",
        "g dL": "g/dL",
        "cells 1L": "cells/µL"
    }
    for k, v in corrections.items():
        text = text.replace(k, v)
    
    # Remove junk characters but keep medical symbols
    text = re.sub(r'[^\w\s\.\,\:\%\-\°\/]', ' ', text)
    return re.sub(r'\s+', ' ', text).strip()

def bold_medical_terms(text, terms_to_bold):
    """Wraps medical terms in Markdown bold tags for the Gradio UI."""
    for term in terms_to_bold:
        pattern = re.compile(rf'\b({re.escape(term)})\b', re.IGNORECASE)
        text = pattern.sub(r'**\1**', text)
    return text

# =========================
# MEDICAL DETECTION
# =========================
def is_medical_text(text):
    """Gatekeeper: Checks if the document is actually medical."""
    text = text.lower()
    primary_identifiers = ["patient", "clinical", "hospital", "doctor", "medical", "history"]
    
    has_primary = any(id_word in text for id_word in primary_identifiers)
    score = sum(1 for w in medical_keywords if w.lower() in text)

    # Valid if it has a main keyword OR at least 3 specific medical terms
    return has_primary or score >= 3