Spaces:
No application file
No application file
| from flask import Flask, jsonify | |
| from flask_socketio import SocketIO | |
| import cv2 | |
| import mediapipe as mp | |
| import numpy as np | |
| import tensorflow as tf | |
| import joblib | |
| import base64 | |
| import os | |
| from io import BytesIO | |
| from PIL import Image | |
| app = Flask(__name__) | |
| socketio = SocketIO(app, cors_allowed_origins="*") # السماح لكل origins | |
| # تحميل النموذج | |
| interpreter = tf.lite.Interpreter(model_path="sign_language_model.tflite") | |
| interpreter.allocate_tensors() | |
| input_details = interpreter.get_input_details() | |
| output_details = interpreter.get_output_details() | |
| # تحميل Scaler و LabelEncoder | |
| scaler = joblib.load("scaler.save") | |
| label_encoder = joblib.load("label_encoder.pkl") | |
| id_to_word = { | |
| 1: "اتنين", 2: "احبك", 3: "اربعه", 4: "الاب", 5: "الام", 6: "بعيد", 7: "هاتف", 8: "تلاتة", | |
| 9: "جدة", 10: "حب", 11: "خارج", 12: "جمسة", 13: "داخل", 14: "سبعة", 15: "ستة", 16: "شكرا", | |
| 17: "صديق", 18: "صفر", 19: "صم", 20: "طفل", 21: "قريب", 22: "مدرسة", 23: "مرحبا", 24: "مش موفق", | |
| 25: "من فضلك", 26: "موافق", 27: "هنا", 28: "هناك", 29: "واحد", 30: "يسار", 31: "يمين",32: "امطار", | |
| 33: "رمال او صحراء", | |
| 34: "كاس", | |
| 35: "مخدة", | |
| 36: "وادي", | |
| 37: "شوكة", | |
| 38: "صم", | |
| 39: "طبق", | |
| 40: "كاميرا", | |
| 41: "كهرباء", | |
| 42: "حفلة", | |
| 43: "مطبخ", | |
| 44: "نهر", | |
| 45: "منشفة", | |
| 46: "معلقة", | |
| 47: "سلك كهرباء", | |
| 48: "سكينة", | |
| 49: "صفر", | |
| 50: "وحد", | |
| 51: "اتنين", | |
| 52: "تلاتة", | |
| 53: "اربعة", | |
| 54: "خمسة", | |
| 55: "ستة", | |
| 56: "سبعة", | |
| 57: "ثمانية", | |
| 58: "تسعة", | |
| 59: "مرتفع", | |
| 60: "الشتاء", | |
| 61: "الصيف", | |
| 62: "تجميد", | |
| 63: "كلية العلوم", | |
| 64: "كل شي", | |
| 65: "ربما", | |
| 66: "امتحان", | |
| 67: "ناجح", | |
| 68: "راسب", | |
| 69: "شعاع", | |
| 70: "مثلث", | |
| 71: "ضرب", | |
| 72: "جمع", | |
| 73: "اصغر من", | |
| 74: "اكبر من", | |
| 75: "الحمدالله", | |
| 76: "الملاكمة", | |
| 77: "عضلة", | |
| 78: "جمجمة", | |
| 79: "قفص صدري", | |
| 80: "قصبة هوائية", | |
| 81: "جهاز تنفسي", | |
| 82: "كبد", | |
| 83: "قلب", | |
| 84: "جهز عصبي", | |
| 85: "فحص نظر", | |
| 86: "التهاب اسنان", | |
| 87: "صداع", | |
| 88: "حساسية", | |
| 89: "مرهم", | |
| 90: "اعاقة بصرية", | |
| 91: "اهلا وسهلا", | |
| 92: "تعا اشرب شاي", | |
| 93: "كوخ يا حبيبي", | |
| 94: "ابدا", | |
| 95: "الم", | |
| 96: "بيت", | |
| 97: "اقف بروح امك", | |
| 98: "هضمي", | |
| 99: "قسمة", | |
| 100: "كلية هندسة", | |
| 101: "معهد تمريض", | |
| 102: "زواج" | |
| } | |
| mp_hands = mp.solutions.hands | |
| hands = mp_hands.Hands(static_image_mode=True, max_num_hands=2, min_detection_confidence=0.5) | |
| def decode_base64_image(base64_str): | |
| image_data = base64.b64decode(base64_str) | |
| image = Image.open(BytesIO(image_data)) | |
| return cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR) | |
| def handle_prediction(data): | |
| try: | |
| img_b64 = data.get("image") | |
| frame = decode_base64_image(img_b64) | |
| frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) | |
| result = hands.process(frame_rgb) | |
| data_aux = [] | |
| if result.multi_hand_landmarks: | |
| for hand_landmarks in result.multi_hand_landmarks[:2]: | |
| x_ = [lm.x for lm in hand_landmarks.landmark] | |
| y_ = [lm.y for lm in hand_landmarks.landmark] | |
| z_ = [lm.z for lm in hand_landmarks.landmark] | |
| for lm in hand_landmarks.landmark: | |
| data_aux.append(lm.x / max(x_)) | |
| data_aux.append(lm.y / max(y_)) | |
| data_aux.append(lm.z / max(z_)) | |
| while len(data_aux) < 126: | |
| data_aux.append(0.0) | |
| if len(data_aux) == 126: | |
| input_data = scaler.transform([np.asarray(data_aux)]).astype(np.float32) | |
| interpreter.set_tensor(input_details[0]['index'], input_data) | |
| interpreter.invoke() | |
| output_data = interpreter.get_tensor(output_details[0]['index']) | |
| predicted_index = int(np.argmax(output_data[0])) | |
| confidence = float(np.max(output_data[0])) | |
| if confidence > 0.5: | |
| predicted_label = label_encoder.inverse_transform([predicted_index])[0] | |
| text = id_to_word.get(int(predicted_label), predicted_label) | |
| socketio.emit('prediction_result', {"prediction": text, "confidence": confidence}) | |
| return | |
| socketio.emit('prediction_result', {"prediction": None, "confidence": 0.0}) | |
| except Exception as e: | |
| socketio.emit('prediction_result', {"error": str(e)}) | |
| def index(): | |
| return " WebSocket API جاهز! أرسل حدث 'predict_image' مع Base64." | |
| if __name__ == '__main__': | |
| port = int(os.environ.get("PORT", 5000)) | |
| socketio.run(app, host="0.0.0.0", port=port) | |