EngReem85 commited on
Commit
b691765
·
verified ·
1 Parent(s): 33c38b4

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +103 -0
app.py ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import numpy as np
3
+ import tensorflow as tf
4
+ import cv2
5
+ from tensorflow.keras import datasets
6
+
7
+ # ============================================
8
+ # 1. تحميل النموذج المحفوظ (تأكد من وجوده في نفس المجلد)
9
+ # ============================================
10
+ model = tf.keras.models.load_model('mnist_cnn_model.keras')
11
+ print("✅ تم تحميل النموذج بنجاح!")
12
+
13
+ # ============================================
14
+ # 2. تحميل بيانات MNIST للاستخدام في الأمثلة العشوائية
15
+ # ============================================
16
+ (_, _), (test_images, test_labels) = datasets.mnist.load_data()
17
+ test_images = test_images.reshape((10000, 28, 28, 1)).astype('float32') / 255
18
+
19
+ # ============================================
20
+ # 3. دالة التنبؤ على الصورة المرسومة (Sketchpad)
21
+ # ============================================
22
+ def predict_sketch(image):
23
+ """
24
+ تستقبل الصورة من لوحة الرسم، تعالجها، وتعيد الاحتمالات لجميع الفئات.
25
+ """
26
+ try:
27
+ # تحويل الصورة إلى تدرج رمادي
28
+ gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
29
+
30
+ # تغيير الحجم إلى 28×28 (مثل صور MNIST)
31
+ resized = cv2.resize(gray, (28, 28))
32
+
33
+ # قلب الألوان (لأن Sketchpad يرسم بالأبيض على الأسود، لكن أحياناً يكون معكوساً)
34
+ inverted = 255 - resized
35
+
36
+ # تطبيع القيم لتكون بين 0 و 1
37
+ normalized = inverted.astype('float32') / 255.0
38
+
39
+ # إعادة التشكيل لتناسب نموذج CNN
40
+ reshaped = normalized.reshape(1, 28, 28, 1)
41
+
42
+ # التنبؤ
43
+ prediction = model.predict(reshaped, verbose=0)[0]
44
+
45
+ # إرجاع الاحتمالات كقاموس (لتعرضها واجهة Gradio بشكل جميل)
46
+ return {str(i): float(prediction[i]) for i in range(10)}
47
+
48
+ except Exception as e:
49
+ return {"خطأ": str(e)}
50
+
51
+ # ============================================
52
+ # 4. دالة عرض مثال عشوائي (تحقيق طلبك بالعشوائية)
53
+ # ============================================
54
+ def random_example():
55
+ """
56
+ تختار صورة عشوائية من مجموعة الاختبار، وتعرضها في لوحة الرسم،
57
+ وتكتب رقمها الحقيقي في مربع المعلومات.
58
+ """
59
+ idx = np.random.randint(0, len(test_images))
60
+ img = test_images[idx].reshape(28, 28) # استخراج الصورة (28×28)
61
+
62
+ # تحويل الصورة إلى 3 قنوات (RGB) لأن Sketchpad يتوقع صورة ملونة
63
+ img_rgb = np.stack([img] * 3, axis=2)
64
+
65
+ # نص المعلومات
66
+ info_text = f"🖼️ مثال عشوائي رقم {idx} | الرقم الحقيقي: {test_labels[idx]}"
67
+
68
+ return img_rgb, info_text
69
+
70
+ # ============================================
71
+ # 5. بناء واجهة Gradio (باستخدام Blocks للتحكم الكامل)
72
+ # ============================================
73
+ with gr.Blocks(title="MNIST Digit Recognizer", theme=gr.themes.Soft()) as demo:
74
+ gr.Markdown("# 🧠 التعرف على الأرقام المكتوبة بخط اليد")
75
+ gr.Markdown("ارسم رقماً في المربع، أو اضغط على زر **'عرض مثال عشوائي'** لتجربة النموذج على بيانات MNIST.")
76
+
77
+ with gr.Row():
78
+ # عمود المدخلات (لوحة الرسم + الأزرار)
79
+ with gr.Column(scale=1):
80
+ sketch = gr.Sketchpad(
81
+ label="✏️ ارسم هنا",
82
+ image_size=(280, 280),
83
+ brush_color="#FFFFFF", # فرشاة بيضاء على خلفية سوداء
84
+ brush_radius=12
85
+ )
86
+ with gr.Row():
87
+ submit_btn = gr.Button("🔮 توقع", variant="primary")
88
+ random_btn = gr.Button("🎲 عرض مثال عشوائي", variant="secondary")
89
+ info = gr.Textbox(label="📌 معلومات", interactive=False, value="ارسم أو اختر مثالاً عشوائياً")
90
+
91
+ # عمود المخرجات (نتائج التنبؤ)
92
+ with gr.Column(scale=1):
93
+ output = gr.Label(num_top_classes=3, label="📊 الاحتمالات (أعلى 3 فئات)")
94
+
95
+ # ربط الأزرار بالدوال
96
+ submit_btn.click(fn=predict_sketch, inputs=sketch, outputs=output)
97
+ random_btn.click(fn=random_example, inputs=[], outputs=[sketch, info])
98
+
99
+ # ============================================
100
+ # 6. تشغيل التطبيق
101
+ # ============================================
102
+ if __name__ == "__main__":
103
+ demo.launch(share=True)