Quand une voiture autonome est en mouvement, il est important qu'elle sache reconnaître les objets qui l'entourent : véhicules, piétons, cyclistes, les panneaux de signalisation. Pour suivre la route, elle doit savoir en particulier reconnaître les bordures, les lignes blanches, les trottoirs, etc.
Pour cela, les photos réalisées par ses capteurs sont traitées par des algorithmes qui permettent de détecter les contours des objets qu'elle rencontre. L'objectif de cette activité est de découvrir le fonctionnement d'un de ces algorithmes de détection de contours.
Pour repérer la position d'un pixel, on repère d'abord la colonne x à laquelle il appartient, puis la ligne y. Notons un tel pixel P(x, y) et NG(x, y) son niveau de gris.
Pour détecter si le pixel P(x, y) appartient ou non à un contour, la méthode consiste à chercher une rupture d'intensité entre 2 pixels symétriques par rapport à P(x, y), appelés pixel voisins. Pour cela on calcule la différence entre les niveaux de gris de 2 pixels voisins. Si cette différence est assez élevée, le pixel fait parti du contour.
Attention : En python le premier pixel en haut à gauche a pour coordonnées (0, 0) et non (1, 1).
Dans l'exemple précédent, seul un couple de pixels voisins est pris en compte dans une unique direction. Pour détecter des contours sur deux directions différentes, il faut prendre en compte deux couples de pixels voisins (voir schéma).
Pour cela, il faut calculer pour chacun la différence des niveaux de gris et afin de pouvoir les ajouter sans que les différences s'annulent du fait des valeurs négatives, il faudra élever leur valeur au carré.
Programmation de la détection de contours dans une image
L'algorithme permettant d'afficher les contours des objets sur une image a été partiellement programmé en python dans l'éditeur ci-dessous.
from PIL import Image
def contour(filename): # Crée la fonction contour
im = Image.open(filename) # Ouvre le fichier image
im_contour = Image.new(im.mode, im.size) # Crée une image vide de même taille
colonne, ligne = im.size
for y in range(1, ligne-1): # Boucles pour balayer les pixels sauf en bordure
for x in range(1, colonne-1):
a = im.getpixel((x-1, y-1)) # pixel au dessus à gauche
b = im.getpixel(( ... , ... )) # pixel en dessous à droite
c = ... # pixel au dessus à droite
d = ... # pixel en dessous à gauche
formule = (a-b)**2 + (c-d)**2
if formule > 800: # Test de contour Si le résultat est supérieur à 800
im_contour.putpixel((x, y), 0) # Colore en noir
else : # Sinon
im_contour.putpixel((x, y), 255) # Colore en blanc
return im_contour # Renvoi l'image avec les contours
im = contour("route_01.png") # Appele la fonction pour l'appliquer
im.show() # Affichage de l'image
im.save("contour.png","PNG") # Sauvegarde de l'image