EngReem85 commited on
Commit
66c7ba5
·
verified ·
1 Parent(s): cfecae9

Update app.py

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