Implementación de Detección de Tráfico con YOLOv8n: Una Guía Paso a Paso
En este artículo, vamos a explorar cómo se puede utilizar un modelo de detección de objetos como YOLOv8n de Ultralytics junto con OpenCV para identificar y capturar imágenes de vehículos dentro de un área específica en un video. El código que discutiremos realiza la detección en tiempo real y guarda imágenes de los vehículos cuando se encuentran dentro de una zona predefinida. También guarda un registro en un archivo CSV.
Requisitos Previos
Antes de comenzar, asegúrate de tener instaladas las siguientes bibliotecas:
- OpenCV
- Ultralytics YOLO
- Supervision (opcional, comentado en el código)
- Pathlib
pip install opencv-python-headless ultralytics
Estructura del proyecto:
SIG
├── src
│ ├── operations
│ │ ├── capture.py
│ │ ├── write_to_csv.py
│ ├── detection.py
├── models
│ ├── yolov8n.pt
├── utils
│ ├── traffic.mp4
├── reports
│ ├── logdetection.csv
│ ├── capture
└── README.md
Código y Explicación
Primero, importamos las librerías necesarias:
pip install opencv-python
pip install numpy
pip install ultralytics
Configuración Inicial
Definimos las rutas y cargamos el modelo YOLO:
model_path = Path('models/yolov8n.pt')
video_path = Path('utils/traffic.mp4')
reports_folder = Path('reports')
model = YOLO(model_path)
Definición de la Zona Fija
Establecemos las coordenadas de la zona fija donde queremos monitorear la presencia de vehículos, es importante resaltar que usando la libreria SuperVision lograriasmos mejores resultados:
fixed_zone_xmin = 950
fixed_zone_ymin = 500
fixed_zone_xmax = 1200
fixed_zone_ymax = 600
Configuración de Archivos de Captura y Registro
Creamos las carpetas y archivos necesarios para almacenar las capturas y los registros:
csv_file = reports_folder / 'logdetection.csv'
capture_folder = reports_folder / 'capture'
capture_folder.mkdir(parents=True, exist_ok=True)
csv_file.touch(exist_ok=True)
Código de Implementación
A continuación, presento el código que captura video, detecta objetos y almacena las detecciones relevantes en un archivo CSV:
import cv2
from time import time
from datetime import datetime
from pathlib import Path
from ultralytics import YOLO
#Importaciones del modulo operations
from operations.capture import capture_image
from operations.csv_operations import write_to_csv
# Ruta al modelo y al video
model_path = Path('models/yolov8n.pt')
video_path = Path('utils/traffic.mp4')
reports_folder = Path('reports')
# Cargar el modelo YOLO
model = YOLO(model_path)
# Coordenadas de la zona fija de detección
fixed_zone_xmin = 950
fixed_zone_ymin = 500
fixed_zone_xmax = 1200
fixed_zone_ymax = 600
# Configuración de archivos y carpetas
csv_file = reports_folder / 'logdetection.csv'
capture_folder = reports_folder / 'capture'
capture_folder.mkdir(parents=True, exist_ok=True)
csv_file.touch(exist_ok=True)
# Captura de video
cap = cv2.VideoCapture(str(video_path))
# Tiempo de inicio y intervalo de reporte
start_time = time()
report_interval = 3 # en segundos
while True:
ret, frame = cap.read()
if not ret:
break
# Detección de objetos en el frame actual
detections = model(frame)[0]
for box in detections.boxes:
label = model.names[box.cls.item()]
if label == "car":
xmin, ymin, xmax, ymax = map(int, box.xyxy[0].tolist())
# Dibujar el cuadro delimitador y la etiqueta
cv2.rectangle(frame, (xmin, ymin), (xmax, ymax), (0, 0, 255), 2)
cv2.putText(frame, label, (xmin, ymin - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
# Verificar si el objeto está dentro de la zona fija
if (xmin < fixed_zone_xmax and xmax > fixed_zone_xmin and
ymin < fixed_zone_ymax and ymax > fixed_zone_ymin):
current_time = time()
if current_time - start_time >= report_interval:
capture_path = capture_image(frame, xmin, ymin, xmax, ymax, quality=50)
data = {
'label': label,
'fecha': datetime.now().date(),
'hora': datetime.now().time(),
'captura': str(capture_path)
}
write_to_csv(data, str(capture_path))
start_time = current_time
cv2.putText(frame, "Captura", (xmin, ymin - 30), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 2)
# Dibujar la zona fija
cv2.rectangle(frame, (fixed_zone_xmin, fixed_zone_ymin), (fixed_zone_xmax, fixed_zone_ymax), (255, 0, 0), 2)
# Mostrar el frame con las detecciones
cv2.imshow("YOLO Object Detection", frame)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
cap.release()
cv2.destroyAllWindows()
Funciones necesarias del proyecto:
(capture.py) Este código define una función para capturar y guardar imágenes de una región específica en un marco de video, La función capture_image
toma un marco de video y coordenadas que delimitan una región específica, captura esa región como una imagen JPEG, y la guarda en una carpeta designada con un nombre único basado en la fecha y hora actuales. Esta función es útil en aplicaciones donde se necesita guardar imágenes de objetos detectados en tiempo real, como en la monitorización de tráfico o sistemas de seguridad.
import cv2
from datetime import datetime
from pathlib import Path
capture_folder = Path('reports\capture')
capture_folder.mkdir(parents=True, exist_ok=True)
def capture_image(frame, xmin, ymin, xmax, ymax, quality=50):
area_detected = frame[ymin:ymax, xmin:xmax]
encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), quality]
_, img_encode = cv2.imencode('.jpg', area_detected, encode_param)
area_detected = cv2.imdecode(img_encode, 1)
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
capture_path = capture_folder / f"capture_{timestamp}.jpg"
cv2.imwrite(str(capture_path), area_detected)
return str(capture_path)
(write_to_csv.oy) La función write_to_csv
permite registrar datos de detecciones de objetos en un archivo CSV, lo que facilita el seguimiento y análisis de eventos detectados en tiempo real. Esta función es especialmente útil en aplicaciones de vigilancia y monitoreo, donde se necesita un registro detallado de las detecciones y sus correspondientes imágenes capturadas.
import csv
from datetime import datetime
from pathlib import Path
csv_file = Path('reports\logdetection.csv')
csv_file.touch(exist_ok=True)
fieldnames = ['label', 'fecha', 'hora', 'captura']
def write_to_csv(data, capture_path):
with open(csv_file, mode='a', newline='') as file:
writer = csv.DictWriter(file, fieldnames=fieldnames)
data['captura'] = capture_path
writer.writerow(data)
Conclusión:
El código implementa un sistema de detección de tráfico utilizando el modelo YOLOv8n en Python. Se carga un modelo pre-entrenado de YOLOv8n para detectar objetos en tiempo real en cada frame de un video utilizando OpenCV.
Marcando el siguiente proceso, se define una zona fija dentro del video para monitorear las detecciones de objetos, específicamente coches, mejorando la eficiencia de las capturas. Cuando un coche es detectado dentro de esta zona fija y ha pasado un intervalo de tiempo específico, se captura una imagen del coche y se registra la información en un archivo CSV, incluyendo la fecha, hora y ruta de la captura. Los cuadros delimitadores y las etiquetas se dibujan en tiempo real sobre los objetos detectados para una visualización clara.
Este sistema es una base eficiente y ampliable para proyectos de detección de tráfico y análisis de datos en tiempo real. Gracias!