ModuMLTECH commited on
Commit
b1e5ec7
·
verified ·
1 Parent(s): 27154b7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +101 -219
app.py CHANGED
@@ -1,6 +1,5 @@
1
  import streamlit as st
2
  import cv2
3
- import tempfile
4
  import os
5
  import time
6
  import numpy as np
@@ -80,58 +79,6 @@ class YOLOVideoProcessor:
80
  self.unique_region1_ids = set()
81
  self.unique_region2_ids = set()
82
 
83
- def process_video(self, video_path, output_path, progress_bar=None):
84
- """Traite une vidéo enregistrée avec optimisations"""
85
- cap = cv2.VideoCapture(video_path)
86
- if not cap.isOpened():
87
- st.error("⚠️ Erreur : Impossible d'ouvrir la vidéo.")
88
- return
89
-
90
- frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
91
- frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
92
- fps = int(cap.get(cv2.CAP_PROP_FPS))
93
-
94
- if fps == 0:
95
- fps = 30 # Valeur par défaut si FPS est invalide
96
-
97
- # Utiliser XVID qui est généralement mieux supporté
98
- fourcc = cv2.VideoWriter_fourcc(*'XVID')
99
- out = cv2.VideoWriter(output_path, fourcc, fps, (frame_width, frame_height))
100
-
101
- processed_frames = 0
102
- total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
103
- frame_count = 0
104
-
105
- while cap.isOpened():
106
- success, frame = cap.read()
107
- if not success:
108
- break
109
-
110
- # Mise à jour de la barre de progression
111
- if progress_bar is not None:
112
- progress_bar.progress(processed_frames / total_frames)
113
-
114
- # Ne traiter qu'une image sur N pour accélérer le traitement
115
- if frame_count % self.frame_skip == 0:
116
- processed_frame = self.process_frame(frame)
117
- self.last_processed_frame = processed_frame
118
- else:
119
- # Réutiliser le dernier frame traité, mais mettre à jour juste les compteurs
120
- processed_frame = self.last_processed_frame if self.last_processed_frame is not None else frame
121
-
122
- out.write(processed_frame)
123
- processed_frames += 1
124
- frame_count += 1
125
-
126
- cap.release()
127
- out.release()
128
- cv2.destroyAllWindows()
129
-
130
- if processed_frames == 0:
131
- st.error("⚠️ Aucune image n'a été écrite dans la vidéo de sortie !")
132
-
133
- return len(self.unique_region1_ids), len(self.unique_region2_ids)
134
-
135
  def process_frame(self, frame):
136
  """Traite une image individuelle avec YOLO et le tracking, avec optimisations"""
137
  if frame is None:
@@ -390,13 +337,13 @@ class YOLOVideoProcessor:
390
  # --- INTERFACE STREAMLIT ---
391
  def main():
392
  st.set_page_config(
393
- page_title="Détecteur de Véhicules",
394
  page_icon="🚗",
395
  layout="wide",
396
  menu_items={"About": "Détection de véhicules avec YOLOv8"}
397
  )
398
 
399
- st.title("🚗 Détection et comptage de Véhicules sur l'Autoroute de l'Avenir")
400
 
401
  # Session state pour gérer l'état de la webcam
402
  if 'webcam_active' not in st.session_state:
@@ -421,10 +368,7 @@ def main():
421
  st.warning("⚠️ Utilisation du modèle YOLO standard à la place")
422
  model_path = "yolov8n.pt"
423
 
424
- # Onglets pour séparer les modes vidéo et webcam
425
- tab1, tab2 = st.tabs(["📹 Analyse de Vidéo", "🎥 Détection en Temps Réel"])
426
-
427
- # Paramètres communs entre les onglets
428
  with st.sidebar:
429
  st.header("🔹 Paramètres")
430
 
@@ -462,170 +406,108 @@ def main():
462
  # Vérifier que les polygones sont valides
463
  valid_polygons = len(poly1) == 4 and len(poly2) == 4
464
 
465
- # Onglet 1: Analyse de Vidéo
466
- with tab1:
467
- uploaded_file = st.file_uploader("📂 Upload une vidéo", type=["mp4", "avi", "mov"])
468
-
469
- if uploaded_file is not None:
470
- # Créer un dossier temporaire si nécessaire
471
- temp_dir = tempfile.mkdtemp()
472
- input_video_path = os.path.join(temp_dir, "input_video.mp4")
473
- output_video_path = os.path.join(temp_dir, "output_video.mp4")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
474
 
475
- # Écrire le fichier téléchargé dans un fichier temporaire
476
- with open(input_video_path, "wb") as f:
477
- f.write(uploaded_file.getbuffer())
 
 
478
 
479
- st.video(input_video_path) # Afficher la vidéo d'entrée
 
480
 
481
- if st.button("▶️ Lancer la détection"):
482
- if valid_polygons:
483
- # Afficher la barre de progression
484
- progress_text = "🔄 Traitement de la vidéo en cours..."
485
- progress_bar = st.progress(0)
486
-
487
- # Traitement de la vidéo avec les paramètres d'optimisation
488
- processor = YOLOVideoProcessor(model_path, poly1, poly2, tracker_method)
489
- processor.frame_skip = frame_skip
490
- processor.downsample_factor = downsample
491
- processor.conf_threshold = conf_threshold
492
-
493
- # Démarrer le traitement
494
- start_time = time.time()
495
- count1, count2 = processor.process_video(input_video_path, output_video_path, progress_bar=progress_bar)
496
- end_time = time.time()
497
-
498
- # Calcul du temps de traitement
499
- processing_time = end_time - start_time
500
-
501
- progress_bar.progress(1.0) # Compléter la barre de progression
502
- st.success(f"✅ Traitement terminé en {processing_time:.2f} secondes!")
503
-
504
- # Afficher les résultats
505
- col_result1, col_result2 = st.columns(2)
506
- with col_result1:
507
- st.metric("Véhicules Sens 1 (Vert)", count1)
508
- with col_result2:
509
- st.metric("Véhicules Sens 2 (Rouge)", count2)
510
-
511
- # Afficher la vidéo traitée
512
- st.subheader("Vidéo traitée")
513
- st.video(output_video_path)
514
-
515
- # Option de téléchargement
516
- with open(output_video_path, "rb") as file:
517
- st.download_button(
518
- label="⬇️ Télécharger la vidéo",
519
- data=file,
520
- file_name="video_traitee.mp4",
521
- mime="video/mp4"
522
- )
523
- else:
524
- st.error("❌ Les coordonnées des polygones doivent contenir **exactement 4 points**.")
525
-
526
- # Onglet 2: Détection en Temps Réel
527
- with tab2:
528
- st.header("Détection en Temps Réel avec Webcam")
529
-
530
- # Vérifier les caméras disponibles
531
- available_cameras = check_camera_availability()
532
- if not available_cameras:
533
- st.warning("⚠️ Aucune caméra détectée automatiquement sur votre système. Vous pouvez toujours essayer les options ci-dessous.")
534
- else:
535
- st.success(f"✅ Caméras détectées aux indices: {available_cameras}")
536
-
537
- # Méthode améliorée de sélection de caméra
538
- camera_options = {"Webcam par défaut (0)": 0}
539
-
540
- # Ajouter plus d'options pour les caméras alternatives
541
- for i in range(1, 8): # Essayer jusqu'à 8 caméras différentes
542
- camera_options[f"Caméra alternative ({i})"] = i
543
-
544
- # Ajouter aussi des options pour les caméras virtuelles ou IP
545
- camera_options["Caméra IP (entrez l'URL)"] = "ip"
546
-
547
- selected_camera = st.selectbox("Sélectionnez la source vidéo", list(camera_options.keys()))
548
-
549
- # Permettre d'entrer une URL de caméra IP
550
- if camera_options[selected_camera] == "ip":
551
- ip_camera_url = st.text_input("URL de la caméra IP (RTSP, HTTP)", "http://adresse-ip:port/video")
552
- camera_id = ip_camera_url
553
- else:
554
- camera_id = camera_options[selected_camera]
555
-
556
- # Paramètres d'affichage
557
- display_quality = st.select_slider(
558
- "Qualité d'affichage",
559
- options=["Basse", "Moyenne", "Haute"],
560
- value="Moyenne"
561
- )
562
-
563
- # Affichage des placeholders
564
- video_container = st.container()
565
- video_placeholder = video_container.empty()
566
-
567
- # Crée une ligne pour les compteurs
568
- count_col1, count_col2 = st.columns(2)
569
- count_placeholders = [count_col1.empty(), count_col2.empty()]
570
-
571
- # Afficher les infos sur les performances
572
- st.info("ℹ️ **Optimisations appliquées:** Multi-threading, redimensionnement des images, et utilisation de CUDA si disponible")
573
-
574
- # Boutons pour démarrer/arrêter la webcam
575
- col_start, col_stop = st.columns(2)
576
-
577
- if col_start.button("▶️ Démarrer la détection en direct"):
578
- if not valid_polygons:
579
- st.error("❌ Les coordonnées des polygones doivent contenir **exactement 4 points**.")
580
- elif st.session_state.webcam_active:
581
- st.warning("⚠️ La webcam est déjà active !")
582
- else:
583
- video_placeholder.info("🔄 Tentative de connexion à la caméra... Veuillez patienter.")
584
-
585
- # Créer le processeur YOLO avec les paramètres d'optimisation
586
- processor = YOLOVideoProcessor(model_path, poly1, poly2, tracker_method)
587
- processor.frame_skip = frame_skip
588
- processor.downsample_factor = downsample
589
- processor.conf_threshold = conf_threshold
590
-
591
- st.session_state.processor = processor
592
- st.session_state.webcam_active = True
593
-
594
- # Démarrer le traitement dans un thread séparé
595
- processing_thread = threading.Thread(
596
- target=st.session_state.processor.process_webcam,
597
- args=(camera_id, video_placeholder, count_placeholders)
598
- )
599
- processing_thread.daemon = True
600
-
601
- # Ajouter le contexte Streamlit au thread pour éviter les erreurs
602
- add_script_run_ctx(processing_thread)
603
-
604
- try:
605
- processing_thread.start()
606
- st.session_state.processing_thread = processing_thread
607
- except Exception as e:
608
- st.error(f"Erreur au démarrage du thread: {e}")
609
- st.session_state.webcam_active = False
610
-
611
- if col_stop.button("⏹️ Arrêter la détection"):
612
- if st.session_state.webcam_active and st.session_state.processor:
613
- st.session_state.processor.stop_processing = True
614
  st.session_state.webcam_active = False
615
-
616
- # Attendre que le thread se termine
617
- if st.session_state.processing_thread:
618
- st.session_state.processing_thread.join(timeout=2.0)
619
- st.session_state.processing_thread = None
620
-
621
- time.sleep(0.5)
622
- video_placeholder.empty() # Effacer l'affichage vidéo
623
-
624
- # Réinitialiser les compteurs
625
- for placeholder in count_placeholders:
626
- placeholder.empty()
627
- else:
628
- st.warning("⚠️ Aucune détection en cours !")
 
 
 
 
 
629
 
630
  if __name__ == "__main__":
631
  main()
 
1
  import streamlit as st
2
  import cv2
 
3
  import os
4
  import time
5
  import numpy as np
 
79
  self.unique_region1_ids = set()
80
  self.unique_region2_ids = set()
81
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
  def process_frame(self, frame):
83
  """Traite une image individuelle avec YOLO et le tracking, avec optimisations"""
84
  if frame is None:
 
337
  # --- INTERFACE STREAMLIT ---
338
  def main():
339
  st.set_page_config(
340
+ page_title="Détecteur de Véhicules en Temps Réel",
341
  page_icon="🚗",
342
  layout="wide",
343
  menu_items={"About": "Détection de véhicules avec YOLOv8"}
344
  )
345
 
346
+ st.title("🚗 Détection et comptage de Véhicules en Temps Réel")
347
 
348
  # Session state pour gérer l'état de la webcam
349
  if 'webcam_active' not in st.session_state:
 
368
  st.warning("⚠️ Utilisation du modèle YOLO standard à la place")
369
  model_path = "yolov8n.pt"
370
 
371
+ # Paramètres dans la barre latérale
 
 
 
372
  with st.sidebar:
373
  st.header("🔹 Paramètres")
374
 
 
406
  # Vérifier que les polygones sont valides
407
  valid_polygons = len(poly1) == 4 and len(poly2) == 4
408
 
409
+ # Section principale de la détection en temps réel
410
+ st.header("Détection en Temps Réel avec Webcam")
411
+
412
+ # Vérifier les caméras disponibles
413
+ available_cameras = check_camera_availability()
414
+ if not available_cameras:
415
+ st.warning("⚠️ Aucune caméra détectée automatiquement sur votre système. Vous pouvez toujours essayer les options ci-dessous.")
416
+ else:
417
+ st.success(f"✅ Caméras détectées aux indices: {available_cameras}")
418
+
419
+ # Méthode améliorée de sélection de caméra
420
+ camera_options = {"Webcam par défaut (0)": 0}
421
+
422
+ # Ajouter plus d'options pour les caméras alternatives
423
+ for i in range(1, 8): # Essayer jusqu'à 8 caméras différentes
424
+ camera_options[f"Caméra alternative ({i})"] = i
425
+
426
+ # Ajouter aussi des options pour les caméras virtuelles ou IP
427
+ camera_options["Caméra IP (entrez l'URL)"] = "ip"
428
+
429
+ selected_camera = st.selectbox("Sélectionnez la source vidéo", list(camera_options.keys()))
430
+
431
+ # Permettre d'entrer une URL de caméra IP
432
+ if camera_options[selected_camera] == "ip":
433
+ ip_camera_url = st.text_input("URL de la caméra IP (RTSP, HTTP)", "http://adresse-ip:port/video")
434
+ camera_id = ip_camera_url
435
+ else:
436
+ camera_id = camera_options[selected_camera]
437
+
438
+ # Paramètres d'affichage
439
+ display_quality = st.select_slider(
440
+ "Qualité d'affichage",
441
+ options=["Basse", "Moyenne", "Haute"],
442
+ value="Moyenne"
443
+ )
444
+
445
+ # Affichage des placeholders
446
+ video_container = st.container()
447
+ video_placeholder = video_container.empty()
448
+
449
+ # Crée une ligne pour les compteurs
450
+ count_col1, count_col2 = st.columns(2)
451
+ count_placeholders = [count_col1.empty(), count_col2.empty()]
452
+
453
+ # Afficher les infos sur les performances
454
+ st.info("ℹ️ **Optimisations appliquées:** Multi-threading, redimensionnement des images, et utilisation de CUDA si disponible")
455
+
456
+ # Boutons pour démarrer/arrêter la webcam
457
+ col_start, col_stop = st.columns(2)
458
+
459
+ if col_start.button("▶️ Démarrer la détection en direct"):
460
+ if not valid_polygons:
461
+ st.error("❌ Les coordonnées des polygones doivent contenir **exactement 4 points**.")
462
+ elif st.session_state.webcam_active:
463
+ st.warning("⚠️ La webcam est déjà active !")
464
+ else:
465
+ video_placeholder.info("🔄 Tentative de connexion à la caméra... Veuillez patienter.")
466
 
467
+ # Créer le processeur YOLO avec les paramètres d'optimisation
468
+ processor = YOLOVideoProcessor(model_path, poly1, poly2, tracker_method)
469
+ processor.frame_skip = frame_skip
470
+ processor.downsample_factor = downsample
471
+ processor.conf_threshold = conf_threshold
472
 
473
+ st.session_state.processor = processor
474
+ st.session_state.webcam_active = True
475
 
476
+ # Démarrer le traitement dans un thread séparé
477
+ processing_thread = threading.Thread(
478
+ target=st.session_state.processor.process_webcam,
479
+ args=(camera_id, video_placeholder, count_placeholders)
480
+ )
481
+ processing_thread.daemon = True
482
+
483
+ # Ajouter le contexte Streamlit au thread pour éviter les erreurs
484
+ add_script_run_ctx(processing_thread)
485
+
486
+ try:
487
+ processing_thread.start()
488
+ st.session_state.processing_thread = processing_thread
489
+ except Exception as e:
490
+ st.error(f"Erreur au démarrage du thread: {e}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
491
  st.session_state.webcam_active = False
492
+
493
+ if col_stop.button("⏹️ Arrêter la détection"):
494
+ if st.session_state.webcam_active and st.session_state.processor:
495
+ st.session_state.processor.stop_processing = True
496
+ st.session_state.webcam_active = False
497
+
498
+ # Attendre que le thread se termine
499
+ if st.session_state.processing_thread:
500
+ st.session_state.processing_thread.join(timeout=2.0)
501
+ st.session_state.processing_thread = None
502
+
503
+ time.sleep(0.5)
504
+ video_placeholder.empty() # Effacer l'affichage vidéo
505
+
506
+ # Réinitialiser les compteurs
507
+ for placeholder in count_placeholders:
508
+ placeholder.empty()
509
+ else:
510
+ st.warning("⚠️ Aucune détection en cours !")
511
 
512
  if __name__ == "__main__":
513
  main()