Dans l’article d’aujourd’hui, nous allons nous intéresser à la lecture des plaques d’immatriculation des voitures. Pour ce faire, nous allons nous appuyer sur l’article Automatic License Plate Recognition using Python and OpenCV de K.M. Sajjad. Cette méthode s’appuie sur l’utilisation de la bibliothèque de reconnaissance de caractère Tesseract que nous avons déjà utilisé.

Afin de pouvoir lire une plaque d’immatriculation, plusieurs opérations sont réalisées. Dans un premier temps, des prétraitements sont appliqués afin de faciliter les analyses ultérieures de l’image. Afin de localiser la plaque, l’image est seuillée afin de mettre en avant les zones blanches de l’image pouvant correspondre à une plaque d’immatriculation. Enfin, la reconnaissance de caractère est appliquée afin d’obtenir l’immatriculation de la voiture.

Maintenant que notre plan d’action est défini, nous pouvons passer à la partie Python avec OpenCV.

Prétraitements de l’image

Avant de pouvoir commencer, nous importons les bibliothèques nécessaires, à savoir OpenCV, Numpy et Tesseract :

import cv2
import numpy as np
import pytesseract

L’étape inévitable qui suit est de charger l’image que nous souhaitons analyser:

img = cv2.imread('image.jpg')

Nous pouvons maintenant passer aux prétraitements. Deux opérations seront à réaliser : convertir l’image RGB en niveau de gris, puis effectuer un seuillage afin de mettre en avant les zones claires, correspondant potentiellement aux plaques d’immatriculation.

img_gris = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
seuil, img_seuil = cv2.threshold(img_gris, 80, 255, cv2.THRESH_BINARY)

Nous pouvons maintenant passer à l’étape suivante, à savoir, extraire les plaques d’immatriculation de l’image.

Extraction des plaques d’immatriculation

Comme l’étape précédente nous à permis de mettre en avant les zones claires, nous allons commencer par utiliser une extraction de contours afin d’extraire de l’image les coordonnées des zones blanches :

contours, _ = cv2.findContours(img_seuil, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

Du fait qu’il est fort probable que de nombreuses zones claires soient présentes dans l’image, il est nécessaire de devoir écarter celles ne correspondant pas aux plaques d’immatriculation. Pour ce faire, nous pouvons effectuer un seuillage dimensionnel :

kernel = np.ones((5, 5), np.uint8)
for cnt in contours:
	(x, y, w, h) = cv2.boundingRect(cnt)
	if (w >= 3 * h) & (w < 6 * h) & (w * h > 5000) & (w * h < 50000):
		img_crop = img_seuil[y:y + h, x:x + w]
		img_resize = cv2.resize(img_crop, (0, 0), fx=5, fy=5)
		img_corrige = cv2.morphologyEx(img_resize, cv2.MORPH_OPEN, kernel)

Pour chaque contour (l. 13), nous calculons alors le rectangle encadrant (l.14), afin de pouvoir effectuer le seuillage dimensionnel à la ligne 15.

Pour les dimensions, nous cherchons un rectangle, dont la largeur est entre 3 et 5 fois plus grande que la hauteur. En effet, les plaques d’immatriculation européenne ont, en générale, une taille de 520mm par 110mm soit un ratio d’environ 4,7 entre la largeur et la hauteur.

Nous ajoutons à cela un seuil sur l’aire de la plaque afin de ne conserver uniquement les zones blanches d’une taille proche de celles d’une plaque d’immatriculation. Ces valeurs dépendent de la taille de l’image et il est important de les ajuster en fonction des conditions d’acquisitions.

Lorsque l’on trouve une zone pouvant correspondre à une plaque, nous extrayons cette zone de l’image seuillée (l.16), puis augmentons la taille de l’image extraite (l. 17) . Cette opération est réalisée afin de faciliter la détection de caractère par tesseract.

Enfin, avant de passer à la lecture de la plaque, nous appliquons une fermeture (l.18), grâce au kernel défini à la ligne 12, afin d’améliorer l’image finale.

Exemples de zones extraites pour la lecture de plaques d'immatriculation
Exemples de zones extraites

Lecture de l’immatriculation

Nous pouvons donc maintenant passer à l’étape qui nous intéresse le plus : la lecture de l’immatriculation !

		txt = pytesseract.image_to_string(img_corrige,config='--psm 7')
		if (txt != ''):
			cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 5)
			cv2.putText(img, txt, (x, y - 15),cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 3)
		else:
			cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 5)
cv2.imshow('image', img)
cv2.waitKey(0)

Pour ce faire, nous appelons la fonction image_to_string() de la bibliothèque tesseract, que nous avions déjà utilisé dans cet article. Du fait que les caractères dans les plaques d’immatriculation soient alignés, nous spécifions en configuration l’argument « –psm 7 » qui permet de considérer que l’image ne contient qu’une seule ligne de texte. Pour plus de détails sur les options disponibles, je vous invite à consulter le manuel de tesseract.

Dans le cas où un texte est trouvé (l. 21), nous affichons un rectangle de couleur vert autour de la plaque (l. 22) et nous ajoutons le texte retourné sur l’image (l. 23). Dans le cas contraire, nous affichons un rectangle rouge (l. 25).

Enfin, nous pouvons afficher l’image résultante ligne 26-27.

Nous arrivons, pour chaque image, à retrouver les plaques d’immatriculation. De plus, le nombre de zones autres que des plaques et relativement faible. Cependant, comme nous pouvons le voir, le résultat n’est pas parfait. Afin d’améliorer les résultats, il serait possible de mettre en place un certain nombre de corrections.

Sur de nombreuses images, un caractère est ajouté avant ceux de la plaque. La détection de la partie bleue de la plaque permettrait de ne pas la prendre en compte lors de la lecture de la plaque et ainsi éviter de prendre en compte un caractère supplémentaire.

Si nous nous intéressons à des plaques d’immatriculation d’un seul pays, alors nous pouvons utiliser les normes en vigueurs. Par exemple, en France, les plaques ont une numérotation de la forme AA 000 AA.


4 commentaires

Boka · 29 août 2019 à 12 h 33 min

SVP pouvez-vous mettre le fichier python à télécharger. On en a besoin. Merci pour tout.

    Florent · 30 août 2019 à 14 h 13 min

    Bonjour,
    Le code entier se trouve dans l’article.

Boka · 30 août 2019 à 13 h 20 min

SVP comment éliminer la partie bleu e lors de la détection des caractères ?

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.