File size: 7,191 Bytes
9bdeee9
ad0e663
9bdeee9
 
 
 
ad0e663
9bdeee9
ad0e663
 
 
9bdeee9
 
ad0e663
9bdeee9
 
ad0e663
 
 
9bdeee9
ad0e663
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9bdeee9
 
ad0e663
 
 
 
 
 
 
9bdeee9
 
ad0e663
 
9bdeee9
ad0e663
 
 
 
9bdeee9
ad0e663
9bdeee9
ad0e663
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9bdeee9
 
ad0e663
 
 
 
 
 
 
9bdeee9
ad0e663
 
9bdeee9
ad0e663
 
9bdeee9
 
ad0e663
 
9bdeee9
ad0e663
 
 
 
 
9bdeee9
 
ad0e663
9bdeee9
 
ad0e663
 
9bdeee9
ad0e663
9bdeee9
 
 
 
 
 
ad0e663
9bdeee9
 
 
ad0e663
9bdeee9
 
ad0e663
 
9bdeee9
ad0e663
 
9bdeee9
ad0e663
 
 
 
 
 
 
9bdeee9
 
 
ad0e663
 
9bdeee9
 
ad0e663
9bdeee9
ad0e663
9bdeee9
ad0e663
9bdeee9
 
 
ad0e663
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9bdeee9
 
 
ad0e663
 
9bdeee9
ad0e663
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9bdeee9
ad0e663
 
 
 
9bdeee9
 
 
ad0e663
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
import gradio as gr
from transformers import pipeline
from PIL import Image, ImageDraw, ImageFont
import torch
import spaces
import numpy as np
import cv2

# Modèles optimisés pour le temps réel
REALTIME_MODELS = {
    "YOLOS Tiny (ultra-rapide)": "hustvl/yolos-tiny",
    "DETR ResNet-50": "facebook/detr-resnet-50",
    "YOLOS Small": "hustvl/yolos-small",
    "Conditional DETR": "microsoft/conditional-detr-resnet-50"
}

# Cache global pour le modèle
current_detector = None
current_model_name = None

def load_detector(model_name):
    """Charge le détecteur avec cache"""
    global current_detector, current_model_name
    
    if current_model_name != model_name:
        print(f"🔄 Chargement du modèle: {model_name}")
        model_id = REALTIME_MODELS[model_name]
        current_detector = pipeline(
            "object-detection",
            model=model_id,
            device=0 if torch.cuda.is_available() else -1
        )
        current_model_name = model_name
        print(f"✅ Modèle chargé: {model_name}")
    
    return current_detector

@spaces.GPU
def process_webcam_frame(frame, model_choice, confidence_threshold):
    """
    Traite chaque frame de la webcam en temps réel
    Cette fonction est appelée automatiquement pour chaque frame
    """
    if frame is None:
        return frame
    
    try:
        # Charger le détecteur
        detector = load_detector(model_choice)
        
        # Convertir numpy array en PIL Image si nécessaire
        if isinstance(frame, np.ndarray):
            # Gradio webcam donne du RGB
            pil_image = Image.fromarray(frame)
        else:
            pil_image = frame
        
        # Redimensionner pour accélérer le traitement
        original_size = pil_image.size
        max_size = 640  # Réduire la taille pour plus de vitesse
        
        if max(original_size) > max_size:
            ratio = max_size / max(original_size)
            new_size = (int(original_size[0] * ratio), int(original_size[1] * ratio))
            resized_image = pil_image.resize(new_size)
        else:
            resized_image = pil_image
            ratio = 1.0
        
        # Détection sur l'image redimensionnée
        detections = detector(resized_image)
        
        # Filtrer par confiance
        filtered_detections = [
            det for det in detections 
            if det['score'] >= confidence_threshold
        ]
        
        # Redimensionner les coordonnées vers la taille originale
        for det in filtered_detections:
            if ratio != 1.0:
                det['box']['xmin'] = int(det['box']['xmin'] / ratio)
                det['box']['ymin'] = int(det['box']['ymin'] / ratio)
                det['box']['xmax'] = int(det['box']['xmax'] / ratio)
                det['box']['ymax'] = int(det['box']['ymax'] / ratio)
        
        # Dessiner les détections sur l'image originale
        annotated_image = draw_detections_fast(pil_image, filtered_detections)
        
        # Convertir back en numpy pour Gradio
        return np.array(annotated_image)
        
    except Exception as e:
        print(f"❌ Erreur de traitement: {e}")
        return frame

def draw_detections_fast(image, detections):
    """Version optimisée pour dessiner les détections"""
    if not detections:
        return image
    
    draw = ImageDraw.Draw(image)
    
    # Police par défaut pour la vitesse
    try:
        font = ImageFont.load_default()
    except:
        font = None
    
    colors = ["#FF6B6B", "#4ECDC4", "#45B7D1", "#96CEB4", "#FECA57"]
    
    for i, detection in enumerate(detections):
        box = detection['box']
        label = detection['label']
        score = detection['score']
        
        # Coordonnées
        x1, y1 = box['xmin'], box['ymin']
        x2, y2 = box['xmax'], box['ymax']
        
        # Couleur
        color = colors[i % len(colors)]
        
        # Boîte
        draw.rectangle([x1, y1, x2, y2], outline=color, width=2)
        
        # Label avec score
        text = f"{label} {score:.2f}"
        
        # Fond du texte (simplifié)
        if font:
            bbox = draw.textbbox((x1, y1-20), text, font=font)
            draw.rectangle(bbox, fill=color)
            draw.text((x1, y1-20), text, fill="white", font=font)
        else:
            draw.text((x1, y1-15), text, fill=color)
    
    return image

# Interface Gradio avec streaming
with gr.Blocks(title="🎥 Détection Live", theme=gr.themes.Soft()) as demo:
    
    gr.Markdown("""
    # 🎥 Détection d'Objets en Temps Réel
    
    **Activez votre webcam** et voyez la détection se faire en direct !
    
    ⚡ **Optimisé pour la vitesse** avec des modèles légers
    """)
    
    with gr.Row():
        with gr.Column(scale=2):
            # Composant webcam avec streaming
            webcam = gr.Interface(
                fn=process_webcam_frame,
                inputs=[
                    gr.Image(sources=["webcam"], streaming=True, type="numpy"),
                    gr.Dropdown(
                        choices=list(REALTIME_MODELS.keys()),
                        value="YOLOS Tiny (ultra-rapide)",
                        label="🤖 Modèle (changement en direct)"
                    ),
                    gr.Slider(
                        minimum=0.1,
                        maximum=1.0,
                        value=0.5,
                        step=0.1,
                        label="🎯 Seuil de confiance"
                    )
                ],
                outputs=gr.Image(type="numpy", streaming=True),
                live=True,  # ⭐ CRUCIAL: Active le mode live
                title=None
            )
        
        with gr.Column(scale=1):
            gr.Markdown("""
            ## 📊 Informations Live
            
            ### 🎛️ Contrôles en temps réel:
            - **Modèle**: Change instantanément
            - **Confiance**: Ajuste le filtrage
            - **Streaming**: Traitement frame par frame
            
            ### ⚡ Optimisations:
            - Images redimensionnées à 640px
            - Modèles légers prioritaires
            - Cache intelligent des modèles
            - Dessin optimisé
            
            ### 🎯 Modèles recommandés:
            - **YOLOS Tiny**: Maximum de vitesse
            - **DETR ResNet-50**: Bon équilibre
            """)
    
    # Version alternative avec Interface simple
    gr.Markdown("---")
    gr.Markdown("## 🎥 Version Alternative (Interface Simple)")
    
    alternative_interface = gr.Interface(
        fn=process_webcam_frame,
        inputs=[
            gr.Image(sources=["webcam"], streaming=True),
            gr.Dropdown(
                choices=list(REALTIME_MODELS.keys()),
                value="YOLOS Tiny (ultra-rapide)"
            ),
            gr.Slider(0.1, 1.0, 0.5, step=0.1)
        ],
        outputs=gr.Image(streaming=True),
        live=True,  # ⭐ Mode live activé
        title="Détection Webcam Live",
        description="Cliquez sur la webcam pour démarrer le streaming live!"
    )

if __name__ == "__main__":
    demo.launch()