OpenCV

Conduite autonome : comment détecter les lignes d’une route

Détecter les voies de circulation est une étape incontournable pour la réalisation d’un système de conduite autonome. Il est, en effet, nécessaire de maintenir la voiture dans la bonne voie. Cette tâche peut être effectuée simplement en vision par ordinateur. Dans cet article, nous allons voir comment réaliser la détection de lignes à l’aide de Python et d’OpenCV.

Comment mettre en avant les lignes dans une image

Pour cet exemple, nous allons nous servir d’une vidéo d’une personne conduisant sur une autoroute que vous pouvez retrouver sur le site pixabay.

Nous commençons bien évidemment par importer les librairies OpenCV (L. 1) et Numpy (L. 2), puis nous ouvrons notre vidéo à la ligne 4. Enfin, nous récupérons chaque image de la vidéo (L. 6-7).

import cv2
import numpy as np 

cap=cv2.VideoCapture('Road-1101.mp4')

while True:
 ret,image = cap.read()

Définition d’une zone d’intérêt

Afin de faciliter les traitements, nous allons nous intéresser uniquement à ce qu’il se passe devant la voiture. Pour ce faire, nous allons créer un masque afin de conserver uniquement notre zone d’intérêt.

Nous commençons par créer une image noire (tous les pixels à zéro) de même dimension que l’image d’origine (L. 9). Nous utilisons ensuite la fonction fillPoly (L. 10), afin que les pixels de notre zone d’intérêts ( compris dans entre les points (360,640), (660,440), (840,440) et (1240,640) ) soit en blanc (255,255,255).

 masque = np.zeros_like(image)
 cv2.fillPoly(masque, np.array([[[330,640],[660,440],[840,440],[1240,640]]]), (255,255,255))

Nous obtenons alors le masque suivant :

Masque utilisé

Nous appliquons enfin ce masque à l’image du flux vidéo :

 imageMasquee = cv2.bitwise_and(image, masque)
Application du masque sur l’image d’origine

Prétraitements pour la détection des lignes

Maintenant que notre zone d’intérêt est définie, nous pouvons passer à la suite. Nous cherchons à mettre en avant les lignes sur la route. Ces lignes sont, le plus fréquemment sur nos routes, de couleur blanche. Afin de les mettre en avant, nous pouvons effectuer un seuillage.

Nous commençons par convertir l’image masquée (RGB) en image en niveau de gris (L. 13), puis nous effectuons un seuillage binaire sur cette image (L. 14). Nous partons du principe que les pixels ayant une valeur supérieure à 175, sont représentatifs des lignes.

 imageGris = cv2.cvtColor(imageMasquee,cv2.COLOR_BGR2GRAY)
 ret, imageSeuillee = cv2.threshold(imageGris, 175, 255, cv2.THRESH_BINARY)
Image seuillée

Afin de faciliter la détection des lignes, nous appliquons un flou gaussien à la ligne 15. Enfin, nous utilisons un filtre de Canny (L. 16) afin de mettre en évidence les contours des lignes.

 imageFloue = cv2.GaussianBlur(imageSeuillee,(7,7),0)
 imageCanny = cv2.Canny(imageFloue, 100, 150)
Image après application du filtre de Canny

Détection des lignes

Afin de détecter les lignes dans l’image, nous utilisons la transformée de Hough, qui est une méthode simple de détection de lignes, à travers la fonction HoughLinesP :

 lines = cv2.HoughLinesP(imageCanny, rho = 1, theta = np.pi/180, threshold = 30 , minLineLength= 20 , maxLineGap=20)

Une fois les lignes détectées, nous pouvons les tracer sur l’image. Pour chaque ligne (L. 19), nous récupérons les coordonnées en x et en y (L. 20), puis nous les ajoutons à l’image avec la fonction line (L. 21).

Il nous reste plus qu’à afficher l’image (L. 22-23) et à définir une condition d’arrêt (L. 24-25) : lorsque la touche échap est pressée.

 lines = cv2.HoughLinesP(imageCanny, rho = 1, theta = np.pi/180, threshold = 30 , minLineLength= 20 , maxLineGap=20)
 for line in lines :
  for x1,y1,x2,y2 in line:
   cv2.line(image, (x1, y1), (x2, y2), [255,0,0], 2)
 
 cv2.imshow('frame',image)
 k = cv2.waitKey(100)
 if k== 27:
  break

Conclusion

Dans cet article, nous avons vu comment mettre en place un système de détection des lignes, pouvant être utilisé pour des voitures autonomes. Bien évidemment, d’autres fonctionnalités doivent cependant être ajoutées afin de rendre la conduite complètement autonome comme par exemple un système de détection de panneaux.

Florent

Share
Published by
Florent

Recent Posts

Capturer une image avec la caméra du Raspberry

Dans cet article, nous allons voir comment capturer simplement une image grâce au module raspicam…

4 mois ago

Détecter les repères faciaux (facial landmarks) avec Dlib

Aujourd’hui nous allons utiliser Dlib et OpenCV pour détecter les repères faciaux (facial landmarks) dans…

2 ans ago

Reconnaissance d’objets en temps réel avec MobileNet

Nous avons vu dans un précédent article comment utiliser l’algorithme MobileNetSSD pour la reconnaissance d’objet…

2 ans ago

Reconnaissance d’objet avec MobileNet et OpenCV

Dans cet article, nous nous intéressons à l’utilisation des réseaux de neurones convolutifs dans le…

2 ans ago

Où est Charlie ?

Derrière ce titre un peu trompeur, nous n’allons pas trouver Charlie dans une image, mais…

2 ans ago

Cheat Sheet OpenCV

Vous trouverez dans cet article une cheat sheet rassemblant un ensemble de fonctions d’OpenCV utilisable…

2 ans ago