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 :

Nous appliquons enfin ce masque à l’image du flux vidéo :
imageMasquee = cv2.bitwise_and(image, masque)

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)

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)

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:
breakConclusion
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.
