Implémentation d'un système de détection de piétons avec Python et OpenCV

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.

Étiquettes: Python OpenCV HOG svm réseaux de neurones convolutifs

Publié le 16 juillet à 20h46