قراءة المستندات العربية آلياً (OCR) على سيرفر خاص

للمستندات العربية المطبوعة النظيفة يكفي Tesseract أو PaddleOCR على CPU بثانية أو ثانيتين للصفحة، أما الصور الرديئة والجداول فتحتاج نموذج رؤية حديثاً. عالج الصورة قبل القراءة، واقرأ رمز QR في الفاتورة الإلكترونية أولاً، وأبقِ وثائق عملائك على سيرفر سعودي.
قراءة المستندات العربية آلياً ممكنة اليوم بأدوات مفتوحة تعمل على سيرفرك، لكن اختيار الأداة يعتمد على نوع الوثيقة لا على شهرة الأداة. الجواب المباشر: إذا كانت وثائقك مطبوعة ونظيفة (عقود مولّدة من Word، خطابات رسمية ممسوحة بدقة 300 نقطة في البوصة)، فـTesseract 5 بنموذج العربية المحسّن أو PaddleOCR يقرآن الصفحة على CPU في ثانية أو ثانيتين بدقة عالية على مستوى الحروف. إذا كانت صوراً من جوال بزوايا مائلة وإضاءة سيئة، أو فيها جداول وأختام وخط يد، فالأدوات التقليدية تنهار، وتحتاج نموذج رؤية لغوياً حديثاً مثل Qwen2.5-VL يقرأ الصورة ويفهم بنيتها ويخرج الحقول مباشرة بصيغة JSON، مع كلفة أعلى في الموارد. في الحالتين، ثلاث قواعد ترفع النتائج أكثر من تبديل الأداة: عالج الصورة قبل القراءة (تدوير وتباين وإزالة ضجيج)، وتحقق من الحقول المستخرجة بقواعد حسابية بدل الثقة العمياء، واقرأ رمز QR في الفاتورة الإلكترونية السعودية قبل أي OCR لأنه يحمل الرقم الضريبي والإجمالي والضريبة بدقة كاملة. لأن هذه الوثائق تحمل هويات وأرقام حسابات وعقوداً، فمكانها الطبيعي سيرفر داخل المملكة لا خدمة OCR خارجية.
لماذا العربية أصعب في OCR
أغلب محركات OCR صُممت لحروف لاتينية منفصلة، أما العربية فتحدّيها مختلف من أربع جهات:
- الاتصال: الحروف متصلة، وشكل الحرف يتغير حسب موقعه (أول ووسط وآخر ومنفرد)، فلا يمكن تقطيع الكلمة إلى حروف بمسافات واضحة.
- النقاط: الفرق بين ب وت وث ون وي نقطة أو نقطتان، وأي ضجيج في المسح أو ختم فوق النص يحوّل حرفاً إلى آخر.
- اختلاط الاتجاه: سطر عربي من اليمين فيه رقم سجل تجاري أو بريد إلكتروني من اليسار، والمحرك الضعيف يعكس ترتيب الأرقام.
- الأرقام بنوعين: فاتورة واحدة قد تحمل ١٢٣ و123 معاً، فلا بد من توحيدها بعد القراءة.
يضاف لذلك الفرق الكبير بين النص المطبوع والمكتوب بخط اليد. المطبوع اليوم مقروء بدقة تتجاوز غالباً 95% على مستوى الحروف إذا كان المسح جيداً، أما خط اليد العربي فما زال صعباً على كل الأدوات المفتوحة، وتوقّع نتائج متذبذبة حتى مع نماذج الرؤية الكبيرة.
مقارنة الأدوات المفتوحة
| الأداة | النوع | العربية المطبوعة | الجداول والتخطيط | الموارد | زمن الصفحة تقريباً |
|---|---|---|---|---|---|
| Tesseract 5 (tessdata_best) | LSTM تقليدي | جيدة جداً على المسح النظيف | ضعيفة | CPU فقط | من 1 إلى 3 ثوانٍ |
| PaddleOCR | كشف وتعرّف عميق | جيدة، أفضل مع الصور المائلة | متوسطة عبر وحدة التخطيط | CPU أو GPU | من 1 إلى 4 ثوانٍ |
| EasyOCR | كشف وتعرّف عميق | متوسطة | ضعيفة | يُفضّل GPU | من 2 إلى 6 ثوانٍ على CPU |
| Qwen2.5-VL 7B | نموذج رؤية لغوي | جيدة جداً حتى مع الصور الرديئة | قوية، يخرج JSON أو جدولاً | GPU بذاكرة 16GB أو أكثر | من 3 إلى 10 ثوانٍ على GPU |
الأرقام تقريبية لصفحة A4 وتختلف كثيراً حسب كثافة النص والمعالج. على CPU يعمل نموذج رؤية بحجم 7B لكنه بطيء، من 30 إلى 90 ثانية للصفحة، وهذا مقبول لعشرات الوثائق يومياً لا لآلاف. راجع رخصة كل نموذج قبل الاستخدام التجاري، فبعض أدوات OCR الحديثة تصدر برخص تقيّد الاستخدام التجاري.
معالجة الصورة قبل القراءة
أكبر تحسين في الدقة يأتي من هذه الخطوة لا من تبديل المحرك. صورة ممسوحة بدقة 150 نقطة ومائلة 3 درجات قد تنزل دقتها إلى النصف. المعالجة الأساسية بـOpenCV:
import cv2, numpy as np
def preprocess(path: str):
img = cv2.imread(path, cv2.IMREAD_GRAYSCALE)
h, w = img.shape
if w < 2000: # ارفع الدقة للصور الصغيرة
img = cv2.resize(img, None, fx=2000/w, fy=2000/w,
interpolation=cv2.INTER_CUBIC)
img = cv2.fastNlMeansDenoising(img, h=15)
th = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY, 31, 15)
coords = np.column_stack(np.where(th == 0))
angle = cv2.minAreaRect(coords)[-1]
angle = angle - 90 if angle > 45 else angle
M = cv2.getRotationMatrix2D((w/2, h/2), angle, 1.0)
return cv2.warpAffine(th, M, (th.shape[1], th.shape[0]),
flags=cv2.INTER_CUBIC, borderValue=255)
الخطوات: تحويل للرمادي، ورفع الدقة إن كانت الصورة صغيرة، وإزالة الضجيج، وعتبة تكيفية تتعامل مع الظلال في صور الجوال، ثم تصحيح الميل. للأختام الزرقاء أو الحمراء فوق النص جرّب قبل التحويل للرمادي أن تأخذ القناة اللونية التي يختفي فيها الختم.
Tesseract عملياً
sudo apt install tesseract-ocr
sudo wget -O /usr/share/tesseract-ocr/5/tessdata/ara.traineddata \
https://github.com/tesseract-ocr/tessdata_best/raw/main/ara.traineddata
tesseract page.png out -l ara+eng --psm 6 --oem 1
استخدم نموذج tessdata_best لا النموذج السريع الافتراضي، فالفرق في العربية ملحوظ. خيار ara+eng ضروري للوثائق التي تمزج أسماء شركات أو بريداً إنجليزياً. الخيار psm 6 يفترض كتلة نص واحدة ويناسب الخطابات، بينما psm 4 أنسب للفواتير ذات الأعمدة. بعد القراءة وحّد الأرقام العربية الهندية إلى لاتينية قبل أي معالجة:
text = text.translate(str.maketrans("٠١٢٣٤٥٦٧٨٩", "0123456789"))
استخراج حقول الفواتير والعقود
ابدأ برمز QR
الفاتورة الضريبية المبسطة في المملكة تحمل رمز QR مشفراً بصيغة TLV ثم Base64، ويضم اسم البائع والرقم الضريبي وتاريخ الفاتورة والإجمالي مع الضريبة ومبلغ الضريبة. قراءته بمكتبة pyzbar ثم فك TLV يعطيك هذه الحقول الخمسة بدقة كاملة في أقل من 100 ميلي ثانية، دون أي OCR. اجعل هذه الخطوة الأولى في خط المعالجة، ولا تلجأ للقراءة النصية إلا إن غاب الرمز أو تلف.
فك الرمز يحتاج سطوراً قليلة، فكل حقل يبدأ ببايت للنوع ثم بايت للطول ثم القيمة:
from pyzbar.pyzbar import decode
from PIL import Image
import base64
def read_zatca_qr(path: str) -> dict:
raw = base64.b64decode(decode(Image.open(path))[0].data)
names = {1: "seller", 2: "vat_no", 3: "timestamp", 4: "total", 5: "vat"}
out, i = {}, 0
while i < len(raw):
tag, ln = raw[i], raw[i+1]
out[names.get(tag, tag)] = raw[i+2:i+2+ln].decode("utf-8")
i += 2 + ln
return out
إن أعادت الدالة خمسة حقول سليمة، فقد انتهت فاتورتك دون أن يلمسها محرك OCR، وتحتاج القراءة النصية فقط لجدول البنود إن أردت تفصيله.
ثم تحقق بالقواعد
حين تستخرج الحقول بالـOCR أو بنموذج رؤية، لا تقبلها كما هي. ثلاث قواعد تكشف أغلب الأخطاء: الرقم الضريبي 15 خانة يبدأ بـ3 وينتهي بـ3، والمبلغ قبل الضريبة مضروباً في 1.15 يساوي الإجمالي بفرق لا يتجاوز هللة أو هللتين، والتاريخ يقع في نطاق منطقي. أي فاتورة تفشل في قاعدة تذهب لمراجعة بشرية بدل أن تدخل النظام المحاسبي خطأً.
نموذج الرؤية للحالات الصعبة
للعقود والفواتير بلا QR أو بجداول معقدة، اطلب من نموذج الرؤية إخراجاً منظماً: "استخرج من الصورة: اسم المورد، الرقم الضريبي، التاريخ، جدول البنود (الوصف، الكمية، السعر)، الإجمالي. أعد JSON فقط." شغّله عبر vLLM أو Ollama على نفس السيرفر، ثم مرّر الناتج على نفس قواعد التحقق. الخط المثالي هجين: QR أولاً، ثم PaddleOCR أو Tesseract للصفحات النظيفة، ثم نموذج الرؤية للصفحات التي تفشل في التحقق فقط، فتوفر نحو 80% من وقت المعالجة الثقيلة.
لماذا تبقى الوثائق على سيرفر سعودي
الوثائق التي تمر على OCR هي الأكثر حساسية في أي شركة: صور هويات، وعقود، وكشوف حسابات، وفواتير موردين. خدمات OCR السحابية الخارجية تعني رفع كل هذا لبلد آخر، وهذا يتعارض مع نظام حماية البيانات الشخصية ومع اشتراطات كثير من الجهات الحكومية. تشغيل المعالجة على خادم سحابي في الرياض يبقي الوثيقة في مسار محلي من لحظة الرفع حتى الحذف.
للحجم: خط Tesseract أو PaddleOCR مع قراءة QR يعالج نحو 2,000 صفحة يومياً على باقة نمو بنواتين و4GB بسعر 6,900 ريال سنوياً، وباقة أعمال بـ4 أنوية و8GB بسعر 11,500 ريال تضاعف ذلك تقريباً. أضف 100GB SSD بـ500 ريال سنوياً لكل نحو 200 ألف صفحة مؤرشفة بصيغة PDF مضغوطة. إن أردت نموذج رؤية على نفس البنية فابدأ من قوالب استضافة الذكاء الاصطناعي التي تأتي بـDocker وJupyter جاهزين للتجربة.
خطة تنفيذ من خمس خطوات
- صنّف وثائقك: كم منها مطبوع نظيف، وكم صور جوال، وكم فواتير بـQR.
- ابنِ خط المعالجة: QR أولاً، ثم معالجة الصورة، ثم Tesseract بنموذج best أو PaddleOCR.
- أضف قواعد التحقق للرقم الضريبي والإجماليات والتواريخ، وأرسل ما يفشل لمراجعة بشرية.
- اختبر على 200 وثيقة حقيقية وقِس نسبة الحقول الصحيحة، ثم قرر إن كان نموذج الرؤية يستحق كلفته للصفحات الصعبة.
- اختر حجم السيرفر من الأسعار والباقات، واحذف الصور الأصلية بعد الاستخراج وفق سياسة احتفاظ مكتوبة.


