Importance de la détection de piétons
La détection de piétons est un domaine crucial de la vision par ordinateur, largement utilisée dans les systèmes de surveillance intelligents, les véhicules autonomes et l'analyse vidéo. L'objectif est d'identifier et de localiser les humains dans une image ou un flux vidéo en s'appuyant sur divers algorithmes d'apprentissage automatique et profond.
Dans un contexte urbain de plus en plus dense, la capacité à repérer les piétons en temps réel est essentielle pour garantir la sécurité routière et optimiser la gestion de la circulation. Les applications s'étendent de la prévention des collisions dans l'automobile à l'analyse comportementale dans les espaces publics.
Fondements algorithmiques de la détection
Approches classiques : HOG et SVM
L'histogramme des gradients orientés (HOG) est un descripteur de caractéristiques populaire pour la détection d'objets. Il capture les contours et les formes en calculant les distributions des gradients locaux. Couplé à un classifieur à vecteurs de suppport (SVM), il forme une méthode robuste pour distinguer les piétons du décor.
import cv2
def detecter_pietons_hog(img_source):
# Conversion en niveaux de gris pour réduire la complexité
img_gris = cv2.cvtColor(img_source, cv2.COLOR_BGR2GRAY)
# Initialisation du descripteur HOG avec le détecteur SVM pré-entraîné
descripteur_hog = cv2.HOGDescriptor()
descripteur_hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())
# Détection multi-échelles
regions_detectees, niveau_confiance = descripteur_hog.detectMultiScale(
img_gris,
winStride=(8, 8),
scale=1.05
)
return regions_detectees, niveau_confiance
# Exécution sur une image statique
image_originale = cv2.imread('scene_urbaine.jpg')
rectangles, scores = detecter_pietons_hog(image_originale)
for rect, score in zip(rectangles, scores):
pos_x, pos_y, largeur, hauteur = rect
cv2.rectangle(image_originale, (pos_x, pos_y), (pos_x + largeur, pos_y + hauteur), (0, 255, 0), 2)
cv2.imshow('Détection HOG', image_originale)
cv2.waitKey(0)
cv2.destroyAllWindows()
Pour entraîner un modèle SVM personnalisé avec scikit-learn sur des caractéristiques extraites :
from sklearn import svm
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
# Séparation des données en ensembles d'entraînement et de test
X_app, X_test, y_app, y_test = train_test_split(caracteristiques_hog, etiquettes, test_size=0.2, random_state=42)
# Instanciation et entraînement du SVM avec un noyau linéaire
classifieur_svm = svm.SVC(kernel='linear')
classifieur_svm.fit(X_app, y_app)
# Évaluation des performances
previsions = classifieur_svm.predict(X_test)
print(classification_report(y_test, previsions))
Méthodes modernes : Deep Learning
Avec l'avènement des réseaux de neurones convolutifs (CNN), la détection d'objets a connu une révolution. Les CNN apprennent automatiquement des représentations hiérarchiques des caractéristiques visuleles, surpassant souvent les méthodes traditionnelles.
import tensorflow as tf
from tensorflow.keras import layers, models
def construire_modele_cnn(hauteur_img, largeur_img, canaux, nb_classes):
reseau = models.Sequential([
layers.Conv2D(32, (3, 3), activation='relu', input_shape=(hauteur_img, largeur_img, canaux)),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(64, (3, 3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Flatten(),
layers.Dense(128, activation='relu'),
layers.Dense(nb_classes, activation='softmax')
])
reseau.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
return reseau
modele_cnn = construire_modele_cnn(64, 64, 3, 2)
modele_cnn.fit(donnees_entrainement, etiquettes_entrainement, epochs=15)
Pour une détection en temps réel, des architectures comme YOLO (You Only Look Once) ou Faster R-CNN sont privilégiées. YOLO traite l'image globale pour prédire simultanément les boîtes englobantes et les probabilités de classe.
Implémentation avec Python et OpenCV
Python, grâce à sa simplicité et son écosystème scientifique, couplé à OpenCV, permet de prototyper rapidement des systèmes de vision par ordinateur.
Détection en flux continu via Haar Cascade
OpenCV inclut des classifieurs en cascade pré-entraînés basés sur les caractéristiques de Haar, qui offrent une solution légère pour la détection de corps entiers.
import cv2
# Initialisation de la capture vidéo (0 pour la webcam par défaut)
flux_video = cv2.VideoCapture(0)
# Chargement du classifieur Haar pré-entraîné
cascade_pietons = cv2.CascadeClassifier('haarcascade_fullbody.xml')
while True:
ret, trame = flux_video.read()
if not ret:
break
trame_grise = cv2.cvtColor(trame, cv2.COLOR_BGR2GRAY)
# Détection des entités dans la trame
entites = cascade_pietons.detectMultiScale(
trame_grise,
scaleFactor=1.1,
minNeighbors=5,
minSize=(30, 30)
)
# Rendu visuel des boîtes englobantes
for (x, y, l, h) in entites:
cv2.rectangle(trame, (x, y), (x+l, y+h), (255, 0, 0), 2)
cv2.imshow('Flux Webcam', trame)
# Arrêt sur la touche 'q'
if cv2.waitKey(1) & 0xFF == ord('q'):
break
flux_video.release()
cv2.destroyAllWindows()
Étapes de mise en œuvre du système
Préparation et augmentation des données
Un modèle performant nécessite une base de données riche et variée. L'augmentation de données (rotation, recadrage, ajustement de luminosité) permet d'artificiellement grossir le jeu d'entraînement et d'améliorer la robustesse face aux variations environnementales.
Post-traitement : Suppression des non-maxima (NMS)
Les algorithmes de détection génèrent souvent de multiples boîtes chevauchantes pour un même objet. La technique NMS (Non-Maximum Suppression) permet de filtrer ces redondances en conservant la boîte ayant le score de confiance le plus élevé.
import numpy as np
def supprimer_non_maxima(boites, seuil_recouvrement=0.3):
if len(boites) == 0:
return []
# Conversion en float pour les calculs d'intersection
boites = boites.astype(float)
# Extraction des coordonnées et scores
x1 = boites[:,0]
y1 = boites[:,1]
x2 = boites[:,2]
y2 = boites[:,3]
scores = boites[:,4]
surfaces = (x2 - x1 + 1) * (y2 - y1 + 1)
indices = np.argsort(scores) # Tri par score croissant
boites_finales = []
while len(indices) > 0:
dernier = len(indices) - 1
idx_courant = indices[dernier]
boites_finales.append(idx_courant)
# Coordonnées de l'intersection maximale
x1_inter = np.maximum(x1[idx_courant], x1[indices[:dernier]])
y1_inter = np.maximum(y1[idx_courant], y1[indices[:dernier]])
x2_inter = np.minimum(x2[idx_courant], x2[indices[:dernier]])
y2_inter = np.minimum(y2[idx_courant], y2[indices[:dernier]])
l_inter = np.maximum(0, x2_inter - x1_inter + 1)
h_inter = np.maximum(0, y2_inter - y1_inter + 1)
# Calcul du taux de recouvrement (IoU)
recouvrement = (l_inter * h_inter) / surfaces[indices[:dernier]]
# Suppression des boîtes trop similaires
indices = np.delete(indices, np.concatenate(([dernier], np.where(recouvrement > seuil_recouvrement)[0])))
return boites[boites_finales].astype(int)
Application aux véhicules autonomes
Dans le contexte de la conduite autonome, la détection de piétons est un enjeu de sécurité critique. Les systèmes embarqués doivent traiter l'information en temps réel pour anticiper les comportements imprévisibles des piétons.
Pour pallier les limites des caméras seules (conditions de faible luminosité, occlusions), la fusion de capteurs est souvent employée. Les données visuelles sont ainsi combinées aux informations de profondeur issues des capteurs LiDAR ou radar, offrant une perception tridimensionnelle de l'environnement.
Les défis actuels résident dans la fiabilité des algorithmes face aux conditions météorologiques extrêmes et la nécessité de réduire la latence pour garantir une réaction instantanée du véhicule.