Mesurer le trafic motorisé & vitesse dans une petite rue

Bonjour,

Je cherche une solution pour mesurer le trafic motorisé dans une petite rue. Et j'aimerais aussi pouvoir mesurer la vitesse si c'est possible. Il s'agit d'une rue en sens unique, j'ai 2 fenêtres qui donnent sur cette rue et les voitures roulent, disons, entre entre 20 et 50km/h.

J'ai vu qu'il y avait un fil de discussion sur ce sujet mais un peu ancien.

Auriez-vous des retours d'expérience et des idées sur la façon de réaliser cela ? Avec quels matériels ?

En vous remerciant par avance pour votre aide.

Denis

Beaucoup d'idées, mais lesquelles fonctionneront dans cet environnement? Puissance, météo, installation, circulation. Au mieux, vous mesurerez la vitesse moyenne, pas la vitesse instantanée. Deux détecteurs (aimants, faisceaux lumineux, faisceaux sonores, caméras) enregistrent le temps des deux capteurs et trouvent la vitesse moyenne en fonction de la distance dans le temps.

Solution un peu chère

Acheter un radar pédagogique et y connecter un arduino (il y a un port qui émet des infos sur certains modèles) pour faire les stats. Certaines mairies en ont qu’ils placent et déplacent de temps en temps, certains lycées aussi.

Le radar pédagogique peut aussi voir les vélos - donc pas forcément les véhicules à moteur cela dit

Comme ça je dirais, qu'avec un Raspberry, une camera et openCV, tu devrais au moins pouvoir au moins compter le nombre de véhicule, peut être qu'en mesurant la distance réel dans la rue couvert par ta caméra, tu pourrais avoir une ordre d'idée de la vitesse?

Malheureusement je n'ai pas d'expérience là dessus et je ne sais qu'elle précision tu pourras avoir :frowning:

OpenCV semble en effet être une bonne approche. Il y a pas mal de littérature sur le sujet.

Avec ce code par exemple fourni par ChatGPT,

import cv2
import numpy as np
import time

# Paramètres
video_source = 'video.mp4'  # Peut être remplacé par l'URL de la caméra IP ou un fichier vidéo
distance_between_lines = 10.0  # Distance réelle entre les lignes en mètres

# Initialiser la capture vidéo
cap = cv2.VideoCapture(video_source)

# Détecteur de fond pour la soustraction de fond
fgbg = cv2.createBackgroundSubtractorMOG2()

# Variables pour le calcul de la vitesse
vehicle_speeds = {}
vehicle_last_positions = {}

while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        break
    
    # Appliquer la soustraction de fond
    fgmask = fgbg.apply(frame)
    
    # Trouver les contours
    contours, _ = cv2.findContours(fgmask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    
    for contour in contours:
        # Ignorer les petits contours qui peuvent être du bruit
        if cv2.contourArea(contour) < 500:
            continue
        
        # Dessiner le rectangle autour du contour
        x, y, w, h = cv2.boundingRect(contour)
        cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
        
        # Calculer le centre du rectangle
        center_x = x + w // 2
        center_y = y + h // 2
        
        # Identifier le véhicule par son centre
        vehicle_id = (center_x, center_y)
        
        if vehicle_id in vehicle_last_positions:
            # Calculer la distance parcourue
            old_center_x, old_center_y, old_time = vehicle_last_positions[vehicle_id]
            distance_pixels = np.sqrt((center_x - old_center_x) ** 2 + (center_y - old_center_y) ** 2)
            
            # Convertir la distance en mètres
            # Supposez que vous avez calibré la distance en pixels à l'avance
            pixels_per_meter = 50  # Exemple de valeur, à calibrer
            distance_meters = distance_pixels / pixels_per_meter
            
            # Calculer le temps écoulé
            current_time = time.time()
            time_elapsed = current_time - old_time
            
            # Calculer la vitesse (m/s)
            speed = distance_meters / time_elapsed
            vehicle_speeds[vehicle_id] = speed
            
            # Mettre à jour la position et l'heure
            vehicle_last_positions[vehicle_id] = (center_x, center_y, current_time)
        else:
            # Première observation du véhicule
            vehicle_last_positions[vehicle_id] = (center_x, center_y, time.time())
    
    # Afficher les vitesses sur l'image
    for vehicle_id, speed in vehicle_speeds.items():
        cv2.putText(frame, f"{speed:.2f} m/s", (vehicle_id[0], vehicle_id[1]), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 2)
    
    # Afficher la vidéo avec les annotations
    cv2.imshow('Frame', frame)
    
    if cv2.waitKey(30) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

Et j'ai poursuivi ma recherche, mais cela demande du travail.

https://wiki.memoirevive79.mooo.com/index.php/Analyse_de_trafic_routier

Pour utiliser chatGPT efficacement, il faut connaitre un peu le langage et les notions utilisées.
ChatGPT n'ayant aucune considération pour ce qui est d'un code fonctionnel.
Je ne suis pas exemple pas sûre que le code reconnaisse une voiture, mais je n'ai pas regardé le code proposé :slight_smile:

Je ne pense pas que ce genre de projet, ne réclame pas un certain travaille de ta pars :slight_smile:

ChatGPT se débrouille pas mal, j'ai déjà expérimenté pour du code Python ou autre.

Faut juste bien comprendre ce qu’il propose pour pouvoir affiner et corriger le tir…

En python je demandes que des choses simples que j'ai la flemme de chercher dans la documentation :slight_smile:

mais en c#, si je lui demande des trucs que mon IDE me propose en automatique ca va, mais des choses un peu plus compliqué, entre les versions et les spécificités des plateformes de déploiement, il est régulièrement dans les choux.
Sans parler qu'il est forcément limité par la date de son dataset :slight_smile:

Bonjour,
Je me suis déjà posé une question du même ordre pour mesurer le trafic dans le rue devant chez moi.
Voici mes conclusion :

  • Capteur a ultrasons, pourquoi pas, mais ils ont une portée assez faible (1.50-2m). Ils peuvent mesurer une vitesse moyenne si vous en mettez deux a une distance donnée. Sa marche, mais que si les voitures sont suffisamment espacées les unes des autres, et avec une précision très relative...

  • Télémètre laser, comme pour le capteur a ultrasons, sauf qu'ils sont bien plus précis et qu'il permettent de "voir" plus loin. Le souci, s'est qu'ils coutent bien plus cher et que le code est plus complexe. Il y as aussi moyen d'utiliser un faisceau laser (comme sur les portail électrique). Il ne renvoie pas une distance, mais indique quand il est coupé.

  • LiDAR, je suppose que s'est le mieux, mais s'est compliqué a réaliser, cher et difficile a coder.

  • Il y as aussi moyen avec deux tubes souple étanches posée au sol a une distance donnée. Quand la voiture roule dessus, sa crée une différence de pression dans le tube qui doit pouvoir être mesurer par un capteur. Je n'ai pas essayer, mais je pense que dans ce cas, s'est le système le plus approprier.

  • Faisceaux infrarouge, sa ne marche pas a cause du fort ensoleillement par chez moi, mais si la rue est suffisamment sombre, pourquoi pas...

Peut être qu'un capteur HALL pourrait capter le métal de la carrosserie d'un véhicule, mais je n'y crois pas trop.

J'espère que mon expérience pourra vous aider.

Guillaume

Bonjour,

Merci pour ces retours. Pour l'instant je regarde plus particulièrement un code Python avec OpenCV, en partant d'une vidéo en fichier. La vidéo bouge un peu donc j'ai des objets parasites.

Voici le code que j'utilise pour l'instant,

import cv2
import numpy as np

# Paramètres
video_source = 'votre_video_stab.mp4'  # Chemin de la vidéo d'entrée
output_video_name = 'video_objets_mouvement.mp4'  # Nom du fichier vidéo de sortie
resize_scale = 0.25  # Échelle de réduction de l'image
min_contour_area = 1000  # Seuil minimum pour la taille de l'aire du contour
circle_radius = 20  # Rayon du cercle à dessiner autour des objets en mouvement

# Paramètres pour le flux optique Farneback
pyr_scale = 0.4
levels = 3
winsize = 15
iterations = 3
poly_n = 5
poly_sigma = 1.2
flags = 0

# Initialiser la capture vidéo
cap = cv2.VideoCapture(video_source)

# Vérifier si la vidéo a pu être ouverte
if not cap.isOpened():
    print("Erreur: Impossible d'ouvrir la vidéo.")
    exit()

# Obtenir les propriétés de la vidéo d'entrée
frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH) * resize_scale)
frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT) * resize_scale)
fps = cap.get(cv2.CAP_PROP_FPS)

# Définir le codec et créer l'objet VideoWriter
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter(output_video_name, fourcc, fps, (frame_width, frame_height))

# Lecture de la première trame
ret, prev_frame = cap.read()
if not ret:
    print("Erreur lors de la lecture de la vidéo")
    cap.release()
    out.release()
    exit()

prev_frame = cv2.resize(prev_frame, (frame_width, frame_height))
prev_gray = cv2.cvtColor(prev_frame, cv2.COLOR_BGR2GRAY)

while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        break
    
    # Redimensionner l'image
    frame = cv2.resize(frame, (frame_width, frame_height))
    
    # Convertir l'image en niveaux de gris
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    
    # Calculer le flux optique dense entre les deux trames
    flow = cv2.calcOpticalFlowFarneback(prev_gray, gray, None, pyr_scale, levels, winsize, iterations, poly_n, poly_sigma, flags)
    
    # Calculer le module et l'angle du flux optique
    magnitude, _ = cv2.cartToPolar(flow[..., 0], flow[..., 1])
    
    # Appliquer un seuillage pour détecter les mouvements
    _, motion_mask = cv2.threshold(magnitude, 5, 255, cv2.THRESH_BINARY)
    
    # Recherche des contours dans le masque de mouvement
    contours, _ = cv2.findContours(motion_mask.astype(np.uint8), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    
    # Dessiner les cercles autour des contours détectés
    for contour in contours:
        contour_area = cv2.contourArea(contour)
        if contour_area > min_contour_area:
            M = cv2.moments(contour)
            if M["m00"] != 0:
                center_x = int(M["m10"] / M["m00"])
                center_y = int(M["m01"] / M["m00"])
                cv2.circle(frame, (center_x, center_y), circle_radius, (0, 255, 0), 2)
    
    # Écrire la trame dans le fichier vidéo de sortie
    out.write(frame)
    
    # Afficher l'image avec les cercles autour des contours détectés
    cv2.imshow('Cercles', frame)
    
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
    
    # Mettre à jour la trame précédente et l'image en niveaux de gris
    prev_frame = frame.copy()
    prev_gray = gray.copy()

# Libérer les ressources
cap.release()
out.release()
cv2.destroyAllWindows()

ça commence à marcher pour le comptage de véhicules, https://youtu.be/_6sZ5U1kOlg?si=JKvs7YV9IQojRxEs

Denis

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.