ANPR avec YOLOV8

ANPR avec YOLOV8' -> 'ANPR avec YOLOV8

Photo de Semyon Borisov sur Unsplash

Introduction :

YOLO V8 est le dernier modèle développé par l’équipe d’Ultralytics. C’est un modèle YOLO de pointe qui dépasse ses prédécesseurs en termes de précision et d’efficacité.

https://github.com/ultralytics/ultralytics

Il est facile à utiliser et accessible en ligne de commande ou via le package Python. Il offre une prise en charge prête à l’emploi pour la détection d’objets, la classification et les tâches de segmentation. Il a récemment ajouté une prise en charge native pour le suivi d’objets, de sorte que nous n’aurons pas à nous préoccuper de cloner des dépôts d’algorithmes de suivi.

Dans cet article, je vais passer en revue les étapes de l’utilisation de YOLOV8 pour construire un outil de reconnaissance automatique des plaques d’immatriculation (ANPR). Alors, commençons.

Suivi des véhicules :

Comme nous l’avons mentionné précédemment, YOLOV8 dispose d’un suivi natif, donc cette étape est assez simple. Tout d’abord, installez le package Ultralytics

pip install ultralytics

Ensuite, nous devons lire les images vidéo avec OpenCV et appliquer la méthode de suivi du modèle avec l’argument persist réglé sur True pour garantir que les identifiants persistent dans le cadre suivant. Le modèle renvoie les coordonnées pour dessiner une boîte englobante ainsi que l’identifiant, l’étiquette et le score

import cv2from ultralytics import YOLOmodel = YOLO('yolov8n.pt')cap = cv2.VideoCapture("test_vids/vid1.mp4")ret = Truewhile ret:    # Lire un cadre de la caméra    ret, frame = cap.read()    if ret and frame_nbr % 10 == 0 :        results = model.track(frame,persist=True)        for result in results[0].boxes.data.tolist():            x1, y1, x2, y2, id, score,label = result            # Vérifier si le seuil est atteint et si l'objet est une voiture            if score > 0.5 and label==2:                cv2.rectangle(frame, (int(x1), int(y1)), (int(x2), int(y2)), (0, 255, 0), 4)                text_x = int(x1)                text_y = int(y1) - 10                cv2.putText(frame, str(id), (text_x, text_y),                           cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 2)                cropped_img = frame[int(y1):int(y2), int(x1):int(x2)]

Voici le résultat sur une image :

image fournie par l'auteur

Les coordonnées des boîtes englobantes sont ensuite utilisées pour recadrer chaque voiture dans l’image.

Reconnaissance des plaques d’immatriculation :

Maintenant que nous avons nos voitures, nous devons détecter les plaques d’immatriculation, pour cela, nous devons entraîner le modèle Yolo. Pour cela, j’ai utilisé l’ensemble de données Kaggle suivant.

Détection des plaques d’immatriculation de voiture

433 images de plaques d’immatriculation

www.kaggle.com

Cependant, les étiquettes de cet ensemble de données sont au format XML PASCAL VOC :

<annotation>    <folder>images</folder>    <filename>Cars105.png</filename>    <size>        <width>400</width>        <height>240</height>        <depth>3</depth>    </size>    <segmented>0</segmented>    <object>        <name>licence</name>        <pose>Unspecified</pose>        <truncated>0</truncated>        <occluded>0</occluded>        <difficult>0</difficult>        <bndbox>            <xmin>152</xmin>            <ymin>147</ymin>            <xmax>206</xmax>            <ymax>159</ymax>        </bndbox>    </object></annotation>

YOLO a besoin des annotations de chaque image dans un fichier avec le format suivant: étiquette, centre x, centre y, largeur, hauteur

Ce code gère cette transformation de nos données:

def xml_to_yolo(bbox, w, h):    # xmin, ymin, xmax, ymax    x_center = ((bbox[2] + bbox[0]) / 2) / w    y_center = ((bbox[3] + bbox[1]) / 2) / h    width = (bbox[2] - bbox[0]) / w    height = (bbox[3] - bbox[1]) / h    return [x_center, y_center, width, height]def convert_dataset():    for filename in os.listdir("annotations"):        tree = ET.parse(f"annotations/{filename}")        root = tree.getroot()        name = root.find("filename").text.replace(".png", "")        width = int(root.find("size").find("width").text)        height = int(root.find("size").find("height").text)        for obj in root.findall('object'):            box = []            for x in obj.find("bndbox"):                box.append(int(x.text))            yolo_box = xml_to_yolo(box, width, height)            line = f"0 {yolo_box[0]} {yolo_box[1]} {yolo_box[2]} {yolo_box[3]}"            with open(f"train/labels/{name}.txt", "a") as file:                # Écrire une ligne dans le fichier                file.write(f"{line}\n")

maintenant, il ne reste plus qu’à configurer notre fichier de configuration yaml avec les chemins vers les dossiers de données d’entraînement et de validation, puis entraîner le modèle note (les noms de dossier à l’intérieur des dossiers d’entraînement et de validation doivent être labels et images). Ensuite, nous le passons en argument à notre instance de modèle et commençons l’entraînement

path: C:/Users/msi/PycharmProjects/ANPR_Yolov8train: trainval: val# Classesnames:  0: plaque d'immatriculation

model = YOLO('yolov8n.yaml')result = model.train(data="config.yaml",device="0",epochs=100,verbose=True,plots=True,save=True)
image by author

Maintenant que nous avons notre modèle de plaque d’immatriculation, il nous suffit de le charger et de l’utiliser sur les images de voiture recadrées de la vidéo, nous appliquons le niveau de gris sur le recadrage de la plaque d’immatriculation et utilisons easy_ocr pour lire son contenu

cropped_img = frame[int(y1):int(y2), int(x1):int(x2)]plates = lp_detector(cropped_img)for plate in plates[0].boxes.data.tolist():    if score > 0.6:          x1, y1, x2, y2, score, _ = plate          cv2.rectangle(cropped_img, (int(x1), int(y1)), (int(x2), int(y2)), (255, 0, 0), 2)          lp_crop = cropped_img[int(y1):int(y2), int(x1):int(x2)]          lp_crop_gray = cv2.cvtColor(lp_crop, cv2.COLOR_BGR2GRAY)          ocr_res = reader.readtext(lp_crop_gray)          if not ocr_res:                print("Aucune plaque détectée")           else:               entry = {'id': id, 'number': ocr_res[0][1], 'score': ocr_res[0][2]}               update_csv(entry)               out.write(frame)                cv2.imshow('frame', frame)        frame_nbr += 1

la fonction update_csv écrira l’identifiant de la voiture et le numéro de plaque d’immatriculation dans un fichier CSV. Et voilà le pipeline ANPR avec yolov8

image by author

Conclusion:

Comme nous l’avons vu, YOLOV8 simplifie le processus de construction d’un pipeline ANPR car il offre un suivi natif et une détection d’objets.

ce dépôt contient le projet complet où j’ai construit une application ANPR avec streamlit:

GitHub – skandermenzli/ANPR_Yolov8

Contribuer au développement de skandermenzli/ANPR_Yolov8 en créant un compte sur GitHub.

github.com

We will continue to update IPGirl; if you have any questions or suggestions, please contact us!

Share:

Was this article helpful?

93 out of 132 found this helpful

Discover more

AI

Les employés veulent ChatGPT au travail. Les patrons craignent qu'ils ne révèlent des secrets.

Certains dirigeants d'entreprise ont interdit l'utilisation d'outils d'intelligence artificielle générative en raison...

Science des données

Créer un avantage informationnel avec un accès conversationnel aux données

À mesure que notre monde devient de plus en plus global et dynamique, les entreprises dépendent de plus en plus des d...