Advanced Multi-Scale PatchMatch & AI-Powered Text Removal Engine for Manga
Project description
mangascourx
Advanced Multi-Scale PatchMatch & AI-Powered Text Removal Engine for Manga
إزالة النصوص من صور المانجا بدقة احترافية
ما هي mangascourx؟
mangascourx مكتبة Python متخصصة في إزالة النصوص والفقاعات من صور المانجا والكوميكس. تجمع بين خوارزميات كلاسيكية مُحسَّنة وتقنيات AI حديثة لتقديم نتائج احترافية جاهزة للطباعة أو إعادة الترجمة.
صورة مانجا أصلية → كشف النصوص والفقاعات → ترميم ذكي للمنطقة → صورة نظيفة
📋 المحتويات
- ✨ الميزات
- 📦 المتطلبات
- 🚀 التثبيت
- 💡 الاستخدام
- 📚 الواجهة البرمجية
- ⚡ msx_all — الاختصار الشامل
- 🏗️ البنية المعمارية
- 📝 سجل الإصدارات
- 🤝 المساهمة
✨ الميزات
🔍 كشف النصوص — طبقتان للدقة
| الطريقة | السرعة | الدقة | يحتاج AI |
|---|---|---|---|
| MSER — Maximally Stable Extremal Regions | ⚡ سريع جداً | متوسطة–عالية | ❌ لا |
| CRAFT — Character Region Awareness For Text | 🐢 أبطأ | عالية جداً | ✅ نعم |
الاختيار تلقائي: إذا أعاد MSER نتائج قليلة، تنتقل المكتبة تلقائياً إلى CRAFT.
💬 كشف فقاعات الحوار
- كشف مبني على الكنتور والمورفولوجيا
- يتعامل مع الفقاعات الدائرية والبيضاوية والمخصصة
- تنظيف الضوضاء تلقائياً قبل وبعد الكشف
🎨 ثلاث خوارزميات ترميم
| الخوارزمية | الجودة | السرعة | الاستخدام الأمثل |
|---|---|---|---|
| PatchMatch | ⭐⭐⭐⭐⭐ | ⚡⚡ متوسطة | نصوص كبيرة، مناطق معقدة |
| Telea Fast Marching | ⭐⭐⭐ | ⚡⚡⚡⚡ سريع جداً | نصوص صغيرة، معالجة سريعة |
| Coherence Transport | ⭐⭐⭐⭐ | ⚡⚡⚡ سريع | الخطوط والعناصر الهندسية |
⚡ الأداء
- تسريع JIT عبر Numba (اختياري لكن موصى به)
- معالجة متوازية
prangeللصور الكبيرة - هرم متعدد المستويات (Gaussian Pyramid) لدقة عالية
- Fallback تلقائي إذا لم يكن Numba مثبتاً
📦 المتطلبات
Python >= 3.8
# أساسي
numpy >= 1.20.0
opencv-python-headless >= 4.5.0
scipy >= 1.7.0
# لتسريع الأداء (موصى به بشدة)
numba >= 0.53.0
# لكشف CRAFT (اختياري)
torch >= 1.9.0
torchvision >= 0.10.0
🚀 التثبيت
من PyPI
pip install mangascourx
إصدار محدد
pip install mangascourx==1.0.5
من GitHub
pip install git+https://github.com/zxui86/mangascourx.git
من المصدر
git clone https://github.com/zxui86/mangascourx.git
cd mangascourx
pip install -e .
التحقق من التثبيت
import mangascourx
print(mangascourx.__version__) # 1.0.5
💡 الاستخدام
1. الحالة الأبسط — خط أنابيب كامل
import cv2
from mangascourx import TextRemovePipeline
image = cv2.imread("manga_page.jpg")
pipeline = TextRemovePipeline(
inpainting_method="patchmatch", # "patchmatch" | "telea"
patch_size=7,
)
result = pipeline.run(image)
cv2.imwrite("cleaned.jpg", result["result"])
# result["result"] — الصورة بعد الإزالة
# result["mask"] — القناع الثنائي
# result["text_detected"] — True إذا وُجد نص
2. خط الأنابيب الكامل مع تبييض الخلفية
from mangascourx import MangaCleanPipeline
pipeline = MangaCleanPipeline(
inpainting_method="patchmatch",
patch_size=7,
denoise_level=3, # تقليل الضوضاء قبل المعالجة
whiten_background=True # تبييض ذكي للصفحات القديمة
)
output = pipeline.run(image)
cv2.imwrite("final.jpg", output["final_page"])
# output["final_page"] — الصورة النهائية النظيفة
# output["mask"] — القناع المستخدم
# output["text_removed"] — True إذا أُزيل نص
3. التحكم الكامل في كل مرحلة
from mangascourx.detection import DetectionOrchestrator
from mangascourx.inpainting import PatchMatchInpainter
# ─── كاشف مخصص ───────────────────────────────────
detector = DetectionOrchestrator(
mser_params={
"delta": 5,
"min_area": 60,
"max_area": 14400,
},
bubble_params={
"block_size": 31,
"morph_open": 3,
"morph_close": 5,
},
merge_priority=["text", "bubbles"],
final_cleanup=True,
fallback_min_boxes=3,
)
# ─── كشف النصوص والفقاعات ─────────────────────────
detection = detector.run(image, enable_text=True, enable_bubbles=True)
mask = detection["mask"] # القناع الموحد
text_boxes = detection["text_boxes"] # [(x, y, w, h), ...]
bubble_boxes = detection["bubble_boxes"] # [(x, y, w, h), ...]
# ─── ترميم مخصص ──────────────────────────────────
inpainter = PatchMatchInpainter(
patch_size=9,
iterations=5,
knn=3,
use_rotation=True,
use_scale=True,
use_coherence=True,
verbose=True,
)
result = inpainter.run(image, mask)
4. معاينة النتائج المرحلية
import cv2
import numpy as np
detection = detector.run(image)
stages = {
"original": image,
"unified_mask": detection["mask"],
"text_mask": detection.get("text_mask", np.zeros(image.shape[:2], np.uint8)),
"bubble_mask": detection.get("bubble_mask", np.zeros(image.shape[:2], np.uint8)),
}
for name, img in stages.items():
cv2.imwrite(f"debug_{name}.jpg", img)
5. معالجة دفعة من الصور
import os, cv2
from mangascourx import TextRemovePipeline
pipeline = TextRemovePipeline(inpainting_method="telea") # telea أسرع للدفعات
for filename in os.listdir("input/"):
if filename.lower().endswith((".jpg", ".png", ".webp")):
img = cv2.imread(f"input/{filename}")
out = pipeline.run(img)
cv2.imwrite(f"output/{filename}", out["result"])
print(f"✓ {filename}")
📚 الواجهة البرمجية
TextRemovePipeline
from mangascourx import TextRemovePipeline
pipeline = TextRemovePipeline(
merge_priority=["text", "bubbles"], # أولوية دمج القنوات
patch_size=7, # حجم رقعة PatchMatch
inpainting_method="patchmatch", # "patchmatch" | "telea"
)
output = pipeline.run(image)
# output["result"] → NDArray[uint8]
# output["mask"] → NDArray[uint8]
# output["text_detected"] → bool
# output["meta"] → dict (إذا وُجد نص)
MangaCleanPipeline
from mangascourx import MangaCleanPipeline
pipeline = MangaCleanPipeline(
inpainting_method="patchmatch",
patch_size=7,
denoise_level=0, # 0 = بدون denoising، 1–10 = شدة التنظيف
whiten_background=True, # تبييض تكيفي للخلفية
)
output = pipeline.run(image)
# output["final_page"] → NDArray[uint8]
# output["mask"] → NDArray[uint8]
# output["text_removed"] → bool
DetectionOrchestrator
from mangascourx.detection import DetectionOrchestrator
detector = DetectionOrchestrator(
craft_model_path=None, # مسار نموذج CRAFT (.pth) أو None
device="cpu", # "cpu" | "cuda" | "cuda:0"
mser_params=None, # dict لتخصيص MSER
craft_params=None, # dict لتخصيص CRAFT
bubble_params=None, # dict لتخصيص كشف الفقاعات
merge_priority=["text", "bubbles"], # ترتيب الأولوية عند التداخل
final_cleanup=True, # تنظيف مورفولوجي نهائي
fallback_min_boxes=3, # حد الانتقال من MSER إلى CRAFT
)
# الاستدعاء الرئيسي
result = detector.run(image, enable_text=True, enable_bubbles=True)
# أو بالاسم البديل:
result = detector.detect(image, enable_text=True, enable_bubbles=True)
# المخرجات:
# result["mask"] → NDArray[uint8] — القناع الموحد
# result["text_mask"] → NDArray[uint8] — قناع النصوص فقط
# result["bubble_mask"] → NDArray[uint8] — قناع الفقاعات فقط
# result["text_boxes"] → list[(x,y,w,h)] — مربعات النصوص
# result["bubble_boxes"] → list[(x,y,w,h)] — مربعات الفقاعات
# result["priority"] → list[str]
خوارزميات الترميم
PatchMatchInpainter — الأعلى جودةً
from mangascourx.inpainting import PatchMatchInpainter
inpainter = PatchMatchInpainter(
patch_size=7, # حجم الرقعة (7–15 مناسب للمانجا)
pyramid_levels=5, # عدد مستويات هرم الصورة
iterations=6, # عدد التكرارات لكل مستوى
knn=3, # عدد أقرب الجيران
random_decay=0.5, # معدل تقليص نطاق البحث العشوائي
use_rotation=True, # السماح بالتطابق بعد الدوران
use_scale=True, # السماح بالتطابق بعد تغيير الحجم
use_coherence=True, # بحث الاتساق بين البكسلات المجاورة
use_bidirectional=True, # تحسين بالاتجاهين
use_features=False, # استخدم التدرجات كميزات إضافية
seed=None, # بذرة للنتائج القابلة للتكرار
verbose=False,
)
result = inpainter.run(image, mask) # → NDArray[uint8]
TeleaInpainter — الأسرع
from mangascourx.inpainting import TeleaInpainter
inpainter = TeleaInpainter(radius=5)
result = inpainter.run(image, mask) # → NDArray[uint8]
CoherenceTransport — للخطوط الهندسية
from mangascourx.inpainting import CoherenceTransport
inpainter = CoherenceTransport(iterations=3, step_size=0.25)
result = inpainter.run(image, mask) # → NDArray[uint8]
أدوات المورفولوجيا والكنتور
from mangascourx.detection.bubbles.morphology import (
clean_noise, dilate, erode, open_mask, close_mask, improve_mask
)
from mangascourx.detection.bubbles.contours import (
detect_bubbles, find_contours, filter_contours_by_area,
draw_contours, draw_bounding_rects
)
from mangascourx.detection.text.mser import detect_text_regions
from mangascourx.detection.mask import process_masks, merge_labeled, cleanup_mask
⚡ msx_all — الاختصار الشامل
في v1.0.5 أضفنا msx_all، ملف واحد يستورد كل دوال وكلاسات المكتبة دفعة واحدة:
import mangascourx.msx_all as msx
# بدلاً من استيرادات متعددة من مسارات مختلفة:
msx.TextRemovePipeline()
msx.MangaCleanPipeline()
msx.DetectionOrchestrator()
msx.PatchMatchInpainter()
msx.TeleaInpainter()
msx.CoherenceTransport()
# كشف النصوص
msx.detect_text_regions(image)
msx.create_mser(delta=5, min_area=60)
msx.non_max_suppression(boxes, overlap_threshold=0.5)
msx.CRAFTDetector("weights.pth", device="cpu")
# كشف الفقاعات
msx.detect_bubbles(binary_mask)
msx.find_contours(mask)
msx.filter_contours_by_area(contours, min_area=100)
msx.draw_contours(image, contours)
msx.draw_bounding_rects(image, rects)
# مورفولوجيا
msx.clean_noise(mask, open_kernel_size=3, close_kernel_size=5)
msx.dilate(mask, kernel_size=3)
msx.erode(mask, kernel_size=3)
msx.open_mask(mask, kernel_size=3)
msx.close_mask(mask, kernel_size=3)
msx.improve_mask(mask, blur_ksize=3)
# دمج الأقنعة
msx.process_masks({"text": t_mask, "bubbles": b_mask}, priority=["text", "bubbles"])
msx.merge_labeled(masks_dict, priority=["text", "bubbles"])
msx.cleanup_mask(mask)
# أدوات SWT
msx.stroke_width_transform(gray_image)
msx.swt_to_mask(swt_map)
msx.detect_text_swt(image)
# رياضيات الأساس
msx.PriorityQueue(capacity=10000)
msx.euclidean_distance_transform(mask)
msx.connected_components(binary_mask)
msx.structure_tensor(gray)
msx.perona_malik_diffusion(image)
msx.curvature_diffusion(image)
# إصدار
print(msx.__version__) # 1.0.5
ملاحظة:
msx_allمفيد للتجربة السريعة والاستكشاف. في الإنتاج يُفضَّل الاستيراد المباشر من المسار الكامل لوضوح الكود.
🏗️ البنية المعمارية
mangascourx/ ← حزمة Python الرئيسية
│
├── __init__.py ← TextRemovePipeline, MangaCleanPipeline
├── _version.py ← "1.0.5"
├── manga_clean.py ← MangaCleanPipeline + تبييض تكيفي
├── text_remove.py ← TextRemovePipeline (خط الأنابيب)
├── msx_all.py ⭐NEW ← كل الدوال في ملف واحد
│
├── detection/
│ ├── detection.py ← DetectionOrchestrator (المنسق)
│ ├── mask.py ← merge_labeled, process_masks
│ ├── base.py ← BaseDetector (واجهة كاشفات)
│ │
│ ├── bubbles/
│ │ ├── contours.py ← detect_bubbles, find_contours
│ │ └── morphology.py ← clean_noise, dilate, erode
│ │
│ └── text/
│ ├── mser.py ← detect_text_regions (MSER)
│ ├── craft_adapter.py ← CRAFTDetector (AI)
│ └── swt.py ← stroke_width_transform
│
├── inpainting/
│ ├── base.py ← Inpainter + _find_boundary + _propagate
│ ├── telea.py ← TeleaInpainter (Fast Marching)
│ ├── coherence.py ← CoherenceTransport
│ └── patchmatch/
│ ├── core.py ← NNF, patch ops, transforms (Numba JIT)
│ ├── engine.py ← PatchMatchInpainter (المحرك)
│ └── propagation.py ← initialize_nnf, propagate, random_search
│
└── core/
├── distance.py ← euclidean_distance_transform
├── components.py ← connected_components, UnionFind
├── tensor.py ← structure_tensor
├── diffusion.py ← perona_malik, curvature_diffusion
├── priority_queue.py ← PriorityQueue (min-heap)
└── etf.py ← Edge Tangent Flow (مستقبلي)
📊 مسار البيانات
cv2.imread() → uint8 BGR Array
│
├──► DetectionOrchestrator.run()
│ │
│ ├──► MSER / CRAFT → text_mask (binary 0/255)
│ ├──► Bubble Seg → bubble_mask (binary 0/255)
│ └──► process_masks → final_mask (binary 0/255)
│
└──► Inpainter.run(image, final_mask)
│
├──► PatchMatch → multi-level NNF search → reconstruct
├──► Telea → Fast Marching → propagate
└──► Coherence → structure tensor → transport
│
└──► uint8 result
📝 سجل الإصدارات
🆕 v1.0.5 — "Package Architecture Edition"
تاريخ الإصدار: يونيو 2025 الأهمية: إصلاح بنيوي شامل — هذا الإصدار هو أول نسخة تعمل فعلياً بعد التثبيت
المشكلة الجذرية
كانت جميع ملفات المشروع مبعثرة في جذر الريبو مباشرة بدلاً من أن تكون داخل مجلد mangascourx/:
# الوضع الخاطئ (v1.0.4 وما قبله):
repo/
├── core/ ← في الجذر مباشرة!
├── detection/ ← في الجذر مباشرة!
├── inpainting/ ← في الجذر مباشرة!
└── setup.py
# الوضع الصحيح (v1.0.5):
repo/
├── setup.py
└── mangascourx/ ← الحزمة الفعلية
├── core/
├── detection/
└── inpainting/
هذا جعل pip install mangascourx ينصّب حزمة فارغة، وأي import mangascourx يفشل فوراً.
الإصلاحات الكاملة
| # | الملف | المشكلة | الإصلاح |
|---|---|---|---|
| 1 | البنية كلها | الملفات في جذر الريبو لا داخل mangascourx/ |
إعادة هيكلة كاملة |
| 2 | detection/detection.py |
from .masks import — الملف اسمه mask.py |
from .mask import |
| 3 | detection/detection.py |
الكلاس Detector لكن text_remove.py يستورد DetectionOrchestrator |
إعادة تسمية + alias للتوافق |
| 4 | detection/detection.py |
بدون .run() — وtext_remove.py يستدعي .run() |
أضفنا run() يستدعي detect() |
| 5 | detection/detection.py |
detect_text_regions(image, **self.mser_params) خاطئ |
detect_text_regions(image, mser_params=self.mser_params) |
| 6 | inpainting/base.py |
غير موجود — telea.py وcoherence.py يستوردانه |
إنشاء من صفر |
| 7 | inpainting/base.py |
_find_boundary() و_propagate() غير معرَّفتان |
نقلهما إلى Inpainter base |
| 8 | inpainting/patchmatch/engine.py |
@njit داخل method بدون استيراد |
أضفنا import مع fallback |
| 9 | inpainting/patchmatch/propagation.py |
from numba import بدون try/except |
أضفنا الـ fallback |
| 10 | setup.py |
مسار _version.py نسبي يعتمد على CWD |
os.path.abspath() |
ملفات __init__.py المفقودة (5 ملفات)
mangascourx/__init__.py ← أُنشئ
mangascourx/detection/__init__.py ← أُنشئ
mangascourx/detection/text/__init__.py ← أُنشئ
mangascourx/inpainting/__init__.py ← أُنشئ
mangascourx/inpainting/patchmatch/__init__.py ← أُنشئ
الإضافة الجديدة
- ✅
mangascourx/msx_all.py— ملف اختصار يستورد كل دوال وكلاسات المكتبة
v1.0.4
- تحسينات في أداء PatchMatch
- إصلاحات بسيطة في MSER
v1.0.3
- إضافة CoherenceTransport
- تحسين واجهة MangaCleanPipeline
v1.0.2
- إضافة CRAFT adapter
- تحسين عملية دمج الأقنعة
v1.0.1
- PatchMatch multi-scale pyramid
- إضافة Telea inpainter
v1.0.0
- الإطلاق الأول
- MSER + PatchMatch الأساسي
🔧 استكشاف الأخطاء
ModuleNotFoundError: No module named 'mangascourx'
# تأكد من التثبيت الصحيح
pip install --force-reinstall mangascourx==1.0.5
# أو من المصدر
pip install -e .
ImportError بعد التثبيت
# امسح الكاش
find . -name "__pycache__" -type d -exec rm -r {} +
pip cache purge
pip install --no-cache-dir mangascourx
numba بطيء أول استدعاء
هذا طبيعي — Numba يقوم بتجميع الكود في أول تشغيل (JIT compilation). من المرة الثانية سيكون سريعاً.
CRAFT لا يعمل
# CRAFT يحتاج torch وملف الأوزان
detector = DetectionOrchestrator(
craft_model_path="path/to/craft_mlt_25k.pth",
device="cpu", # أو "cuda"
)
# إذا لم يكن CRAFT متاحاً، سيستخدم MSER تلقائياً
🤝 المساهمة
- Fork المستودع
git checkout -b feature/your-featuregit commit -m "Add: your feature"git push origin feature/your-feature- افتح Pull Request
أدوات التطوير
pip install -e ".[dev]"
pytest tests/
flake8 mangascourx/
black mangascourx/
📄 الترخيص
هذا المشروع مرخص تحت MIT License.
👤 المؤلف
- GitHub: @zxui86
- Email: zly30257@gmail.com
- Issues: github.com/zxui86/mangascourx/issues
🗺️ الخارطة المستقبلية
- نموذج AI خاص للمانجا (Manga-specific text detector)
- دعم الفيديو وملفات CBZ/CBR
- واجهة سطر أوامر
mangascourx clean input.jpg - معالجة GPU كاملة (CUDA-native PatchMatch)
- توثيق تفاعلي مع أمثلة مرئية
mangascourx v1.0.5 — مستقر ✅
آخر تحديث: يونيو 2025
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mangascourx-1.0.5.tar.gz.
File metadata
- Download URL: mangascourx-1.0.5.tar.gz
- Upload date:
- Size: 48.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.20
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d680fe63d2e53b80c611acc1025987fa80459c93580fd30c2ecc1177ae0e55dc
|
|
| MD5 |
dbbe730cacb5f7e2b8be2a774a0fe788
|
|
| BLAKE2b-256 |
599401a400366a0bf46098ee4c00f255ccffb5f2b48e4a7f68bb2dee8f280e3b
|
File details
Details for the file mangascourx-1.0.5-py3-none-any.whl.
File metadata
- Download URL: mangascourx-1.0.5-py3-none-any.whl
- Upload date:
- Size: 52.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.20
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a1d7ca1634d548571bb07944cc42ef8ea3edd7403713ce0dcc84d95d6c7969c1
|
|
| MD5 |
6cfc4d7fde0f7c456e1864f74dbb6f50
|
|
| BLAKE2b-256 |
66619047a44f392fc308cfb37d3c174d11ec3cfa9e265dad54d43fb675ab26a5
|