File size: 10,484 Bytes
766dbd9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
"""
ZKA Marchés CI - Détection d'Objets avec YOLOv5
Application Gradio pour Hugging Face Spaces
"""

import gradio as gr
import torch
import cv2
import numpy as np
from PIL import Image
import sys
from pathlib import Path

# Add YOLOv5 to path
YOLOV5_ROOT = Path(__file__).resolve().parent
if str(YOLOV5_ROOT) not in sys.path:
    sys.path.insert(0, str(YOLOV5_ROOT))

# Charger le modèle YOLOv5
print("🔄 Chargement du modèle YOLOv5...")
try:
    model = torch.hub.load('ultralytics/yolov5', 'yolov5s', pretrained=True)
    model.conf = 0.25  # Seuil de confiance
    model.iou = 0.45   # Seuil IoU pour NMS
    print("✅ Modèle chargé avec succès!")
except Exception as e:
    print(f"❌ Erreur de chargement: {e}")
    model = None

# Traduction des classes en français
CLASS_NAMES_FR = {
    'person': 'Personne',
    'bicycle': 'Vélo',
    'car': 'Voiture',
    'motorcycle': 'Moto',
    'airplane': 'Avion',
    'bus': 'Bus',
    'train': 'Train',
    'truck': 'Camion',
    'boat': 'Bateau',
    'traffic light': 'Feu de circulation',
    'fire hydrant': 'Borne d\'incendie',
    'stop sign': 'Panneau stop',
    'parking meter': 'Parcomètre',
    'bench': 'Banc',
    'bird': 'Oiseau',
    'cat': 'Chat',
    'dog': 'Chien',
    'horse': 'Cheval',
    'sheep': 'Mouton',
    'cow': 'Vache',
    'elephant': 'Éléphant',
    'bear': 'Ours',
    'zebra': 'Zèbre',
    'giraffe': 'Girafe',
    'backpack': 'Sac à dos',
    'umbrella': 'Parapluie',
    'handbag': 'Sac à main',
    'tie': 'Cravate',
    'suitcase': 'Valise',
    'frisbee': 'Frisbee',
    'skis': 'Skis',
    'snowboard': 'Snowboard',
    'sports ball': 'Ballon de sport',
    'kite': 'Cerf-volant',
    'baseball bat': 'Batte de baseball',
    'baseball glove': 'Gant de baseball',
    'skateboard': 'Skateboard',
    'surfboard': 'Planche de surf',
    'tennis racket': 'Raquette de tennis',
    'bottle': 'Bouteille',
    'wine glass': 'Verre à vin',
    'cup': 'Tasse',
    'fork': 'Fourchette',
    'knife': 'Couteau',
    'spoon': 'Cuillère',
    'bowl': 'Bol',
    'banana': 'Banane',
    'apple': 'Pomme',
    'sandwich': 'Sandwich',
    'orange': 'Orange',
    'broccoli': 'Brocoli',
    'carrot': 'Carotte',
    'hot dog': 'Hot-dog',
    'pizza': 'Pizza',
    'donut': 'Donut',
    'cake': 'Gâteau',
    'chair': 'Chaise',
    'couch': 'Canapé',
    'potted plant': 'Plante en pot',
    'bed': 'Lit',
    'dining table': 'Table à manger',
    'toilet': 'Toilettes',
    'tv': 'Télévision',
    'laptop': 'Ordinateur portable',
    'mouse': 'Souris',
    'remote': 'Télécommande',
    'keyboard': 'Clavier',
    'cell phone': 'Téléphone portable',
    'microwave': 'Micro-ondes',
    'oven': 'Four',
    'toaster': 'Grille-pain',
    'sink': 'Évier',
    'refrigerator': 'Réfrigérateur',
    'book': 'Livre',
    'clock': 'Horloge',
    'vase': 'Vase',
    'scissors': 'Ciseaux',
    'teddy bear': 'Ours en peluche',
    'hair drier': 'Sèche-cheveux',
    'toothbrush': 'Brosse à dents'
}

def detect_objects(image, confidence_threshold, language):
    """
    Détecte les objets dans une image
    
    Args:
        image: Image PIL
        confidence_threshold: Seuil de confiance (0-1)
        language: Langue pour les labels ('fr' ou 'en')
    
    Returns:
        image_result: Image avec les bounding boxes
        stats_text: Statistiques de détection
        detections_html: Tableau HTML des détections
    """
    if model is None:
        return None, "❌ Modèle non chargé", ""
    
    if image is None:
        return None, "❌ Aucune image fournie", ""
    
    try:
        # Mettre à jour le seuil de confiance
        model.conf = confidence_threshold
        
        # Effectuer la détection
        results = model(image)
        
        # Obtenir les détections
        detections = results.pandas().xyxy[0]
        
        # Créer l'image avec les bounding boxes
        img_result = np.array(results.render()[0])
        img_result = Image.fromarray(img_result)
        
        # Statistiques
        num_detections = len(detections)
        
        if num_detections == 0:
            stats_text = "🔍 Aucun objet détecté"
            detections_html = ""
        else:
            # Compter les objets par classe
            class_counts = detections['name'].value_counts().to_dict()
            
            # Texte des statistiques
            stats_text = f"✅ **{num_detections} objet(s) détecté(s)**\n\n"
            stats_text += "**Répartition par classe:**\n"
            for class_name, count in class_counts.items():
                if language == 'fr' and class_name in CLASS_NAMES_FR:
                    class_name = CLASS_NAMES_FR[class_name]
                stats_text += f"- {class_name}: {count}\n"
            
            # Tableau HTML des détections
            detections_html = "<table style='width:100%; border-collapse: collapse;'>"
            detections_html += "<tr style='background-color: #f2f2f2;'>"
            detections_html += "<th style='border: 1px solid #ddd; padding: 8px;'>Classe</th>"
            detections_html += "<th style='border: 1px solid #ddd; padding: 8px;'>Confiance</th>"
            detections_html += "<th style='border: 1px solid #ddd; padding: 8px;'>Position (x1, y1, x2, y2)</th>"
            detections_html += "</tr>"
            
            for idx, row in detections.iterrows():
                class_name = row['name']
                if language == 'fr' and class_name in CLASS_NAMES_FR:
                    class_name = CLASS_NAMES_FR[class_name]
                
                conf = row['confidence']
                x1, y1, x2, y2 = int(row['xmin']), int(row['ymin']), int(row['xmax']), int(row['ymax'])
                
                detections_html += f"<tr>"
                detections_html += f"<td style='border: 1px solid #ddd; padding: 8px;'>{class_name}</td>"
                detections_html += f"<td style='border: 1px solid #ddd; padding: 8px;'>{conf:.2%}</td>"
                detections_html += f"<td style='border: 1px solid #ddd; padding: 8px;'>({x1}, {y1}, {x2}, {y2})</td>"
                detections_html += "</tr>"
            
            detections_html += "</table>"
        
        return img_result, stats_text, detections_html
    
    except Exception as e:
        error_msg = f"❌ Erreur lors de la détection: {str(e)}"
        return None, error_msg, ""

# Interface Gradio
with gr.Blocks(theme=gr.themes.Soft(), title="ZKA - Détection d'Objets") as demo:
    
    gr.Markdown("""
    # 🚀 ZKA Marchés CI - Détection d'Objets par IA
    
    ### Système intelligent de gestion des flux dans les marchés d'Abidjan
    
    Cette application utilise **YOLOv5** pour détecter en temps réel différents objets dans vos images.
    Développée dans le cadre d'un projet de gestion des flux humains et véhicules dans les marchés d'Abidjan.
    
    📌 **Instructions:**
    1. Uploadez une image ou utilisez un exemple
    2. Ajustez le seuil de confiance si nécessaire
    3. Choisissez la langue des labels
    4. Cliquez sur "🔍 Détecter les Objets"
    """)
    
    with gr.Row():
        with gr.Column(scale=1):
            # Entrées
            input_image = gr.Image(
                type="pil",
                label="📸 Image d'entrée",
                height=400
            )
            
            confidence_slider = gr.Slider(
                minimum=0.1,
                maximum=0.9,
                value=0.25,
                step=0.05,
                label="🎯 Seuil de confiance",
                info="Plus la valeur est élevée, plus les détections sont précises (mais moins nombreuses)"
            )
            
            language_radio = gr.Radio(
                choices=[("Français 🇫🇷", "fr"), ("English 🇬🇧", "en")],
                value="fr",
                label="🌍 Langue des labels"
            )
            
            detect_btn = gr.Button("🔍 Détecter les Objets", variant="primary", size="lg")
            
            gr.Markdown("""
            ### 🎯 Objets détectables:
            
            **Transport & Mobilité:**
            - Personnes, véhicules (voitures, motos, bus, camions)
            - Vélos, trottinettes
            
            **Infrastructure & Commerce:**
            - Mobilier urbain (bancs, tables)
            - Objets de marché
            
            **Total:** 80 classes d'objets COCO
            """)
        
        with gr.Column(scale=1):
            # Sorties
            output_image = gr.Image(
                type="pil",
                label="✅ Image avec détections",
                height=400
            )
            
            stats_output = gr.Markdown(label="📊 Statistiques")
            
            detections_table = gr.HTML(label="📋 Détails des détections")
    
    # Exemples
    gr.Markdown("### 📷 Exemples d'images")
    gr.Examples(
        examples=[
            ["https://images.unsplash.com/photo-1573164713988-8665fc963095?w=800", 0.25, "fr"],
            ["https://images.unsplash.com/photo-1449824913935-59a10b8d2000?w=800", 0.25, "fr"],
            ["https://images.unsplash.com/photo-1519046904884-53103b34b206?w=800", 0.3, "fr"],
        ],
        inputs=[input_image, confidence_slider, language_radio],
        outputs=[output_image, stats_output, detections_table],
        fn=detect_objects,
        cache_examples=False,
    )
    
    # Actions
    detect_btn.click(
        fn=detect_objects,
        inputs=[input_image, confidence_slider, language_radio],
        outputs=[output_image, stats_output, detections_table]
    )
    
    gr.Markdown("""
    ---
    
    ### 📖 À propos du projet
    
    **ZKA Marchés CI** est un système intelligent de gestion des flux dans les marchés d'Abidjan basé sur YOLOv5.
    
    **Objectifs:**
    - Détection en temps réel des personnes et véhicules
    - Prévention de la surpopulation
    - Gestion optimale de l'espace
    - Amélioration de la sécurité
    
    **Technologies:**
    - YOLOv5 (Ultralytics)
    - PyTorch
    - Gradio
    
    **Développé par:** ESATIC (École Supérieure Africaine des TIC)
    
    ---
    
    💡 **Conseil:** Pour de meilleurs résultats, utilisez des images claires avec un bon éclairage.
    """)

# Lancer l'application
if __name__ == "__main__":
    print("🚀 Lancement de l'application ZKA...")
    demo.launch()