OCR-Demo / core /models.py
thangvckeygen's picture
Deploy 7-Model OCR Benchmark Space with Bounding Box Visualizer
b611f38
Raw
History Blame Contribute Delete
4.49 kB
"""
Core Data Models for Local-First OCR Benchmarking & Region Classification.
Standardizes bounding boxes, semantic categories, and benchmark results across all 6 models.
"""
from dataclasses import dataclass, field, asdict
from typing import List, Dict, Any, Optional
from enum import Enum
class RegionType(str, Enum):
"""Standardized 10 semantic region categories."""
TITLE_HEADER = "Title/Header"
PARAGRAPH = "Paragraph"
TEXT = "Text"
TABLE = "Table"
TABLE_CELL = "Table cell"
KEY_VALUE = "Key-Value"
NUMBER_PRICE = "Number/Price"
IMAGE = "Image"
FOOTER = "Footer"
OTHER = "Other"
# Standard 10 categories as list of strings
ALL_REGION_TYPES: List[str] = [rt.value for rt in RegionType]
# Aesthetic color palette for visualization (RGBA / Hex)
REGION_COLORS: Dict[str, Dict[str, Any]] = {
RegionType.TITLE_HEADER.value: {
"hex": "#8B5CF6", # Purple
"rgb": (139, 92, 246),
"fill_rgba": (139, 92, 246, 50),
"badge_bg": "#EDE9FE",
"badge_text": "#5B21B6"
},
RegionType.PARAGRAPH.value: {
"hex": "#10B981", # Emerald
"rgb": (16, 185, 129),
"fill_rgba": (16, 185, 129, 45),
"badge_bg": "#D1FAE5",
"badge_text": "#065F46"
},
RegionType.TEXT.value: {
"hex": "#06B6D4", # Cyan / Teal
"rgb": (6, 182, 212),
"fill_rgba": (6, 182, 212, 40),
"badge_bg": "#CFFAFE",
"badge_text": "#155E75"
},
RegionType.TABLE.value: {
"hex": "#3B82F6", # Blue
"rgb": (59, 130, 246),
"fill_rgba": (59, 130, 246, 55),
"badge_bg": "#DBEAFE",
"badge_text": "#1E40AF"
},
RegionType.TABLE_CELL.value: {
"hex": "#60A5FA", # Light Blue
"rgb": (96, 165, 250),
"fill_rgba": (96, 165, 250, 40),
"badge_bg": "#EFF6FF",
"badge_text": "#1D4ED8"
},
RegionType.KEY_VALUE.value: {
"hex": "#F59E0B", # Amber
"rgb": (245, 158, 11),
"fill_rgba": (245, 158, 11, 55),
"badge_bg": "#FEF3C7",
"badge_text": "#92400E"
},
RegionType.NUMBER_PRICE.value: {
"hex": "#F97316", # Orange
"rgb": (249, 115, 22),
"fill_rgba": (249, 115, 22, 60),
"badge_bg": "#FFEDD5",
"badge_text": "#9A3412"
},
RegionType.IMAGE.value: {
"hex": "#EC4899", # Pink / Rose
"rgb": (236, 72, 153),
"fill_rgba": (236, 72, 153, 50),
"badge_bg": "#FCE7F3",
"badge_text": "#9D174D"
},
RegionType.FOOTER.value: {
"hex": "#64748B", # Slate
"rgb": (100, 116, 139),
"fill_rgba": (100, 116, 139, 45),
"badge_bg": "#F1F5F9",
"badge_text": "#334155"
},
RegionType.OTHER.value: {
"hex": "#9CA3AF", # Gray
"rgb": (156, 163, 175),
"fill_rgba": (156, 163, 175, 40),
"badge_bg": "#F3F4F6",
"badge_text": "#374151"
}
}
@dataclass
class Region:
"""Represents a single detected spatial layout region on the document image."""
box: List[int] # [x1, y1, x2, y2] in exact pixel coordinates
text: str # Recognized text content
region_type: str = RegionType.TEXT.value # One of the 10 standardized categories
confidence: Optional[float] = None # Confidence score between 0.0 and 1.0
details: Optional[Dict[str, Any]] = None # Extra metadata (e.g. table HTML, key-value split)
def to_dict(self) -> Dict[str, Any]:
return asdict(self)
@dataclass
class OCRModelOutput:
"""Standardized result output from any of the 6 OCR models."""
model_name: str
model_id: str
status: str # 'SUCCESS' or 'ERROR'
inference_time_seconds: Optional[float] = None
inference_time_str: str = "N/A"
text: Optional[str] = None
markdown: Optional[str] = None
json: Optional[Any] = None
output_type: str = "markdown"
word_count: int = 0
regions: List[Region] = field(default_factory=list)
region_counts: Dict[str, int] = field(default_factory=dict)
annotated_image_path: Optional[str] = None
annotated_image_base64: Optional[str] = None
error: Optional[str] = None
def to_dict(self) -> Dict[str, Any]:
d = asdict(self)
d["regions"] = [r.to_dict() if isinstance(r, Region) else r for r in self.regions]
return d