Spaces:
Sleeping
Sleeping
| 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 | |
| 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) |