mrz-reader-api / app.py
Mahmoud-Bayoumi0's picture
Upload 2 files
5355d14 verified
from flask import Flask, request, jsonify
from flask_cors import CORS
from passporteye import read_mrz
from PIL import Image
import numpy as np
import cv2
import io
import base64
import json
from datetime import datetime
app = Flask(__name__)
# تفعيل CORS للسماح للفرونت إند بالوصول للباك إند
CORS(app, resources={r"/api/*": {"origins": "*"}})
def crop_mrz_region(image):
"""قص منطقة MRZ تلقائياً (الـ 35% السفلي من الصورة)"""
img_array = np.array(image)
height, width = img_array.shape[:2]
mrz_height = int(height * 0.35)
y_start = height - mrz_height
cropped = img_array[y_start:height, :]
return Image.fromarray(cropped)
def enhance_mrz_image(image):
"""تحسين جودة صورة MRZ باستخدام OpenCV"""
img_array = np.array(image)
# تحويل لرمادي
if len(img_array.shape) == 3:
gray = cv2.cvtColor(img_array, cv2.COLOR_RGB2GRAY)
else:
gray = img_array
# تقليل الضوضاء
denoised = cv2.fastNlMeansDenoising(gray)
# تحسين التباين
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
enhanced = clahe.apply(denoised)
# تحويل لصورة ثنائية (Black & White) لسهولة القراءة
_, binary = cv2.threshold(enhanced, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
return Image.fromarray(binary)
def image_to_base64(image):
"""تحويل الصورة إلى نص Base64 للعرض في المتصفح"""
# تصغير الصورة قليلاً لتسريع النقل إذا كانت ضخمة
max_size = 800
if max(image.size) > max_size:
image.thumbnail((max_size, max_size), Image.Resampling.LANCZOS)
buffered = io.BytesIO()
image.save(buffered, format="PNG")
img_str = base64.b64encode(buffered.getvalue()).decode()
return img_str
@app.route('/api/process-passport', methods=['POST'])
def process_passport():
try:
if 'image' not in request.files:
return jsonify({'success': False, 'error': 'لم يتم استلام صورة'}), 400
file = request.files['image']
image = Image.open(file.stream).convert('RGB')
# 1. قص منطقة الـ MRZ
mrz_cropped = crop_mrz_region(image)
# 2. تحسين الصورة
mrz_enhanced = enhance_mrz_image(mrz_cropped)
# 3. حفظ في Buffer للقراءة بواسطة PassportEye
img_buffer = io.BytesIO()
mrz_enhanced.save(img_buffer, format='PNG')
img_buffer.seek(0)
# 4. استخراج البيانات
start_time = datetime.now()
mrz = read_mrz(img_buffer)
processing_time = (datetime.now() - start_time).total_seconds()
if mrz is None:
return jsonify({'success': False, 'error': 'فشل في قراءة منطقة MRZ. حاول تصوير منطقة السطرين السفليين بوضوح.'}), 422
mrz_data = mrz.to_dict()
mrz_data['walltime'] = processing_time
# 5. تجهيز الصور للفرونت إند
images_response = {
'original': image_to_base64(image),
'cropped': image_to_base64(mrz_cropped),
'enhanced': image_to_base64(mrz_enhanced)
}
return jsonify({
'success': True,
'data': mrz_data,
'images': images_response
})
except Exception as e:
print(f"Error: {str(e)}")
return jsonify({'success': False, 'error': str(e)}), 500
if __name__ == '__main__':
# استخدام المنفذ الذي توفره المنصة أو 7860 (الافتراضي لـ Hugging Face)
import os
port = int(os.environ.get('PORT', 7860))
app.run(host='0.0.0.0', port=port)