Amadoudllo commited on
Commit
3105ea2
·
verified ·
1 Parent(s): 3d4c507

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +198 -0
app.py ADDED
@@ -0,0 +1,198 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # ============================================================
2
+ # app.py : Application Gradio — Détection d'émotions faciales
3
+ # Déployée sur Hugging Face Spaces
4
+ # ============================================================
5
+
6
+ import gradio as gr
7
+ import numpy as np
8
+ import cv2
9
+ import tensorflow as tf
10
+ import json
11
+ from huggingface_hub import hf_hub_download
12
+
13
+ # --- Charger le modèle depuis notre repo HuggingFace ---
14
+ print("⏳ Chargement du modèle...")
15
+ model_path = hf_hub_download(
16
+ repo_id = "Amadoudllo/emotion-detection-cnn",
17
+ filename = "best_cnn_model.keras"
18
+ )
19
+ model = tf.keras.models.load_model(model_path)
20
+ print("✅ Modèle chargé !")
21
+
22
+ # --- Charger le mapping classes ---
23
+ class_path = hf_hub_download(
24
+ repo_id = "Amadoudllo/emotion-detection-cnn",
25
+ filename = "class_indices.json"
26
+ )
27
+ with open(class_path, "r") as f:
28
+ idx_to_class = json.load(f)
29
+
30
+ # --- Détecteur de visages Haar Cascade ---
31
+ face_cascade = cv2.CascadeClassifier(
32
+ cv2.data.haarcascades + "haarcascade_frontalface_default.xml"
33
+ )
34
+
35
+ # --- Paramètres ---
36
+ IMG_SIZE = 48
37
+
38
+ # Emojis par émotion
39
+ EMOJIS = {
40
+ "Angry" : "😠",
41
+ "Fear" : "😨",
42
+ "Happy" : "😄",
43
+ "Neutral" : "😐",
44
+ "Sad" : "😢",
45
+ "Surprise" : "😲"
46
+ }
47
+
48
+ def clean_label(label):
49
+ """ Corrige Suprise → Surprise """
50
+ return "Surprise" if label == "Suprise" else label
51
+
52
+ def detect_emotion(image):
53
+ """
54
+ Fonction principale appelée à chaque frame webcam ou image uploadée.
55
+ Reçoit une image RGB → retourne image annotée + scores émotions
56
+ """
57
+ if image is None:
58
+ return None, {}
59
+
60
+ # Convertir RGB → BGR pour OpenCV
61
+ frame = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
62
+ gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
63
+
64
+ # --- Détection des visages ---
65
+ faces = face_cascade.detectMultiScale(
66
+ gray,
67
+ scaleFactor=1.1,
68
+ minNeighbors=5,
69
+ minSize=(30, 30)
70
+ )
71
+
72
+ # Scores par défaut si aucun visage
73
+ scores = {
74
+ f"{EMOJIS.get(clean_label(idx_to_class[str(i)]), '')} {clean_label(idx_to_class[str(i)])}": 0.0
75
+ for i in range(len(idx_to_class))
76
+ }
77
+
78
+ for (x, y, w, h) in faces:
79
+
80
+ # --- Préparer le visage pour le modèle ---
81
+ roi = cv2.resize(gray[y:y+h, x:x+w], (IMG_SIZE, IMG_SIZE))
82
+ inp = roi.reshape(1, IMG_SIZE, IMG_SIZE, 1).astype("float32") / 255.
83
+
84
+ # --- Prédiction ---
85
+ preds = model.predict(inp, verbose=0)[0]
86
+ idx = np.argmax(preds)
87
+ emotion = clean_label(idx_to_class[str(idx)])
88
+ confidence = preds[idx] * 100
89
+
90
+ # Scores pour le graphique Gradio
91
+ scores = {
92
+ f"{EMOJIS.get(clean_label(idx_to_class[str(i)]), '')} {clean_label(idx_to_class[str(i)])}": float(preds[i])
93
+ for i in range(len(preds))
94
+ }
95
+
96
+ # --- Dessiner sur la frame ---
97
+ cv2.rectangle(frame, (x, y), (x+w, y+h), (102, 126, 234), 2)
98
+ label = f"{EMOJIS.get(emotion, '')} {emotion} ({confidence:.1f}%)"
99
+ (tw, th), _ = cv2.getTextSize(label, cv2.FONT_HERSHEY_SIMPLEX, 0.7, 2)
100
+ cv2.rectangle(frame, (x, y-th-12), (x+tw+10, y), (102, 126, 234), -1)
101
+ cv2.putText(frame, label, (x+5, y-5),
102
+ cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 255), 2)
103
+
104
+ # Reconvertir BGR → RGB pour Gradio
105
+ frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
106
+
107
+ return frame_rgb, scores
108
+
109
+
110
+ # ============================================================
111
+ # Interface Gradio
112
+ # ============================================================
113
+
114
+ with gr.Blocks(
115
+ title="🎭 Détection d'Émotions Faciales",
116
+ theme=gr.themes.Soft()
117
+ ) as demo:
118
+
119
+ # --- En-tête ---
120
+ gr.Markdown("""
121
+ # 🎭 Détection d'Émotions Faciales en Temps Réel
122
+ **Modèle CNN from Scratch — 64.44% accuracy — 6 émotions détectées**
123
+
124
+ 👉 Utilise ta **webcam** ou **uploade une photo** de visage !
125
+
126
+ > Modèle entraîné sur Kaggle · Code sur [GitHub](https://github.com/amadoudllo/emotion-detection-cnn)
127
+ """)
128
+
129
+ with gr.Tabs():
130
+
131
+ # ── Tab 1 : Webcam temps réel ──
132
+ with gr.Tab("📷 Webcam Temps Réel"):
133
+ gr.Markdown("### Active ta webcam et place ton visage devant la caméra")
134
+
135
+ with gr.Row():
136
+ with gr.Column():
137
+ webcam = gr.Image(
138
+ sources=["webcam"],
139
+ streaming=True,
140
+ label="Webcam",
141
+ mirror_webcam=True
142
+ )
143
+ with gr.Column():
144
+ webcam_output = gr.Image(
145
+ label="Détection",
146
+ streaming=True
147
+ )
148
+ webcam_scores = gr.Label(
149
+ label="Scores par émotion",
150
+ num_top_classes=6
151
+ )
152
+
153
+ # Connexion streaming webcam
154
+ webcam.stream(
155
+ fn=detect_emotion,
156
+ inputs=[webcam],
157
+ outputs=[webcam_output, webcam_scores]
158
+ )
159
+
160
+ # ── Tab 2 : Upload image ──
161
+ with gr.Tab("🖼️ Uploader une Image"):
162
+ gr.Markdown("### Uploade une photo de visage pour analyser l'émotion")
163
+
164
+ with gr.Row():
165
+ with gr.Column():
166
+ img_input = gr.Image(
167
+ sources=["upload"],
168
+ label="Image à analyser",
169
+ type="numpy"
170
+ )
171
+ btn = gr.Button(
172
+ "🔍 Détecter l'émotion",
173
+ variant="primary"
174
+ )
175
+ with gr.Column():
176
+ img_output = gr.Image(label="Résultat")
177
+ img_scores = gr.Label(
178
+ label="Scores par émotion",
179
+ num_top_classes=6
180
+ )
181
+
182
+ # Bouton déclenche la détection
183
+ btn.click(
184
+ fn=detect_emotion,
185
+ inputs=[img_input],
186
+ outputs=[img_output, img_scores]
187
+ )
188
+
189
+ # --- Exemples ---
190
+ gr.Markdown("""
191
+ ---
192
+ **Émotions détectées :**
193
+ 😠 Angry · 😨 Fear · 😄 Happy · 😐 Neutral · 😢 Sad · 😲 Surprise
194
+
195
+ **Défi IA — Semaine 1** · Construit avec ❤️ par Amadoudllo
196
+ """)
197
+
198
+ demo.launch()