Spaces:
Sleeping
Sleeping
File size: 5,974 Bytes
900df0b | 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 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | """
محرك كشف الجداول بـ Table Transformer (TATR)
================================================
يكشف مواقع الجداول في الصور باستخدام Microsoft Table Transformer.
يُرجع قائمة بالجداول المكتشفة مع إحداثيات BBox ونسبة الثقة.
يمكن دمج النتائج مع الهيكل القياسي لـ normalize_ocr_output().
المؤلف: Dr Abdulmalek Tamer Al-husseini
الترخيص: MIT
"""
import logging
from typing import Optional
logger = logging.getLogger(__name__)
class TableDetectionTransformer:
"""
محرك كشف الجداول باستخدام Table Transformer.
مثال الاستخدام:
>>> detector = TableDetectionTransformer(device='cpu')
>>> tables = detector.detect_tables("image.jpg", threshold=0.8)
>>> for t in tables:
... print(f"جدول: {t['bbox']}, ثقة: {t['score']}")
"""
def __init__(
self,
model_name: str = "microsoft/table-transformer-detection",
device: Optional[str] = None,
):
"""
تهيئة كاشف الجداول.
Args:
model_name: اسم النموذج من HuggingFace
device: الجهاز ('cuda' أو 'cpu'). إذا None يُكتشف تلقائياً.
"""
self.model_name = model_name
self.processor = None
self.model = None
self._loaded = False
if device is None:
try:
import torch
self.device = "cuda" if torch.cuda.is_available() else "cpu"
except ImportError:
self.device = "cpu"
else:
self.device = device
def _load_model(self) -> bool:
"""
تحميل النموذج والمعالج (Lazy Loading).
Returns:
True إذا تم التحميل بنجاح
"""
if self._loaded and self.model is not None:
return True
try:
from transformers import (
AutoImageProcessor,
AutoModelForObjectDetection,
)
import torch
logger.info("جارٍ تحميل Table Transformer (الجهاز: %s)...", self.device)
self.processor = AutoImageProcessor.from_pretrained(self.model_name)
self.model = (
AutoModelForObjectDetection.from_pretrained(self.model_name)
.to(self.device)
)
self.model.eval()
self._loaded = True
logger.info("تم تحميل Table Transformer بنجاح")
return True
except ImportError:
logger.warning(
"مكتبة transformers غير مثبتة. قم بتثبيتها:\n"
" pip install transformers>=4.37.0 torch>=2.0.0"
)
return False
except Exception as e:
logger.error("فشل في تحميل Table Transformer: %s", e)
return False
def detect_tables(
self,
image_path: str,
threshold: float = 0.8,
) -> list[dict]:
"""
كشف الجداول في صورة.
Args:
image_path: مسار ملف الصورة
threshold: حد الثقة الأدنى لاكتشاف الجداول (الافتراضي 0.8)
Returns:
قائمة جداول، كل جدول يحتوي على:
- bbox: [x1, y1, x2, y2] (إحداثيات مطلقة)
- score: نسبة الثقة (0-1)
- label: تسمية الكائن المكتشف
"""
if not self._load_model():
logger.warning("تعذر تحميل Table Transformer")
return []
try:
import torch
from PIL import Image
image = Image.open(image_path).convert("RGB")
inputs = self.processor(
images=image, return_tensors="pt"
).to(self.device)
with torch.no_grad():
outputs = self.model(**inputs)
target_sizes = torch.tensor([image.size[::-1]]).to(self.device)
results = self.processor.post_process_object_detection(
outputs,
threshold=threshold,
target_sizes=target_sizes,
)[0]
tables = []
for score, label, box in zip(
results["scores"],
results["labels"],
results["boxes"],
):
box_coords = [round(i) for i in box.tolist()]
tables.append({
"bbox": box_coords,
"score": round(score.item(), 3),
"label": self.model.config.id2label[label.item()],
})
logger.info(
"تم كشف %d جدول في الصورة (عتبة: %.2f)",
len(tables),
threshold,
)
return tables
except Exception as e:
logger.error("فشل في كشف الجداول: %s", e)
return []
def detect_tables_relative(
self,
image_path: str,
threshold: float = 0.8,
) -> list[dict]:
"""
كشف الجداول مع إحداثيات نسبية (للدمج مع الهيكل القياسي).
Args:
image_path: مسار ملف الصورة
threshold: حد الثقة الأدنى
Returns:
قائمة جداول مع bbox نسبي [x1/W, y1/H, x2/W, y2/H]
"""
from PIL import Image
tables = self.detect_tables(image_path, threshold)
img = Image.open(image_path)
w, h = img.size
for table in tables:
x1, y1, x2, y2 = table["bbox"]
table["bbox_relative"] = [x1 / w, y1 / h, x2 / w, y2 / h]
return tables
|