Skip to content
Snippets Groups Projects
Commit 35cf1f56 authored by Paul Chevalier's avatar Paul Chevalier
Browse files

jsp pourquoi qqn a fait un version POO du programme d'avant j'espère que ct...

jsp pourquoi qqn a fait un version POO du programme d'avant j'espère que ct pas importnant ( je le met dans un autre fichier OK ou)
parent 6570d722
No related branches found
No related tags found
No related merge requests found
import cv2
import os
import shutil
import tkinter as tk
from tkinter import ttk, simpledialog, messagebox, filedialog
import threading
import time
class VideoPlayer:
def __init__(self):
self.is_playing = False
self.current_video = None
self.stop_event = threading.Event()
self.play_thread = None
self.speed = 1.0
def play_video(self, video_path, speed=1.0):
"""Démarre la lecture d'une vidéo en boucle dans un thread séparé"""
self.stop_event.clear()
self.is_playing = True
self.current_video = video_path
self.speed = speed
# Créer un nouveau thread pour la lecture
self.play_thread = threading.Thread(target=self._play_video_loop)
self.play_thread.daemon = True
self.play_thread.start()
def _play_video_loop(self):
"""Joue la vidéo en boucle jusqu'à ce que stop_event soit déclenché"""
while not self.stop_event.is_set():
cap = cv2.VideoCapture(self.current_video)
if not cap.isOpened():
print(f"Erreur : Impossible d'ouvrir {self.current_video}")
break
fps = cap.get(cv2.CAP_PROP_FPS)
delay = int(1000 / (fps * self.speed))
while cap.isOpened() and not self.stop_event.is_set():
ret, frame = cap.read()
if not ret:
break # Fin de la vidéo, on recommence
cv2.imshow("Lecture Vidéo", frame)
if cv2.waitKey(delay) & 0xFF == ord('q'):
self.stop()
break
cap.release()
# Si on a atteint la fin mais que stop_event n'est pas déclenché,
# on recommence la lecture depuis le début
if not self.stop_event.is_set():
continue
else:
break
def stop(self):
"""Arrête la lecture de la vidéo"""
self.stop_event.set()
if self.play_thread:
self.play_thread.join(timeout=1.0)
self.is_playing = False
cv2.destroyAllWindows()
def get_selection(title, options, root=None):
"""Fenêtre avec un menu déroulant pour faire un choix"""
# Vérifier si une instance root a été passée, sinon en créer une nouvelle
own_root = False
if root is None:
root = tk.Tk()
root.withdraw()
own_root = True
selection_window = tk.Toplevel(root)
selection_window.title(title)
selection_window.geometry("300x150")
selection_window.lift() # Amener la fenêtre au premier plan
selection_window.focus_force() # Forcer le focus
tk.Label(selection_window, text=title).pack(pady=5)
selected_value = tk.StringVar()
dropdown = ttk.Combobox(selection_window, textvariable=selected_value, values=options, state='readonly')
dropdown.pack(pady=5)
dropdown.current(0)
def validate():
selection_window.destroy()
tk.Button(selection_window, text="Valider", command=validate).pack(pady=10)
selection_window.wait_window()
# Si nous avons créé notre propre root, il faut le détruire
if own_root:
root.destroy()
return selected_value.get()
def classifier_video(video_path, liste_joueuses, cpt, video_player, root):
"""Interface utilisateur pour classifier ou supprimer une vidéo avec des menus déroulants"""
if messagebox.askyesno("Suppression", "Voulez-vous supprimer cette vidéo ?"):
video_player.stop()
os.remove(video_path)
print(f"Vidéo supprimée : {video_path}")
return None
joueuse = get_selection("Sélectionnez une joueuse", liste_joueuses, root)
if not joueuse:
return None
action_types = ["Réception", "Passe", "Défense", "Autre"]
action = get_selection("Sélectionnez une action", action_types, root)
if not action:
return None
passe_types = {
"Bonne passe (verte)": "Bonne passe",
"Bonne hauteur, mauvaise zone (bleue)": "Bonne hauteur, mauvaise zone",
"Bonne zone, mauvaise hauteur (blanche)": "Bonne zone, mauvaise hauteur",
"Mauvaise passe (rouge)": "Mauvaise passe"
}
passe_result = None
if action == "Passe":
passe_result = get_selection("Qualité de Passe", list(passe_types.keys()), root)
passe_result = passe_types.get(passe_result)
new_name = f"{joueuse}_{action}"
if passe_result:
new_name += f"_{passe_result}"
# On ne change pas l'extension pour conserver le format d'origine
extension = os.path.splitext(video_path)[-1]
new_name += f"_{cpt}{extension}"
# Arrêter la lecture de la vidéo une fois la classification terminée
video_player.stop()
return joueuse, action, passe_result, new_name
def concatener_videos_cv2(video_paths, destination_path):
"""Concatène les vidéos en utilisant OpenCV"""
if not video_paths:
return False
if len(video_paths) == 1:
# S'il n'y a qu'une seule vidéo, la copier simplement
shutil.copy(video_paths[0], destination_path)
return True
# Récupérer les propriétés de la première vidéo
cap = cv2.VideoCapture(video_paths[0])
frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = int(cap.get(cv2.CAP_PROP_FPS))
cap.release()
# Créer l'objet VideoWriter pour la vidéo de sortie
fourcc = cv2.VideoWriter_fourcc(*'mp4v') # Codec pour mp4
out = cv2.VideoWriter(destination_path, fourcc, fps, (frame_width, frame_height))
# Parcourir chaque vidéo et ajouter ses frames à la vidéo de sortie
for video_path in video_paths:
cap = cv2.VideoCapture(video_path)
while True:
ret, frame = cap.read()
if not ret:
break
out.write(frame)
cap.release()
# Libérer l'objet VideoWriter
out.release()
return True
def organiser_videos(video_list, liste_joueuses):
"""Affiche et trie une liste de vidéos en fonction des critères choisis"""
# Créer une seule instance de Tk pour toute l'application
root = tk.Tk()
root.withdraw() # Cacher la fenêtre principale
cpt = 0
speed_choice = get_selection("Vitesse de Lecture", ["1", "1.5", "2"], root)
speed = float(speed_choice) if speed_choice else 1.0
# Créer un lecteur vidéo
video_player = VideoPlayer()
# Dictionnaire pour stocker les vidéos par catégorie
videos_par_categorie = {}
# Liste pour stocker les fichiers à supprimer à la fin
files_to_delete = []
for video in video_list:
if os.path.exists(video):
print(f"Affichage de la vidéo : {video}")
# Lancer la lecture de la vidéo en boucle
video_player.play_video(video, speed)
# Attendre un peu pour que la vidéo commence à s'afficher
time.sleep(0.5)
# Classifier la vidéo pendant qu'elle est en lecture
classification = classifier_video(video, liste_joueuses, cpt, video_player, root)
cpt += 1
if classification:
joueuse, action, passe_result, new_name = classification
# Créer une clé unique pour cette catégorie
categorie_key = f"{joueuse}/{action}"
if action == "Passe" and passe_result:
categorie_key += f"/{passe_result}"
# Ajouter la vidéo à sa catégorie
if categorie_key not in videos_par_categorie:
videos_par_categorie[categorie_key] = []
videos_par_categorie[categorie_key].append((video, new_name))
# Ajouter le fichier à la liste des fichiers à supprimer
files_to_delete.append(video)
# S'assurer que la lecture est arrêtée
video_player.stop()
if videos_par_categorie != {}:
# Demander le dossier de destination
base_dir = filedialog.askdirectory(title="Sélectionnez le dossier de destination", parent=root)
if not base_dir:
root.destroy()
return
# Traiter chaque catégorie
for categorie, videos in videos_par_categorie.items():
# Créer le dossier de destination
dest_dir = os.path.join(base_dir, categorie)
os.makedirs(dest_dir, exist_ok=True)
# Créer les chemins temporaires pour les vidéos
temp_video_paths = []
for video_path, new_name in videos:
temp_path = os.path.join(dest_dir, new_name)
shutil.copy(video_path, temp_path)
temp_video_paths.append(temp_path)
# Créer le nom du fichier final concaténé
categorie_name = categorie.replace('/', '_')
output_file = os.path.join(dest_dir, f"{categorie_name}_complet.mp4")
# Concaténer les vidéos
if concatener_videos_cv2(temp_video_paths, output_file):
print(f"Vidéos concaténées dans {output_file}")
# Supprimer les fichiers temporaires
for temp_path in temp_video_paths:
if os.path.exists(temp_path):
os.remove(temp_path)
# Supprimer les fichiers d'origine
if messagebox.askyesno("Suppression des originaux", "Voulez-vous supprimer les vidéos originales ?", parent=root):
for file_path in files_to_delete:
if os.path.exists(file_path):
try:
os.remove(file_path)
print(f"Fichier original supprimé : {file_path}")
except Exception as e:
print(f"Erreur lors de la suppression de {file_path}: {e}")
# Détruire la fenêtre principale à la fin
root.destroy()
# Programme principal
liste_joueuses = ["lilou", "sadio", "ester"]
# Initialisation de Tk pour le sélecteur de dossier initial
root_initial = tk.Tk()
root_initial.withdraw()
video_folder = filedialog.askdirectory(title="Sélectionnez le dossier contenant les vidéos", parent=root_initial)
root_initial.destroy()
if video_folder:
videos = [os.path.join(video_folder, f) for f in os.listdir(video_folder) if f.endswith(('.mp4', '.avi', '.mov'))]
organiser_videos(videos, liste_joueuses)
# import cv2
# import os
# import shutil
# import tkinter as tk
# from tkinter import ttk, simpledialog, messagebox, filedialog
# import subprocess
# def get_selection(title, options):
# """Fenêtre avec un menu déroulant pour faire un choix"""
# selection_window = tk.Toplevel()
# selection_window.title(title)
# selection_window.geometry("300x150")
# tk.Label(selection_window, text=title).pack(pady=5)
# selected_value = tk.StringVar()
# dropdown = ttk.Combobox(selection_window, textvariable=selected_value, values=options, state='readonly')
# dropdown.pack(pady=5)
# dropdown.current(0)
# def validate():
# selection_window.destroy()
# tk.Button(selection_window, text="Valider", command=validate).pack(pady=10)
# selection_window.wait_window()
# return selected_value.get()
# def afficher_video(video_path, speed=1.0):
# """Affiche une vidéo avec la vitesse choisie"""
# cap = cv2.VideoCapture(video_path)
# if not cap.isOpened():
# print(f"Erreur : Impossible d'ouvrir {video_path}")
# return False
# fps = int(cap.get(cv2.CAP_PROP_FPS))
# delay = int(1000 / (fps * speed))
# while cap.isOpened():
# ret, frame = cap.read()
# if not ret:
# break
# cv2.imshow("Lecture Vidéo", frame)
# if cv2.waitKey(delay) & 0xFF == ord('q'):
# break
# cap.release()
# cv2.destroyAllWindows()
# return True
# def classifier_video(video_path, liste_joueuses, cpt):
# """Interface utilisateur pour classifier ou supprimer une vidéo avec des menus déroulants"""
# root = tk.Tk()
# root.withdraw()
# if messagebox.askyesno("Suppression", "Voulez-vous supprimer cette vidéo ?"):
# os.remove(video_path)
# print(f"Vidéo supprimée : {video_path}")
# return None
# joueuse = get_selection("Sélectionnez une joueuse", liste_joueuses)
# if not joueuse:
# return None
# action_types = ["Réception", "Passe", "Défense", "Autre"]
# action = get_selection("Sélectionnez une action", action_types)
# if not action:
# return None
# passe_types = {
# "Bonne passe (verte)": "Bonne passe",
# "Bonne hauteur, mauvaise zone (bleue)": "Bonne hauteur, mauvaise zone",
# "Bonne zone, mauvaise hauteur (blanche)": "Bonne zone, mauvaise hauteur",
# "Mauvaise passe (rouge)": "Mauvaise passe"
# }
# passe_result = None
# if action == "Passe":
# passe_result = get_selection("Qualité de Passe", list(passe_types.keys()))
# passe_result = passe_types.get(passe_result)
# new_name = f"{joueuse}_{action}"
# if passe_result:
# new_name += f"_{passe_result}"
# # On ne change pas l'extension pour conserver le format d'origine
# extension = os.path.splitext(video_path)[-1]
# new_name += f"_{cpt}{extension}"
# return joueuse, action, passe_result, new_name
# def concatener_videos_cv2(video_paths, destination_path):
# """Concatène les vidéos en utilisant OpenCV au lieu de FFmpeg"""
# if not video_paths:
# return False
# if len(video_paths) == 1:
# # S'il n'y a qu'une seule vidéo, la copier simplement
# shutil.copy(video_paths[0], destination_path)
# return True
# # Récupérer les propriétés de la première vidéo
# cap = cv2.VideoCapture(video_paths[0])
# frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
# frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
# fps = int(cap.get(cv2.CAP_PROP_FPS))
# cap.release()
# # Créer l'objet VideoWriter pour la vidéo de sortie
# fourcc = cv2.VideoWriter_fourcc(*'mp4v') # Codec pour mp4
# out = cv2.VideoWriter(destination_path, fourcc, fps, (frame_width, frame_height))
# # Parcourir chaque vidéo et ajouter ses frames à la vidéo de sortie
# for video_path in video_paths:
# cap = cv2.VideoCapture(video_path)
# while True:
# ret, frame = cap.read()
# if not ret:
# break
# out.write(frame)
# cap.release()
# # Libérer l'objet VideoWriter
# out.release()
# return True
# def organiser_videos(video_list, liste_joueuses):
# """Affiche et trie une liste de vidéos en fonction des critères choisis"""
# cpt = 0
# speed_choice = get_selection("Vitesse de Lecture", ["1", "1.5", "2"])
# speed = float(speed_choice) if speed_choice else 1.0
# # Dictionnaire pour stocker les vidéos par catégorie
# videos_par_categorie = {}
# # Liste pour stocker les fichiers à supprimer à la fin
# files_to_delete = []
# for video in video_list:
# if os.path.exists(video):
# print(f"Affichage de la vidéo : {video}")
# afficher_video(video, speed)
# classification = classifier_video(video, liste_joueuses, cpt)
# cpt += 1
# if classification:
# joueuse, action, passe_result, new_name = classification
# # Créer une clé unique pour cette catégorie
# categorie_key = f"{joueuse}/{action}"
# if action == "Passe" and passe_result:
# categorie_key += f"/{passe_result}"
# # Ajouter la vidéo à sa catégorie
# if categorie_key not in videos_par_categorie:
# videos_par_categorie[categorie_key] = []
# videos_par_categorie[categorie_key].append((video, new_name))
# # Ajouter le fichier à la liste des fichiers à supprimer
# files_to_delete.append(video)
# # Demander le dossier de destination
# base_dir = filedialog.askdirectory(title="Sélectionnez le dossier de destination")
# if not base_dir:
# return
# # Traiter chaque catégorie
# for categorie, videos in videos_par_categorie.items():
# # Créer le dossier de destination
# dest_dir = os.path.join(base_dir, categorie)
# os.makedirs(dest_dir, exist_ok=True)
# # Créer les chemins temporaires pour les vidéos
# temp_video_paths = []
# for video_path, new_name in videos:
# temp_path = os.path.join(dest_dir, new_name)
# shutil.copy(video_path, temp_path)
# temp_video_paths.append(temp_path)
# # Créer le nom du fichier final concaténé
# categorie_name = categorie.replace('/', '_')
# output_file = os.path.join(dest_dir, f"{categorie_name}_complet.mp4")
# # Concaténer les vidéos
# if concatener_videos_cv2(temp_video_paths, output_file):
# print(f"Vidéos concaténées dans {output_file}")
# # Supprimer les fichiers temporaires
# for temp_path in temp_video_paths:
# if os.path.exists(temp_path):
# os.remove(temp_path)
# # Supprimer les fichiers d'origine
# if messagebox.askyesno("Suppression des originaux", "Voulez-vous supprimer les vidéos originales ?"):
# for file_path in files_to_delete:
# if os.path.exists(file_path):
# try:
# os.remove(file_path)
# print(f"Fichier original supprimé : {file_path}")
# except Exception as e:
# print(f"Erreur lors de la suppression de {file_path}: {e}")
# # Programme principal
# liste_joueuses = ["lilou", "sadio", "ester"]
# video_folder = filedialog.askdirectory(title="Sélectionnez le dossier contenant les vidéos")
# if video_folder:
# videos = [os.path.join(video_folder, f) for f in os.listdir(video_folder) if f.endswith(('.mp4', '.avi', '.mov'))]
# organiser_videos(videos, liste_joueuses)
import cv2
import tkinter as tk
from tkinter import ttk
from PIL import Image, ImageTk
import threading
class CameraSelector:
def __init__(self, root):
self.root = root
self.root.title("Sélection de caméra")
self.cameras = []
self.current_camera = None
self.video_source = None
# Détection des caméras disponibles
self.detect_cameras()
# Interface graphique
self.create_widgets()
def detect_cameras(self):
"""Détecte toutes les caméras disponibles jusqu'à l'index 10"""
self.cameras = []
for i in range(10): # Vous pouvez augmenter ce nombre si nécessaire
cap = cv2.VideoCapture(i)
if cap.isOpened():
self.cameras.append(i)
cap.release()
def create_widgets(self):
"""Crée l'interface utilisateur"""
# Cadre principal
main_frame = ttk.Frame(self.root, padding=10)
main_frame.pack()
# Sélection de caméra
ttk.Label(main_frame, text="Caméras détectées:").pack()
self.camera_var = tk.StringVar()
self.cam_selector = ttk.Combobox(main_frame, textvariable=self.camera_var)
self.cam_selector['values'] = [f"Caméra {i}" for i in self.cameras]
self.cam_selector.pack(pady=5)
# Bouton de confirmation
ttk.Button(main_frame, text="Ouvrir", command=self.start_camera).pack(pady=5)
# Zone d'affichage vidéo
self.video_label = ttk.Label(main_frame)
self.video_label.pack()
def start_camera(self):
"""Démarre le flux vidéo de la caméra sélectionnée"""
if self.current_camera is not None:
self.stop_camera()
selected = self.cam_selector.current()
if selected == -1:
return
self.video_source = self.cameras[selected]
self.current_camera = cv2.VideoCapture(self.video_source)
# Démarrer l'affichage vidéo dans un thread séparé
self.thread = threading.Thread(target=self.show_video)
self.thread.daemon = True
self.thread.start()
def show_video(self):
"""Affiche le flux vidéo dans le label"""
while self.current_camera.isOpened():
ret, frame = self.current_camera.read()
if ret:
# Conversion de l'image pour Tkinter
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
img = Image.fromarray(frame)
imgtk = ImageTk.PhotoImage(image=img)
# Mise à jour de l'interface
self.video_label.configure(image=imgtk)
self.video_label.image = imgtk
else:
break
def stop_camera(self):
"""Arrête le flux vidéo"""
if self.current_camera is not None:
self.current_camera.release()
self.video_label.configure(image='')
self.video_label.image = None
def on_close(self):
self.stop_camera()
self.root.destroy()
def detect_cameras():
"""Détecte les caméras connectées à l'ordinateur."""
cameras = []
for i in range(4): # Vérifie les 4 premiers indices de caméra
cap = cv2.VideoCapture(i)
if cap.isOpened():
cameras.append(i)
cap.release()
return cameras
def select_camera():
"""Affiche une interface Tkinter pour sélectionner une caméra."""
cameras = detect_cameras()
if not cameras:
print("Aucune caméra détectée.")
return None
def on_select():
nonlocal selected_camera
selected_camera = int(camera_var.get())
root.destroy()
if __name__ == "__main__":
root = tk.Tk()
app = CameraSelector(root)
root.protocol("WM_DELETE_WINDOW", app.on_close)
root.mainloop()
\ No newline at end of file
root.title("Sélection de la caméra")
tk.Label(root, text="Sélectionnez une caméra :").pack(pady=10)
camera_var = tk.StringVar(value=str(cameras[0]))
for cam in cameras:
ttk.Radiobutton(root, text=f"Caméra {cam}", variable=camera_var, value=str(cam)).pack(anchor=tk.W)
ttk.Button(root, text="Valider", command=on_select).pack(pady=10)
selected_camera = None
root.mainloop()
return selected_camera
if __name__ == "__main__":
camera_index = select_camera()
if camera_index is not None:
print(f"Caméra sélectionnée : {camera_index}")
else:
print("Aucune caméra sélectionnée.")
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment