|
|
🛠️ How to use it
from transformers import Qwen2_5_VLForConditionalGeneration, AutoProcessor
import torch
from PIL import Image
from typing import List, Dict
import os
def process_vision_info(messages: List[dict]):
image_inputs = []
video_inputs = []
for message in messages:
if isinstance(message["content"], list):
for item in message["content"]:
if item["type"] == "image":
image = item["image"]
if isinstance(image, str):
# Open image with quality improvement
image = Image.open(image).convert("RGB")
elif isinstance(image, Image.Image):
pass
else:
raise ValueError(f"Unsupported image type: {type(image)}")
image_inputs.append(image)
elif item["type"] == "video":
video_inputs.append(item["video"])
return image_inputs if image_inputs else None, video_inputs if video_inputs else None
model_name = "sherif1313/Arabic-handwritten-OCR-4bit-Qwen2.5-VL-3B-v3"
model = Qwen2_5_VLForConditionalGeneration.from_pretrained(
model_name,
dtype=torch.bfloat16,
device_map="auto",
trust_remote_code=True
)
processor = AutoProcessor.from_pretrained(
model_name,
trust_remote_code=True
)
def extract_text_from_image(image_path):
try:
# ✅ Use clearer prompt that requests the complete text
messages = [
{
"role": "user",
"content": [
{"type": "image", "image": image_path},
{"type": "text", "text": "ارجو استخراج النص العربي كاملاً من هذه الصورة من البداية الى النهاية بدون اي اختصار ودون ذيادة او حذف. اقرأ كل المحتوى النصي الموجود في الصورة:"},
],
}
]
# Prepare text and images
text = processor.apply_chat_template(
messages, tokenize=False, add_generation_prompt=True
)
image_inputs, video_inputs = process_vision_info(messages)
# Process inputs with improved settings
inputs = processor(
text=[text],
images=image_inputs,
padding=True,
return_tensors="pt",
).to(model.device)
# ✅ Improved generation settings for long texts
generated_ids = model.generate(
**inputs,
max_new_tokens=512, # Significant increase to accommodate long texts 1024
min_new_tokens=50, # Minimum to ensure no premature truncation
do_sample=False, # For consistent results
temperature=0.1, # Balance between creativity and stability 0.3
top_p=0.1, # For moderate diversity 0.9
repetition_penalty=1.1, # Prevent repetition
pad_token_id=processor.tokenizer.eos_token_id,
eos_token_id=processor.tokenizer.eos_token_id,
num_return_sequences=1
)
# Extract only the generated text (without user prompt)
input_len = inputs.input_ids.shape[1]
output_text = processor.batch_decode(
generated_ids[:, input_len:],
skip_special_tokens=True,
clean_up_tokenization_spaces=True # Improve spacing
)[0]
return output_text.strip()
except Exception as e:
return f"Error occurred while processing image: {str(e)}"
def enhance_image_quality(image_path):
"""Enhance image quality to improve OCR accuracy"""
try:
img = Image.open(image_path)
# Increase resolution if image is small
if max(img.size) < 800:
new_size = (img.size[0] * 2, img.size[1] * 2)
img = img.resize(new_size, Image.Resampling.LANCZOS)
return img
except:
return Image.open(image_path)
if __name__ == "__main__":
TEST_IMAGES_DIR = "/media/imges" # Replace with your folder image path
IMAGE_EXTENSIONS = ['.png', '.jpg', '.jpeg', '.tif', '.tiff']
image_files = [
os.path.join(TEST_IMAGES_DIR, f)
for f in os.listdir(TEST_IMAGES_DIR)
if any(f.lower().endswith(ext) for ext in IMAGE_EXTENSIONS)
]
if not image_files:
print("❌ No images found in the folder.")
exit()
print(f"🔍 Found {len(image_files)} images for processing")
for img_path in sorted(image_files):
print(f"\n{'='*50}")
print(f"🖼️ Processing: {os.path.basename(img_path)}")
print(f"{'='*50}")
try:
# ✅ Use the enhanced function
extracted_text = extract_text_from_image(img_path)
print("📝 Extracted text:")
print("-" * 40)
print(extracted_text)
print("-" * 40)
# ✅ Calculate text length for comparison
text_length = len(extracted_text)
print(f"📊 Text length: {text_length} characters")
except Exception as e:
print(f"❌ Error processing {os.path.basename(img_path)}: {e}")
🌍 Scientific Discovery: "Dynamic Equilibrium Theorem"
During training, we discovered a fundamental mathematical phenomenon architectures.
Characteristics of this state:
Eval Loss stabilizes at 0.415 ± 0.001
Train Loss adapts dynamically to batch difficulty
Generalization becomes independent of training fluctuations
Model achieves maximum predictive accuracy with minimum resource usage
This discovery represents a new theoretical benchmark for optimal model training and has been verified across multiple Arabic OCR datasets.
Theoretical Foundation:
"Dynamic Equilibrium in Models: The 5.34% Golden Ratio".
🚀 Applications
Academic & Research
- Digital Archives: Convert historical Arabic manuscripts to searchable text.
- Linguistic Research: Analyze the evolution of Arabic handwriting styles.
- Educational Tools: Digitize handwritten student work and notes.
- Cultural Preservation: Preserve endangered manuscripts and documents.
Commercial & Government
- Government Services: Process handwritten forms and applications.
- Banking: Process handwritten checks and financial documents.
- Healthcare: Digitize handwritten medical records and prescriptions.
- Business: Automate invoice processing and handwritten record digitization.
⚠️ Limitations & Ethical Guidelines
Technical Limitations
- Image Quality: Requires minimum 200 DPI for optimal performance.
- Handwriting Styles: Best on clear, standard handwriting; may struggle with extremely irregular personal styles.
- Document Types: Optimized for text documents; not designed for forms with complex layouts.
- Lighting Conditions: Performance degrades under poor lighting or heavy shadows.
Ethical Use Requirements
- Privacy: Never process documents containing personal data without explicit consent.
- Copyright: Respect copyright laws when digitizing historical documents.
- Transparency: Always disclose when OCR output is machine-generated.
- Accuracy Verification: Human verification required for legal/medical documents.
🙏 Acknowledgments
- Qwen Team for the exceptional base model.
- Hugging Face for the transformative platform.
- Dataset Contributors from Muharaf, KHATT, and Everyone who participated with data.
Responsible Disclosure
If you discover errors, biases, or security vulnerabilities, please report them at message