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

# 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"
}

# Variables globales pour le cache
current_detector = None
current_model_name = None

@spaces.GPU
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 detect_objects_live(image, model_choice, confidence_threshold):
    """
    Fonction principale de détection pour le streaming live
    """
    if image is None:
        return None
    
    try:
        # Charger le détecteur
        detector = load_detector(model_choice)
        
        # Convertir en PIL Image si c'est un array numpy
        if isinstance(image, np.ndarray):
            pil_image = Image.fromarray(image)
        else:
            pil_image = image
        
        # Redimensionner pour optimiser la vitesse
        original_size = pil_image.size
        max_size = 480  # Taille réduite 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
        
        # Effectuer la détection
        detections = detector(resized_image)
        
        # Filtrer par confiance
        filtered_detections = [
            det for det in detections 
            if det['score'] >= confidence_threshold
        ]
        
        print(f"🎯 Détections trouvées: {len(filtered_detections)}")
        
        # Ajuster les coordonnées à 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
        annotated_image = draw_detections(pil_image, filtered_detections)
        
        return annotated_image
        
    except Exception as e:
        print(f"❌ Erreur: {e}")
        return image

def draw_detections(image, detections):
    """Dessine les boîtes de détection sur l'image"""
    if not detections:
        return image
    
    # Créer une copie pour dessiner
    img_copy = image.copy()
    draw = ImageDraw.Draw(img_copy)
    
    # Couleurs vives pour les détections
    colors = ["#FF0000", "#00FF00", "#0000FF", "#FFFF00", "#FF00FF", "#00FFFF"]
    
    try:
        # Essayer de charger une police
        font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 20)
    except:
        font = ImageFont.load_default()
    
    for i, detection in enumerate(detections):
        box = detection['box']
        label = detection['label']
        score = detection['score']
        
        # Coordonnées de la boîte
        x1, y1 = box['xmin'], box['ymin']
        x2, y2 = box['xmax'], box['ymax']
        
        # Couleur pour cette détection
        color = colors[i % len(colors)]
        
        # Dessiner la boîte (plus épaisse pour être visible)
        draw.rectangle([x1, y1, x2, y2], outline=color, width=4)
        
        # Texte du label
        text = f"{label} ({score:.2f})"
        
        # Fond du texte pour la lisibilité
        bbox = draw.textbbox((x1, y1-30), text, font=font)
        draw.rectangle([bbox[0]-2, bbox[1]-2, bbox[2]+2, bbox[3]+2], fill=color)
        
        # Texte en blanc
        draw.text((x1, y1-30), text, fill="white", font=font)
    
    return img_copy

# Interface Gradio simplifiée
with gr.Blocks(title="🎥 Détection Live", theme=gr.themes.Soft()) as demo:
    
    gr.Markdown("""
    # 🎥 Détection d'Objets en Temps Réel
    
    **Autorisez l'accès à votre webcam** et la détection se fera automatiquement !
    """)
    
    with gr.Row():
        with gr.Column():
            # Contrôles
            model_dropdown = gr.Dropdown(
                choices=list(REALTIME_MODELS.keys()),
                value="YOLOS Tiny (ultra-rapide)",
                label="🤖 Modèle de détection"
            )
            
            confidence_slider = gr.Slider(
                minimum=0.1,
                maximum=1.0,
                value=0.5,
                step=0.1,
                label="🎯 Seuil de confiance minimum"
            )
        
        with gr.Column():
            gr.Markdown("""
            ### 📊 Info
            - **Streaming automatique** activé
            - **Détection en continu** sur chaque frame
            - **Ajustements en temps réel**
            """)
    
    # Interface de streaming principal
    webcam_interface = gr.Interface(
        fn=detect_objects_live,
        inputs=[
            gr.Image(sources=["webcam"], streaming=True, label="📹 Webcam Live"),
            model_dropdown,
            confidence_slider
        ],
        outputs=gr.Image(streaming=True, label="🎯 Détection en Temps Réel"),
        live=True,
        allow_flagging="never",
        title=None,
        description="La détection se fait automatiquement sur chaque frame de la webcam"
    )

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