From 57769777e7ac092e77cd5b2a4e9688fcb98f53d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?OTH=C3=89GUY=20Marion?= <marion.otheguy@imt-atlantique.fr> Date: Fri, 14 Mar 2025 09:31:40 +0000 Subject: [PATCH] Upload New File --- compute_centroids.py | 142 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 compute_centroids.py diff --git a/compute_centroids.py b/compute_centroids.py new file mode 100644 index 0000000..c83f45f --- /dev/null +++ b/compute_centroids.py @@ -0,0 +1,142 @@ +import cv2 +import csv +import os +import numpy as np + +# Chemin vers la vidéo +eye ='right' +nb = 1 + +video_path = f'.\\recording{nb}\\recording{nb}__{eye}.avi' +frame_folder = f'.\\recording{nb\\output_frames_{eye}' +contour_output_folder = f'.\\recording{nb}\\\\contour_frames_{eye}' + + +# Chemin du fichier CSV pour sauvegarder les centroïdes +csv_file_path = f'.\\recording{nb}\\centroids_{eye}.csv' +centroids_list, timestamps=[], [] + +# Créer un dossier pour sauvegarder les images binaires et un dossier pour sauvegarder les images avec les contours +if not os.path.exists(frame_folder): + os.makedirs(frame_folder) +if not os.path.exists(contour_output_folder): + os.makedirs(contour_output_folder) + +# Lire la vidéo +cap = cv2.VideoCapture(video_path) + +frame_number = 0 + +while True: + # Lire la vidéo frame par frame + ret, frame = cap.read() + + timestamp = cap.get(cv2.CAP_PROP_POS_MSEC) / 1000.0 # Get timestamp in seconds + timestamps.append(timestamp) + + # Si la vidéo est terminée, on arrête la boucle + if not ret: + break + + # Convertir la frame en niveaux de gris + gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) + + # Appliquer une transformation binaire avec un seuil + _, binary_frame = cv2.threshold(gray_frame, 127, 255, cv2.THRESH_BINARY) + + # Sauvegarder l'image binaire + frame_output_path = os.path.join(frame_folder, f'frame_{frame_number:04d}.png') + cv2.imwrite(frame_output_path, binary_frame) + + + + # Détecter les contours + contours, hierarchy = cv2.findContours(binary_frame, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) + centroids = [] + + # Trier les contours par taille (aire décroissante) + contours = sorted(contours, key=cv2.contourArea, reverse=True) + # Calculer les centroïdes des contours + for contour in contours: + M = cv2.moments(contour) + if M["m00"] != 0: + cX = int(M["m10"] / M["m00"]) + cY = int(M["m01"] / M["m00"]) + centroids.append((cX, cY)) + else: + centroids.append((0, 0)) + + # Initialiser les coordonnées, les tailles des deux plus gros centroïdes et leur distance + x1, y1, x2, y2, s1, s2, d = None, None, None, None, + None, None, None + + # Vérifier s'il y a au moins un centroid + if len(centroids) > 0: + x1, y1 = centroids[0] + + # Vérifier s'il y a au moins deux centroides + if len(centroids) > 1: + x2, y2 = centroids[1] + + # Vérifier si les coordonnées des centroïdes doivent être échangées + if frame_number > 0 and centroids_list: + prev_x1, prev_y1, prev_x2, prev_y2 = None, None, None, None + for prev_centroid in reversed(centroids_list): + if prev_x1 is None and prev_centroid[1] is not None: + prev_x1 = prev_centroid[1] + if prev_y1 is None and prev_centroid[2] is not None: + prev_y1 = prev_centroid[2] + if prev_x2 is None and prev_centroid[3] is not None: + prev_x2 = prev_centroid[3] + if prev_y2 is None and prev_centroid[4] is not None: + prev_y2 = prev_centroid[4] + if prev_x1 is not None and prev_y1 is not None and prev_x2 is not None and prev_y2 is not None: + break + if x1 is not None and y1 is not None and x2 is not None and y2 is not None: + dist_s1_prev_s2 = np.sqrt((x1 - prev_x2) ** 2 + (y1 - prev_y2) ** 2) + dist_s2_prev_s1 = np.sqrt((x2 - prev_x1) ** 2 + (y2 - prev_y1) ** 2) + dist_s1_prev_s1 = np.sqrt((x1 - prev_x1) ** 2 + (y1 - prev_y1) ** 2) + dist_s2_prev_s2 = np.sqrt((x2 - prev_x2) ** 2 + (y2 - prev_y2) ** 2) + + if dist_s1_prev_s1 > dist_s1_prev_s2 and dist_s2_prev_s2 > dist_s2_prev_s1: + x2, y2 = centroids[0] + x1, y1 = centroids[1] + + # Si le premier centroid disparaît, le deuxième reste en position 2 + if x1 == 0 and y1 == 0 and (x2 != 0 or y2 != 0): + x1, y1 = x2, y2 + x2, y2 = None, None + + + if x1 is not None and y1 is not None and x2 is not None and y2 is not None: + d=np.sqrt((x1-x2)**2 + (y1-y2)**2) + else : + d=None + centroids_list.append([timestamp, x1, y1, x2, y2, d]) + + # Créer une image en couleur pour dessiner les contours + contour_image = cv2.cvtColor(binary_frame, cv2.COLOR_GRAY2BGR) + + # Dessiner les contours sur l'image (couleur rouge) + cv2.drawContours(contour_image, contours, -1, (0, 0, 255), 2) + cv2.circle(contour_image, (x1, y1), 1, (0, 255, 0), -1) # Dessiner le premier centroïde en vert + cv2.circle(contour_image, (x2, y2), 1, (0, 255, 0), -1) # Dessiner le premier centroïde en vert + cv2.putText(contour_image, f'({x1},{y1}); ({x2}, {y2})', (5, 20), cv2.FONT_HERSHEY_SIMPLEX, 0.4, (0, 255, 0), 1) # Ajouter un label au premier centroïde + + # Sauvegarder l'image avec les contours + contour_output_path = os.path.join(contour_output_folder, f'contour_{frame_number:04d}.png') + cv2.imwrite(contour_output_path, contour_image) + + frame_number += 1 + print(f'Processed frame {frame_number}') + +# Libérer les ressources +cap.release() +cv2.destroyAllWindows() + +# Écrire les centroïdes dans un fichier CSV +with open(csv_file_path, mode='w', newline='') as csv_file: + csv_writer = csv.writer(csv_file) + csv_writer.writerow(['time', 'x1', 'y1', 'x2', 'y2', 'd']) # Écrire l'en-tête + for centroid in centroids_list: + csv_writer.writerow(centroid) \ No newline at end of file -- GitLab