ANPR con YOLOV8

ANPR con YOLOV8

Foto de Semyon Borisov en Unsplash

Introducción:

YOLO V8 es el último modelo desarrollado por el equipo de Ultralytics. Es un modelo YOLO de última generación que supera a sus predecesores en términos de precisión y eficiencia.

https://github.com/ultralytics/ultralytics

Es fácil de usar y accesible desde la línea de comandos o a través del paquete de Python. Ofrece soporte listo para usar para tareas de detección, clasificación y segmentación de objetos. Recientemente agregó soporte nativo para el seguimiento de objetos, por lo que no tendremos que lidiar con clonar repositorios de algoritmos de seguimiento.

En este artículo, repasaré los pasos para utilizar YOLOV8 y construir una herramienta de reconocimiento automático de matrículas de vehículos (ANPR). Así que empecemos.

Seguimiento de vehículos:

Como mencionamos anteriormente, YOLOV8 tiene seguimiento nativo, por lo que este paso es bastante sencillo. Primero, instale el paquete ultralytics

pip install ultralytics

Luego, debemos leer los fotogramas de video con OpenCV y aplicar el método de seguimiento del modelo con el argumento persist establecido en True para garantizar que los identificadores persistan en el siguiente fotograma. El modelo devuelve las coordenadas para dibujar un cuadro delimitador, junto con el identificador, etiqueta y puntuación.

import cv2from ultralytics import YOLOmodel = YOLO('yolov8n.pt')cap = cv2.VideoCapture("test_vids/vid1.mp4")ret = Truewhile ret:    # Leer un fotograma de la cámara    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            # verifique si se cumple el umbral y si el objeto es un automóvil            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)]

aquí está el resultado en un fotograma:

imagen proporcionada por el autor

Luego, se utilizan las coordenadas de los cuadros delimitadores para recortar cada automóvil en el fotograma y obtener una imagen.

Reconocimiento de matrículas:

Ahora que tenemos nuestros automóviles, necesitamos detectar las matrículas, para eso, necesitamos entrenar el modelo Yolo. Para eso, utilicé el siguiente conjunto de datos de Kaggle.

Detección de matrículas de automóviles

433 imágenes de matrículas

www.kaggle.com

Sin embargo, las etiquetas en este conjunto de datos están en formato XML de 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 necesita las anotaciones de cada imagen en un archivo con el siguiente formato: etiqueta, centro x, centro y, ancho, alto

Este código maneja esa transformación de nuestros datos:

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:                # Escribir una línea en el archivo                file.write(f"{line}\n")

ahora, lo único que queda es configurar nuestro archivo de configuración yaml con las rutas a las carpetas de datos de entrenamiento y validación, luego entrenar el modelo (nota: los nombres de las carpetas dentro de las carpetas de entrenamiento y validación deben ser etiquetas e imágenes). Luego, lo pasamos como argumento a nuestra instancia del modelo y comenzamos el entrenamiento

path: C:/Users/msi/PycharmProjects/ANPR_Yolov8train: trainval: val# Classesnames:  0: matrícula

model = YOLO('yolov8n.yaml')result = model.train(data="config.yaml",device="0",epochs=100,verbose=True,plots=True,save=True)
imagen por autor

Ahora que tenemos nuestro modelo de matrícula, simplemente tenemos que cargarlo y usarlo en las imágenes de coches recortadas del video, aplicamos escala de grises en el recorte de la matrícula y usamos easy_ocr para leer su contenido

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("No se detectó matrícula")           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 función update_csv escribirá el ID del coche y el número de matrícula en un archivo CSV. Y eso es el pipeline de ANPR con yolov8

imagen por autor

Conclusión:

Como vimos, YOLOV8 simplifica el proceso de construir un pipeline de ANPR ya que ofrece seguimiento nativo y detección de objetos.

este repositorio contiene el proyecto completo donde construí una aplicación de ANPR con streamlit:

GitHub – skandermenzli/ANPR_Yolov8

Contribuye al desarrollo de skandermenzli/ANPR_Yolov8 creando una cuenta en GitHub.

github.com

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

Share:

Was this article helpful?

93 out of 132 found this helpful

Discover more

Inteligencia Artificial

Ya está mucho más allá de lo que los humanos pueden hacer' ¿Eliminará la IA a los arquitectos?

Está revolucionando la construcción, pero ¿podría la inteligencia artificial eliminar toda una profesión?

Inteligencia Artificial

Conoce a WebAgent el nuevo LLM de DeepMind que sigue instrucciones y completa tareas en sitios web

La integración entre modelos de lenguaje grandes (LLMs) y sitios web es una de las áreas que puede desbloquear una nu...

Inteligencia Artificial

Aprendiendo el lenguaje de las moléculas para predecir sus propiedades

Este sistema de IA solo necesita una pequeña cantidad de datos para predecir propiedades moleculares, lo que podría a...

Inteligencia Artificial

Esta herramienta podría proteger tus imágenes de la manipulación de IA

PhotoGuard, creado por investigadores del MIT, altera las fotos de formas imperceptibles para nosotros pero evita que...