EasyOCR هو مكتبة OCR جاهزة من JaidedAI لبايثون: pip install easyocr، وسطران من الكود، ثم يرجع لك النص الموجود داخل الصورة على هيئة سلاسل نصية. المكتبة مرخّصة تحت Apache-2.0، وتدعم أكثر من 80 لغة، وتعمل كسلسلة من نموذجين في PyTorch — كاشف CRAFT يحدد أي جزء يعتقد أنه نص، ثم مُعرِّف يقرأ الأحرف داخل كل صندوق. أوزان النموذج المدرَّبة مسبقًا تُنزَّل تلقائيًا عند أول استخدام. ومن حيث الفكرة، فهي بديل مستضاف ذاتيًا لـ Tesseract وPaddleOCR، وليست واجهة OCR سحابية تُحاسَب لكل صفحة.
واجهة الاستخدام الأساسية مختصرة جدًا: Reader(['en']) ثم readtext(). لكن النشر الفعلي أثقل بكثير — حوالي 2 غيغابايت من PyTorch في هذه البيئة، ونحو غيغابايت واحد من الذاكرة المقيمة في عملية جديدة تم قياسها. لقد أنشأت 36 ملف PNG باللغة الإنجليزية، وشغّلت easyocr 1.7.2 على المعالج فقط، ثم قيّمت النتائج حرفًا بحرف مقابل الحقيقة المرجعية التي ولّدتها. كان الحجم والاتجاه هما العاملين الأكبرين في هبوط معدل الخطأ الحرفي CER؛ كما كشف الاختبار أيضًا عن مشاكل في اكتشاف الرموز القصيرة والتعرّف على علامة الدولار.
أشد هذه الإخفاقات يرتبط بالمعامل الذي ينصح به الجميع تقريبًا. لدى rotation_info سمعة على صفحة القضايا باعتباره الحل للصور الدوارة، لذلك اختبرته على ثلاث نسخ من الجملة نفسها بعد تدويرها بزاوية قائمة مختلفة. عند 270°، فعل تمامًا ما يعد به، إذ خفّض معدل الخطأ الحرفي من 0.83 إلى 0.10. عند 180°، نجح جزئيًا فقط: من 0.85 إلى 0.67، مع إسقاط عبارة كاملة. أما عند 90°، فكان الأسوأ: من 0.81 إلى 0.92، وبدأ المُعرِّف بإرجاع نصوص معكوسة في المرآة. نفس المعامل، ونفس قائمة الزوايا، وثلاث نتائج مختلفة — لذا تشغيله لا يعني أن "تدوير الصورة تم التعامل معه". كما أنتجت نفس العينات الـ36 أيضًا سقفًا حادًا جدًا لحجم الخط، وخطأً منهجيًا في قراءة علامة الدولار، وتنبؤًا واحدًا مني اتضح أنه كان خاطئًا تمامًا.
نموذجان داخل معطف واحد
EasyOCR ليس نموذجًا واحدًا. إنه خط معالجة من مرحلتين، ومعرفة أي مرحلة أخفقت تغيّر طريقة التشخيص بالكامل.
المرحلة الأولى هي CRAFT، أي الكاشف. مهمته الوحيدة هي تحديد المواقع — أين يوجد نص في الصورة أصلًا، ثم إرجاع الصناديق المحيطة به. هو لا يقرأ أي حرف. المرحلة الثانية هي CRNN، أي المعرِّف — استخراج خصائص عبر ResNet، ثم BiLSTM، ثم فك ترميز CTC greedy — وهو الذي يقرأ الأحرف داخل كل صندوق. كلا المرحلتين تعملان على PyTorch. وعلى المعالج، يعمل المُعرِّف افتراضيًا بعد ضغط ديناميكي إلى int8، ولهذا يكون أسرع وأخف مما يوحي به عدد المعاملات الخام.

النتيجة العملية: لدى EasyOCR نمطان مختلفان تمامًا من الفشل، ويحتاج كل واحد إلى علاج مختلف. إذا لم يرسم الكاشف أي صندوق، فلن يفيدك أي تحسين للمُعرِّف — لأن الأحرف لم تدخل خط المعالجة أصلًا. وإذا كان الصندوق موجودًا لكن النص خاطئًا، فالمشكلة في التعرّف، وقد ينقذها بعض المعالجة المسبقة. تقريبًا كل نقاش من نوع "EasyOCR تجاهل النص الخاص بي" قرأته يخلط بين هذين الأمرين.
الحالة الحالية للمشروع، وفق فحص بتاريخ 27 يوليو 2026: 29,825 نجمة، 528 قضية مفتوحة، رخصة Apache-2.0، والإصدار v1.7.2 من سبتمبر 2024، مع آخر push إلى master في ديسمبر 2025. هذه التواريخ لا تثبت الاستقرار المعماري ولا صحة الصيانة. قبل الاعتماد عليه، تحقّق من التوافق مع حزمة Python/PyTorch لديك، ومن سرعة استجابة الصيانة الحديثة، ومن القضايا المرتبطة بمدخلاتك.
يرتبط OCR كثيرًا بفكرة حل CAPTCHA، وهذا ليس الاستخدام المقصود هنا. لم يتم اختبار أي شيء ضد أنظمة مكافحة البوتات، ولا يوجد هنا أي تأييد لتجاوز تحديات كشف الروبوتات. نطاق العمل هنا هو قراءة النص من الصور ولقطات الشاشة التي يحق لك قراءتها.
ما الذي قسته، وما الذي لا تغطيه هذه الأرقام
مجموعة الاختبار تتكوّن من 36 ملف PNG قمت برسمها بنفسي: 35 صورة سطر واحد تغطي سبعة خطوط، وثمانية أحجام، وسبع درجات تباين، وسبع زوايا ميل، وثلاث تدويرات متعامدة، وثلاث خلفيات — بالإضافة إلى لقطة شاشة تركيبية للوحة تحكم تضم 19 عنصرًا معنّونًا بشكل منفصل. كل صورة وُلدت من سلسلة ثابتة (Sphinx of black quartz, judge my vow. 1234567890 — 48 حرفًا، بحالة كبيرة وصغيرة مختلطة، وأرقام، وعلامات ترقيم) في نفس الخطوة التي كُتب فيها الوسم المرجعي، لذلك لا يمكن للصورة ووسمها أن ينفصلا عن بعضهما عمليًا.
الدقة تُقاس عبر معدل الخطأ الحرفي (CER): مسافة Levenshtein على مستوى الأحرف مقسومة على طول النص المرجعي. CER = 0 يعني قراءة مثالية. CER = 0.10 يعني أن نحو حرف واحد من كل عشرة خاطئ. أذكر CER الحساس لحالة الأحرف كعنوان رئيسي، ومعه CER غير الحساس للحالة، لأن الحالة هي المكان الذي يعيش فيه معظم "الخطأ" فعليًا.
لكن الحدود أهم من الأرقام نفسها:
- الإنجليزية فقط. المعرّف
english_g2. EasyOCR يعلن دعم أكثر من 80 لغة؛ أنا اختبرت لغة واحدة. لا شيء هنا يقول شيئًا عن النصوص غير اللاتينية، وهي أصلًا المنطقة التي تتركز فيها المقارنات الأكاديمية المنشورة في OCR. - بيانات تركيبية فقط. نص مرسوم، وليس صورًا فوتوغرافية. لا ضجيج كاميرا، ولا آثار JPEG، ولا إضاءة، ولا منظور.
- لا كتابة يدوية. المشروع نفسه يذكر أن الكتابة اليدوية غير مدعومة بعد.
- المعالج فقط. macOS arm64، و
gpu=False. كانت MPS متاحة على الجهاز، لكن EasyOCR يستخدم المعالج إذا لم تكن هناك CUDA. لم تُقَس أي أداءات على GPU، لذلك لن ترى أي رقم GPU هنا. - جهاز واحد، وإصدار واحد. easyocr 1.7.2، torch 2.13.0، Python 3.12.
إذًا: هذه منحنيات مضبوطة لعامل واحد تكشف بدقة أين يبدأ فقدان الدقة، على نص لاتيني نظيف ومُرسوم. لكنها ليست تقييمًا لبيانات واقعية، ولا تصلح بديلًا عنه.
الأدلة قابلة للفحص وليست حبيسة دفتر ملاحظات. مولّد العينات والنصوص المرجعية موجودان في tests/build_fixtures.py وtests/fixtures/ground_truth.json؛ أما التعرف والتوقيت والتقاط الموارد فتوجد في tests/run_easyocr.py؛ وtests/metrics.py تحسب معدلات الخطأ المعروضة من المخرجات الخام. سجلات التعرف والقياسات التجميعية محفوظة تحت artifacts/raw/. إعادة تشغيل هذه السلسلة مفيدة للتحقق من هذا الجهاز وهذا الإصدار. لكنها ما زالت لا تقول كيف سيتصرف EasyOCR مع صور هاتفك، أو لغاتك، أو التخطيطات، أو سلسلة المعالجة المسبقة لديك، لذلك يجب أن يضيف تقييم الإنتاج مدخلات ممثلة بدلًا من اعتبار هذه العينات مجموعة اعتماد نهائية.
هناك فخ واحد في أداة القياس يستحق التنبيه، لأنه كاد يخرج بعنوان خاطئ تمامًا. أول تمريرة للقياس أعطتني CER = 0.375 على Arial الأسود النظيف، وهو رقم سيئ جدًا لأبسط إدخال ممكن. لكن المشكلة لم تكن في EasyOCR. الكاشف كان قد قسم سطرًا بصريًا واحدًا إلى صندوق للكلمات وصندوق للأرقام، بينما كان دمجي البسيط بالترتيب y ثم x يضع الأرقام أولًا. بعد إصلاح ذلك عبر تجميع واعٍ للأسطر (تجميع الصناديق بحسب التداخل الرأسي، ثم القراءة من اليسار إلى اليمين)، هبطت الخطوط النظيفة إلى نحو 0.04–0.10. إذا كنت تبني تقييم OCR خاصًا بك، فهذه الفخاخ تنتظرك أيضًا.
الإعداد: التثبيت صغير، لكن التبعيات ليست صغيرة

pip install easyocr
هذا هو كل شيء، والصدق هنا محدود. الحزمة نفسها بسيطة؛ لكن ما تسحبه معها هو PyTorch بحجم يقارب 2 غيغابايت. ثم عند أول استدعاء لـ readtext()، ينزّل EasyOCR أوزانه بصمت إلى ~/.EasyOCR/model/ — إجمالي 93.7 MiB، موزعة إلى 79.30 MiB لكاشف CRAFT (craft_mlt_25k.pth) و14.44 MiB لمعرّف الإنجليزية (english_g2.pth).
لا يذكر أحد هذا في الشروحات، لذا: أول تشغيل يحتاج اتصالًا بالشبكة وسيتوقف حتى يكتمل التنزيل، وأي نشر داخل حاوية إمّا يضمّن هذه الأوزان داخل الصورة أو يتحمل التنزيل عند التشغيل البارد. وبعد التخزين المؤقت، يصبح كل شيء دون اتصال.
تهيئة Reader() الباردة — تحميل النماذج من القرص إلى الذاكرة، مع خطوة التحويل إلى int8 — استغرقت 1.3–1.7 ثانية عبر عدة تشغيلات. بعد ذلك:
import easyocr
reader = easyocr.Reader(['en'], gpu=False)
result = reader.readtext('screenshot.png')
وهذا كل شيء. سطران، بلا إعدادات، بلا اختيار نموذج، بلا البحث عن checkpoint. اسم "easy" هنا مستحق فعلًا في هذه المرحلة — الاحتكاك كله في وزن التبعيات، وليس في الواجهة.
أرضية النص النظيف: أحرف شبه مثالية، لكن الحالة ليست مثالية
سبعة خطوط نظامية، أسود على أبيض، 32 بكسل، ونفس الجملة في كل مرة:
| الخط | CER (حساس لحالة الأحرف) | CER (غير حساس لحالة الأحرف) |
|---|---|---|
| Georgia | 0.0625 | 0.0000 |
| Times | 0.0417 | 0.0417 |
| Comic Sans | 0.0417 | 0.0208 |
| Arial | 0.0833 | 0.0208 |
| Verdana | 0.0833 | 0.0208 |
| Impact | 0.0833 | 0.0208 |
| Courier | 0.1042 | 0.0417 |
| المتوسط | 0.0714 | 0.0238 |
متوسط CER هو 0.071، وينخفض إلى 0.024 بمجرد تجاهل حالة الأحرف. وهذه هي الخلاصة. EasyOCR لا يفقد الأحرف على النص اللاتيني النظيف — هو يصيب الشكل ويخطئ الحالة.
بالتحديد، يعيد الكلمة الصغيرة vow على أنها VOW في ستة من أصل سبعة خطوط (وComic Sans يكتفي بـ Vow). ويضيف Impact تحويل of إلى Of أيضًا. والخطأ المتكرر الآخر هو علامات الترقيم: النقطة في نهاية الجملة تعود أحيانًا كـ : أو _ في عدة خطوط. أما Georgia فتعطي قراءة مثالية بمجرد أن تتوقف عن الاهتمام بالحالة.
وهذا نمط مفيد جدًا معرفته. إذا كانت الخطوة اللاحقة لديك هي مطابقة تقريبية، أو بحث بالكلمات المفتاحية، أو تمرير النص إلى نموذج لغوي، فإن تبديل الحالة يكلفك شيئًا شبه معدوم. أما إذا كانت الخطوة التالية مقارنة نصية دقيقة مع مفتاح قاعدة بيانات، فحينها يكلفك كل شيء. طبّق تطبيع الحالة قبل المقارنة، وستتبخر نصف نسبة الخطأ الظاهرة في EasyOCR.
كون Courier هو الأسوأ (0.1042) منطقي أيضًا: الخطوط أحادية العرض تترك مسافات غير طبيعية بين الأحرف، وهو ما يصعّب على مفكك ترميز CTC الذي تعلّم تباعد الحروف المعتاد.
عتبة الحجم تقع تمامًا حيث تقول الوثائق إنها تقع

لدى readtext() معامل موثق هو min_size=10، وهو يستبعد الصناديق المكتشفة التي يقل ارتفاعها عن 10 بكسل. معظم الناس يتجاوزونه دون انتباه. لكنه أهم رقم منفرد في الواجهة لأي شخص يعمل على استخراج النص من لقطات الشاشة أو ملفات PDF، وهذا ما يفعله عند مسح ارتفاع الحرف المرسوم:
| الارتفاع المرسوم بالبكسل | CER | ما الذي حدث |
|---|---|---|
| 8 | 0.7708 | انهيار — الصناديق تقع تحت فلتر min_size ويتم إسقاطها؛ ولا تبقى إلا أجزاء |
| 10 | 0.1458 | تدهور — عند الحد تمامًا، قسم الكاشف السطر إلى 3 صناديق |
| 12 | 0.0417 | تعافٍ |
| 16 | 0.0000 | قراءة مثالية |
| 20 | 0.0208 | نظيف |
| 28 | 0.0208 | نظيف |
| 40 | 0.0625 | نظيف (وتعود مشكلة تبديل الحالة) |
| 64 | 0.0625 | نظيف (تبديل الحالة) |
القفزة من 0.04 إلى 0.77 بين 12 بكسل و8 بكسل ليست تدهورًا تدريجيًا. إنها فلترة تفعل بالضبط ما تنص عليه، والنتيجة أن النص تحت نحو 10 بكسل يصبح فعليًا غير مرئي لـ EasyOCR الافتراضي.
النقطة المثالية هي 12–28 بكسل، مع CER كامل يساوي 0 عند 16 بكسل. فوق 40 بكسل، يرتفع CER من جديد — ليس لأن الأحرف تضيع، بل لأن تبديل vow إلى VOW يعود مرة أخرى. النص الكبير ليس أصعب قراءة؛ فقط لم يعد يستفيد من التباعد الذي جعل 16 بكسل مثاليًا.
لمن يستخرج النص من لقطات الشاشة: تحقق من ارتفاع الحروف المرسومة قبل أن تلوم النموذج. فلقطة لوحة تحكم مأخوذة بمقياس 1× على شاشة HiDPI، أو صفحة PDF رُسمت عند 72 DPI، تضع النص الأساسي غالبًا تحت 10 بكسل. التقط عند 2× أو كبّر قبل OCR، وستتجنب فئة كاملة من شكاوى "EasyOCR تجاهل نصف الصفحة". وإن لم يكن ذلك ممكنًا، فخفّض min_size — لكن توقع الضجيج، لأن الفلتر موجود أصلًا لقمع الاكتشافات غير المفيدة.
التدوير: تحمّل 10° فقط، وحلّ غير متناظر
لنبدأ بالميل. زوايا صغيرة، Arial بحجم 32 بكسل، الإعدادات الافتراضية مقابل rotation_info=[90,180,270]:
| زاوية الميل | CER (الافتراضي) | CER (مع rotation_info) |
|---|---|---|
| 0° | 0.0833 | 0.0833 |
| 5° | 0.0417 | 0.0417 |
| 10° | 0.0208 | 0.0833 |
| 15° | 0.2917 | 0.3750 |
| 20° | 0.7500 | 0.7708 |
| 30° | 0.8958 | 0.8750 |
| 45° | 0.8958 | 0.8750 |
EasyOCR الافتراضي يتعامل مع الميل حتى نحو 10° دون مشاكل كبيرة (CER ≤ 0.083)، ثم يبدأ بالاهتزاز عند 15°، ويصبح غير صالح عند 20°. rotation_info لا يفيد مع الميل، وهذا منطقي عندما تعرف ماذا يفعل — إنه يعيد المحاولة فقط عند الزوايا التي تحددها، و15° ليست 90 أو 180 أو 270. وعند 10° جعل النتيجة أسوأ قليلًا (0.021 → 0.083)، لأن إعادة المحاولة بزاوية خاطئة قد تفوز في تصويت الثقة.
أما التدويرات المتعامدة فهنا يصبح الأمر غريبًا:
| التدوير | CER (الافتراضي) | CER (مع rotation_info) | تم الاسترداد؟ |
|---|---|---|---|
| 90° | 0.8125 | 0.9167 | لا — أسوأ |
| 180° | 0.8542 | 0.6667 | جزئيًا |
| 270° | 0.8333 | 0.1042 | نعم |
نفس المعامل. نفس قائمة الزوايا. ثلاث نتائج مختلفة.
عند 270°، يفعل rotation_info تمامًا ما تعد به سلسلة القضية: ينخفض CER من 0.83 إلى 0.10، وهي قراءة صالحة فعلًا. عند 180°، ينجح جزئيًا فقط — يتحسن CER إلى 0.67، لكن العبارة my vow. تُسقط بالكامل. أما عند 90°، فالأمر يسوء، من 0.81 إلى 0.92، ويشرح المخرج الخام السبب: المعرِّف يعيد نصوصًا معكوسة. VOW تعود كـ MOA. وquartz تعود كـ zuuenb. اقرأها في مرآة وستبدو صحيحة، وهي خدعة ممتعة لكن خط أنابيب بيانات عديم الفائدة.
تحققت من هذا عبر التنبؤات الخام بدلًا من المقاييس المجمّعة، لأن "ترتيب الدمج هو الذي خلطها" كان أول ظني. لكنه ليس أثرًا ناتجًا عن الدمج — هذا ما أرجعه EasyOCR فعليًا.
الآلية هنا مجرد فرضية لا قياس؛ لم أجرِ تجربة على اتفاقية التدوير. Pillow يرسم الزوايا الموجبة عكس عقارب الساعة، لذا فقط الصورة المرسومة عند 270° تصطف صدفة مع اتجاه إعادة المحاولة الذي يتعامل معه المُعرِّف جيدًا، بينما حالة 90° يكون أفضل مسار لها مقترنًا باتجاه معكوس. أيا كانت الآلية، فالدرس التشغيلي لا يعتمد عليها:
تُظهر هذه العينات أن rotation_info لا يمكن افتراض أنه يتصرف بصورة متناظرة عبر كل الاتجاهات. تحقّق من التدويرات المتوقعة في مدخلاتك؛ واعتبار توحيد الاتجاه قبل المعالجة خيارًا مناسبًا قد يكون تخفيفًا مفيدًا، لكنه ليس شرطًا أثبته ثلاث أمثلة مرسومة.
التنبؤ الذي أخطأت فيه
دخلت التجربة وأنا أتوقع أن التباين المنخفض سيكون نقطة الضعف اللينة في EasyOCR. النص الرمادي الخافت على خلفية بيضاء هو قصة الفشل الكلاسيكية في OCR، وهناك حتى مسار إنقاذ موثق لذلك: contrast_ths=0.1 مع adjust_contrast=0.5، حيث يعيد تشغيل الصناديق منخفضة التباين بنسخة محسّنة ويحتفظ بالنتيجة الأعلى ثقة.
لكنه لم يعمل أصلًا — لأنه لم يكن بحاجة إليه.
| رمادي المقدمة | تباين Weber | CER (الافتراضي) | CER (adjust_contrast=1.0) |
|---|---|---|---|
| 0 (أسود) | 1.000 | 0.0833 | 0.0833 |
| 64 | 0.749 | 0.0833 | 0.0833 |
| 110 | 0.569 | 0.0833 | 0.0833 |
| 150 | 0.412 | 0.1042 | 0.1042 |
| 180 | 0.294 | 0.0625 | 0.0625 |
| 200 | 0.216 | 0.0417 | 0.0417 |
| 220 | 0.137 | 0.0417 | 0.0417 |
CER لا يخرج أبدًا من النطاق النظيف، حتى عند Weber 0.14 — أي الرمادي 220 على الأبيض، وهو خافت لدرجة أنني اضطررت إلى التحديق في العينة للتأكد أن النص موجود أصلًا. وعمود تحسين التباين مطابق تمامًا لعمود الافتراضي في كل خطوة، لأن الافتراضي نجح من البداية.
والخلفيات قالت القصة نفسها. النص كله باللون الأسود:
| الخلفية | CER |
|---|---|
| لوحة زرقاء فاتحة صلبة | 0.083 |
| تدرج رأسي | 0.021 |
| ضجيج Gaussian (μ200, σ22) | 0.000 |
قراءة مثالية على أكثر عينة ضجيجًا في المجموعة.
لكن النطاق هنا ضيق: نتحدث عن تباين منخفض بلون ثابت ومن دون ضجيج، وليس إيصالًا مصورًا فيه ضجيج مستشعر وضغط JPEG. في هذه المجموعة، الهندسة والرموز القصيرة سببت أكبر الإخفاقات؛ أما المتغيرات اللونية والضجيج الاصطناعي المختبر فلم تفعل.
حالة واقعية: استخراج أرقام من لقطة شاشة للوحة تحكم
هذه هي الحالة التي ينتهي إليها عمل OCR في بايثون في الغالب. يرسل لك أحدهم لقطة شاشة للوحة داخلية، أو أنت تشغّل مسار كشط بيثون على صفحة تحليلات مليئة بالرسوم البيانية حيث لا توجد الأرقام إلا كبكسلات مرسومة، وتريد القيم على هيئة بيانات.
لقد رسمت نافذة "Sales Dashboard" — رأسًا داكنًا مع عنوان وشارة دائرية بحرف، وثلاثة ألواح KPI، وثلاثة أزرار، وجدول 2×3 — ثم وسمت جميع 19 عنصرًا نصيًا بسلاسلها الدقيقة وصناديقها البكسلية، وبعدها طابقت مخرجات EasyOCR معها عبر تداخل الصناديق.
استدعاء الكاشف: 16 من 19. الإخفاقات الثلاثة كانت:
- الشارة ذات الحرف الواحد، "A"
- خلية الجدول "Q1"
- خلية الجدول "Q2"
أما "Q3" فتم اكتشافها. نفس الخط، نفس الحجم، نفس العمود — لكن الكاشف احتفظ بالرمز ذي الحرفين مرة وأسقط اثنين آخرين. كان الاكتشاف غير متسق عبر خلايا متشابهة بصريًا. وبما أن المخرجات كانت حتمية في هذه التشغيلات، فهذا ليس دليلًا على سلوك عشوائي من نوع "رمي عملة". توجد مشكلة مرتبطة بجودة اللقطة في #460.
ومن بين العناصر الـ16 التي اكتشفها، كان النص شبه مثالي: متوسط CER 0.027، مع 13 من 16 قراءة مطابقة تمامًا. العناوين، والوسوم، والأزرار ("Save"، "Cancel"، "Export CSV")، ورؤوس الأعمدة، والأرقام المفصولة بفواصل، كلها عادت بـ CER = 0. و1,284 قُرئت بشكل صحيح، بما في ذلك الفاصلة.
أما القراءات الثلاث غير المثالية فهي نفس الخطأ تمامًا. مبالغ الدولار:
| الحقيقة المرجعية | قراءة EasyOCR |
|---|---|
$57,912 | S57,912 |
$18,330 | S18,330 |
$25,178 | S25,178 |
$12,004 | $12,004 (صحيح) |
ثلاث علامات دولار من أصل أربع تحولت إلى الحرف الكبير S. وهذا، بصريًا، مفهوم — لكنه يعني أن كل حقل عملة في عملية الاستخراج الخاصة بك يبتعد حرفًا واحدًا عن العبث، وأي float() بسيط سيفشل فيها كلها.
إذا كانت سلسلة معالجة اللقطات لديك تتضمن تسميات قصيرة أو عملات، فاختبر بدائل مثل التكبير، أو القص مع حواف إضافية، أو فرض توقعات محددة على الحقول، أو معالجة لاحقة تراعي الرموز. لم أقم بقياس أي من هذه هنا، وقد يؤدي regex يبدل S الأولية إلى إفساد القيم الصحيحة. طبّق التصحيحات فقط عندما تجعلها البنية وقواعد التحقق آمنة.
ما تكلفة تشغيله
الأرقام على نفس الجهاز (macOS arm64، معالج فقط، جهاز واحد، وتم القياس تحت حمل متزامن محتمل — تعامل معها كشكل عام لا كمعيار عالمي):
| المقياس | القيمة |
|---|---|
| أوزان النموذج على القرص | 93.7 MiB (79.30 للكاشف + 14.44 للمُعرِّف) |
| الذاكرة المقيمة القصوى في عملية CPU جديدة | 984.5 MiB |
تهيئة باردة لـ Reader() | 1.3–1.7 s |
| زمن التشغيل الدافئ لسطر نظيف واحد 48 حرفًا (p50) | حوالي 0.062 s (p25–p75: 0.059–0.067 s، n=20) |
detail=0 مقابل detail=1 | متقاربان جدًا (0.062 مقابل 0.063 s كوسيط) |
الكلفة الأبرز ليست 94 MB من الأوزان — بل حوالي غيغابايت واحد من الذاكرة المقيمة لكل عملية عاملة، فوق تثبيت torch بحجم يقارب 2 GB. هذا هو الرقم الذي يحدد ما إذا كان الحل يناسب حاويتك، وهو الرقم الذي لا يذكره أحد.
السرعة جيدة للحالة السهلة. أقل من 0.1 ثانية في الحالة الدافئة لسطر واحد نظيف على المعالج أمر عملي جدًا. لكن هذه هي الحالة السهلة فعلًا: سطر قصير واحد عالي التباين. الشكاوى المتكررة من نوع "EasyOCR يستغرق عشرات الثواني على المعالج" تتعلق بوثائق كبيرة متعددة المناطق بحجم اللوحة الكامل، ولم أعد إنتاجها — حمل مختلف، وأنا أذكره بدلًا من الادعاء بعكسه.
أسطورة صغيرة يجب إنهاؤها: detail=0 لا يجعل EasyOCR أسرع. هو فقط يزيل صناديق الإحاطة ودرجات الثقة من قيمة الإرجاع. أما الحساب فقد حدث بالفعل. الوسيط يختلف بمقدار مللي ثانية تقريبًا، وهذا ضجيج.
الإيجابيات والسلبيات
الإيجابيات
- استرجاع الأحرف على النص اللاتيني المرسوم النظيف شبه مثالي — متوسط CER 0.071 مع حساسية لحالة الأحرف، و0.024 بعد تجاهل الحالة، مع إمكانية الوصول إلى CER كامل يساوي 0 عند 16 بكسل.
- واجهة فعلًا من سطرين.
Reader(['en'])ثمreadtext()، بلا إعدادات، بلا اختيار نموذج. - أكثر تحمّلًا للتباين مما يقال عادة: لا انهيار حتى Weber 0.14 على نص نظيف، والخلفيات الضبابية أو المتدرجة أو الملونة لم تضعفه (وعينة الضجيج الغاوسي كانت قراءة مثالية).
- شبه مثالي على عناصر لقطة الشاشة التي يكتشفها: متوسط CER 0.027، و13 من 16 قراءة مطابقة، بما في ذلك الأرقام المفصولة بفواصل.
- حتمي. كل رقم دقة هنا كان مطابقًا بايتًا لنتيجة تشغيلين مستقلين تمامًا؛ وحده الزمن تغيّر.
- Apache-2.0 ومستضاف ذاتيًا، بلا رسوم استخدام للمورّد؛ وتبقى كلفة التشغيل الفعلية في الحوسبة والذاكرة والتخزين والطوابير.
السلبيات
- انهيار حاد تحت عتبة
min_size=10الموثقة — CER = 0.77 عند 8 بكسل. النص الصغير في الواجهات يصبح غير مرئي افتراضيًا. - تحمّل الميل يتوقف تقريبًا عند 10° وينهار عند 20°.
rotation_infoليس حلًا متناظرًا: 270° يسترجع، 180° يسترجع جزئيًا، و90° يسوء ويعيد نصًا معكوسًا.- الكاشف يسقط الرموز القصيرة المعزولة — شارة من حرف واحد وخلّيتان من حرفين، بينما أبقى خلية ثالثة بنفس النمط.
- قراءة منهجية خاطئة من
$إلىSفي القيم المالية (3 من 4). - نحو 1 غيغابايت من الذاكرة المقيمة لكل عملية، بالإضافة إلى تبعية torch بحجم يقارب 2 غيغابايت.
- أحدث إصدار يعود إلى سبتمبر 2024؛ والمشروع أقرب إلى الاستقرار منه إلى التطور النشط.
من ينبغي أن يستخدمه، ومن الأفضل أن يبتعد عنه
قيّم EasyOCR عندما تكون مدخلاتك نظيفة، ومعتدلة الاتجاه، ونصًا مرسومًا بحجم معقول — مثل لقطات الشاشة، أو واجهات المستخدم، أو ملفات PDF المحوَّلة إلى صور، أو التقارير المولدة — وتريد خط معالجة Python مستضافًا ذاتيًا دون رسوم استخدام لمورّد. نتائج الإنجليزية التركيبية على CPU تنطبق على هذا المسار؛ أما الصور الفوتوغرافية، والكتابة اليدوية، واللغات الأخرى فتحتاج اختبارًا منفصلًا.
ابتعد عنه إذا كان أي مما يلي يصف مدخلاتك. الصور الفوتوغرافية — أرقامي تركيبية ومصنوعة بالرسم، ولا تقول شيئًا عن ضجيج الكاميرا أو المنظور أو الإضاءة. الكتابة اليدوية — المشروع نفسه لا يدّعي دعمه. النصوص غير اللاتينية — EasyOCR يدعم أكثر من 80 لغة، لكنني اختبرت لغة واحدة، والمقارنات الأكاديمية المنشورة هي المرجع هناك، لا مسحًا إنجليزيًا تركيبيًا. المدخلات ذات الدوران العشوائي — إلا إذا كنت تقوم بتصحيح الاتجاه بنفسك أولًا. النشر المحدود بالذاكرة — غيغابايت لكل عامل تتراكم بسرعة.
قبل اختيار OCR، افحص DOM واستجابات الشبكة. إذا كانت القيم المطلوبة موجودة أصلًا كنص منظم، فإن استخراجها من المصدر يتجنب أخطاء الاكتشاف والتعرّف في OCR. OCR مكانه عندما لا يتوفر سوى البكسلات.
البدائل، ومكاننا من هذه المنظومة
EasyOCR مرخّص تحت Apache-2.0 ومستضاف ذاتيًا، بلا رسوم استخدام للمورّد لكن مع تكلفة حوسبة وتشغيل حقيقية. PaddleOCR وTesseract ونماذج الرؤية-اللغة لم تُشغَّل عبر هذا الاختبار، لذلك لا يوجد هنا استنتاج مباشر بالمقارنة بينها.
لكن المقارنة الأكثر فائدة ليست OCR مقابل OCR. بل: هل يجب أن تستخدم OCR أصلًا؟
معظم أعمال استخراج اللقطات التي أراها هي التفاف على صفحة ويب يصعب كشطها — جدول يُرسم بجافاسكربت، أو لوحة خلف تسجيل دخول، أو موقع يقاوم الاستخراج. التقاط الصورة ثم تشغيل OCR يبدو طريقًا أسهل، لكنك في الحقيقة تتخلى عن نص منظم كان سليمًا، ثم تدفع "ضريبة علامة الدولار" لتسترجع نسخة أسوأ منه.
ملاحظة المؤلف: Thunderbit هو خيارنا المدار لاستخراج البيانات من صفحات الويب. لم يُشغَّل على هذه العينات الصورية. الحد الفاصل هنا هو تمثيل المصدر: استخدم استخراج DOM/network عندما توجد بيانات ويب منظمة، واختبر OCR عندما لا يتوفر سوى البكسلات.
قراءة ذات صلة من نفس منصة الاختبار: المقارنة الكاملة بين الكشّافات مفتوحة المصدر، ومراجعة Crawl4AI، ونظرة أوسع على الاستخراج المدفوع بالذكاء الاصطناعي للصفحات التي تقاوم المحددات.
جرّب Thunderbit لاستخراج بيانات الويب
الحكم النهائي
هل ينبغي استخدام EasyOCR؟ نعم، إذا كانت صورك معتدلة الاتجاه، وكانت أحرفك على الأقل بارتفاع 12 بكسل، وأنت تقرأ نصًا لاتينيًا. داخل هذه الحدود هو ممتاز جدًا — متوسط CER 0.071 على النص النظيف، و0.024 بعد تطبيع الحالة، وقراءة مثالية عند 16 بكسل، ومتانة تجاه التباين أفضل مما توحي به سمعته. والواجهة فعلًا من سطرين، والمخرجات حتمية، وهذا مهم أكثر مما يعترف الناس عندما يصححون خط أنابيب.
خارج هذه الحدود، يفشل بطرق محددة ويمكن تعلمها. النص تحت 10 بكسل يختفي داخل فلتر min_size. والميل بعد 20° يدمّر القراءة. وrotation_info يصلح اتجاهًا متعامدًا واحدًا، ويصلح الآخر جزئيًا، ويجعل الثالث أسوأ مع نص معكوس. والرموز المفردة والرموز ذات الحرفين تسقط من الكاشف بينما تبقى جيرانها. وعلامات الدولار تتحول إلى الحرف S.
إخفاقات هذه العينات جاءت من المرحلتين معًا: صناديق مفقودة أو في اتجاه خاطئ من جهة الهندسة، وارتباك علامة الدولار من جهة التعرّف. لذا تعامل مع التكبير، وتوحيد الاتجاه، والقص مع حواف إضافية، وإصلاح الرموز بحسب المخطط كمرشحين يجب التحقق منهم، لا كحلول آمنة على الإطلاق.
فقط لا تختبره بالطريقة التي كنت على وشك استخدامها أنا، أي بأداة تقييم مكسورة ورقم لا تفهمه. أنشئ عيناتك بنفسك، واعرف الحقيقة المرجعية بدقة، وابحث عن العتبة الحادة الخاصة بك.
جرّب Thunderbit لاستخراج بيانات الويب Get Started Free
الأسئلة الشائعة
هل EasyOCR دقيق بما يكفي لاستخراج النصوص من لقطات الشاشة في بيئة إنتاج؟
على لوحة التحكم التركيبية، كانت العناصر المطابقة بمتوسط CER يساوي 0.027 مع 13 من 16 قراءة مطابقة تمامًا. ثلاثة من أصل 19 عنصرًا لم تُكتشف، وثلاث علامات دولار من أصل أربع تحولت إلى S. ما إذا كان هذا مقبولًا — وما إذا كان التكبير أو الإصلاح الواعي للمخطط يساعدان — يجب اختباره على التخطيطات المستهدفة.
ما أصغر حجم خط يستطيع EasyOCR قراءته؟
عمليًا، نحو 12 بكسل من ارتفاع الحرف المرسوم. معامل readtext() المسمى min_size=10 يستبعد الصناديق التي يقل ارتفاعها عن 10 بكسل، والتأثير هنا يشبه الحافة الحادة لا المنحدر: كان CER = 0.77 عند 8 بكسل، و0.15 عند 10 بكسل، و0.04 عند 12 بكسل، و0 عند 16 بكسل. النطاق النظيف في المسح الذي أجريته كان 12–28 بكسل. إذا كان مصدرُك لقطة شاشة HiDPI مأخوذة بمقياس 1× أو ملف PDF تم تحويله إلى صورة عند 72 DPI، فكبّر قبل OCR بدلًا من خفض min_size، لأن هذا الفلتر موجود أصلًا لقمع الاكتشافات غير المفيدة.
هل يصلح rotation_info الصور الدوّارة في EasyOCR؟
ليس بشكل موثوق، وليس بشكل متناظر. مع rotation_info=[90,180,270] على ثلاث نسخ من الجملة نفسها بعد تدويرها بزاوية متعامدة، استعادَت صورة 270° نفسها بوضوح (CER من 0.83 إلى 0.10)، وصورة 180° جزئيًا فقط (0.85 إلى 0.67، مع إسقاط عبارة)، بينما أصبحت صورة 90° أسوأ (0.81 إلى 0.92) مع نص معكوس مثل VOW → MOA. كما أنه لا يفعل شيئًا للميل البسيط، لأنه يعيد المحاولة فقط عند الزوايا التي تحددها. صحّح الاتجاه قبل استدعاء EasyOCR بدل الاعتماد على هذا المعامل.
كم من الذاكرة والمساحة يحتاج EasyOCR؟
الأوزان هي 93.7 MiB، وتُنزَّل إلى ~/.EasyOCR/model/ عند أول استخدام — 79.30 MiB للكاشف و14.44 MiB لمُعرِّف الإنجليزية. الذاكرة المقيمة القصوى في عملية CPU جديدة تم قياسها كانت 984.5 MiB، فوق تثبيت torch بحجم يقارب 2 GB. التهيئة الباردة لـ Reader استغرقت 1.3–1.7 ثانية؛ ثم سطر واحد نظيف عمل بزمن p50 قريب من 0.062 ثانية على هذا الجهاز. وdetail=0 غيّر شكل المخرجات، لا زمن التنفيذ المقاس.
هل EasyOCR مجاني للاستخدام التجاري، وهل ما زال قيد الصيانة؟ هو مرخّص تحت Apache-2.0، وهي رخصة متساهلة ومناسبة تجاريًا. حتى 27 يوليو 2026، كان المستودع عند 29,825 نجمة مع 528 قضية مفتوحة، وأحدث إصدار هو v1.7.2 من سبتمبر 2024، وآخر push إلى master كان في ديسمبر 2025. اقرأ هذا على أنه مستقر أكثر منه مهجور — البنية لم تتغير منذ فترة، والنشاط انتقل إلى صفحة القضايا. تحقّق بنفسك من الرخصة الحالية ومن حالة الإصدارات قبل أن تبني عليه.


