tutoriales.com

Seguimiento de Objetos en Movimiento con DeepSORT y YOLOv8 en Python

Este tutorial práctico te guiará en la construcción de un sistema de visión artificial capaz de detectar y rastrear múltiples objetos simultáneamente utilizando YOLOv8 para la detección de alta precisión y DeepSORT para la asignación de identidades consistentes en secuencias de video.

Intermedio12 min de lectura49 views
Reportar error

Introducción al Rastreo y Detección de Objetos

El análisis de video en tiempo real es uno de los campos más fascinantes y de mayor crecimiento dentro de la inteligencia artificial y la visión artificial. Mientras que la detección de objetos nos permite identificar qué hay en una imagen y dónde está en un momento dado, el seguimiento de objetos (Object Tracking) va un paso más allá al mantener una identidad única para cada objeto a lo largo de una secuencia de cuadros.

En este tutorial completo, combinaremos dos de las herramientas más potentes del ecosistema actual:

  • YOLOv8 (You Only Look Once v8): Desarrollado por Ultralytics, es el estado del arte en detección de objetos por su increíble velocidad y precisión.
  • DeepSORT (Simple Online and Realtime Tracking with a Deep Association Metric): Un algoritmo robusto que utiliza filtros de Kalman y redes neuronales profundas para asociar características de apariencia y mantener las identidades de los objetos incluso cuando se ocluyen temporalmente.

Al finalizar este tutorial, serás capaz de desplegar tu propio sistema capaz de contar personas, seguir vehículos en autopistas o analizar flujos de tráfico con código totalmente funcional en Python.

📌 Nota: Este tutorial está diseñado para desarrolladores con conocimientos básicos de Python y conceptos generales de aprendizaje automático.

Requisitos Previos y Configuración del Entorno

Antes de escribir código, debemos preparar nuestro entorno de desarrollo. Necesitaremos instalar Python (recomendamos la versión 3.10 o superior) y las bibliotecas necesarias para el procesamiento de imágenes y modelos de aprendizaje profundo.

Instalación de Dependencias

Abre tu terminal o consola de comandos y crea un entorno virtual para mantener tu proyecto limpio y ordenado. Luego, instala los paquetes requeridos:

python -m venv venv
source venv/bin/activate  # En Windows usa: venv\Scripts\activate
pip install --upgrade pip
pip install ultralytics opencv-python numpy filterpy

Verificación de la Instalación

Para asegurarte de que todo funciona correctamente, puedes ejecutar un breve script de prueba para comprobar que PyTorch y OpenCV reconocen tu hardware (CPU o GPU):

import cv2
import ultralytics

print("Versión de OpenCV:", cv2.__version__)
print("Versión de Ultralytics:", ultralytics.__version__)
ultralytics.checks()
💡 Consejo: Si dispones de una tarjeta gráfica NVIDIA compatible con CUDA, asegúrate de instalar la versión de PyTorch con soporte para GPU para acelerar drásticamente el rendimiento del rastreo.

Arquitectura del Sistema: ¿Cómo Funciona YOLOv8 + DeepSORT?

Para entender el código que escribiremos más adelante, es fundamental comprender cómo interactúan la detección y el seguimiento. El proceso ocurre en cada cuadro de video de forma secuencial.

1. Cuadro de Video 2. Detección YOLOv8 (Cajas Delimitadoras) Cajas + Cuadros 3. Proceso DeepSORT Filtro de Kalman Predicción de Movimiento Extractor de Apariencia (Deep ReID Features) Asociación de Datos (Asignación de IDs Únicos) 5. Salida de Video Final IDs Persistentes + Seguimiento Visual

El flujo de trabajo detallado consta de los siguientes pasos:

Paso 1 - Captura: El sistema lee un cuadro (frame) del archivo de video o cámara web.
Paso 2 - Detección: YOLOv8 procesa el cuadro y devuelve una lista de cajas delimitadoras con clases y puntuaciones de confianza.
Paso 3 - Predicción: El Filtro de Kalman predice la posición actual del objeto basándose en su trayectoria previa.
Paso 4 - Asociación: El algoritmo calcula la distancia de Mahalanobis y las características de apariencia (coseno de similitud) para vincular las detecciones actuales con los objetos rastreados existentes.
Paso 5 - Actualización: Se asignan los IDs definitivos, se actualizan las trayectorias y se renderizan los resultados en pantalla.

Implementación del Código Base

Vamos a construir nuestro script principal paso a paso. Crearemos un archivo llamado tracker.py en el directorio de tu proyecto.

Importación de Librerías y Carga del Modelo

Comenzaremos importando las librerías necesarias y cargando el modelo preentrenado de YOLOv8. Usaremos el modelo estándar yolov8n.pt (nano) por razones de velocidad, pero puedes cambiarlo a yolov8s.pt o superior si buscas mayor precisión.

import cv2
import numpy as np
from ultralytics import YOLO

# Cargar el modelo YOLOv8 preentrenado en COCO
model = YOLO("yolov8n.pt")

# Inicializar la captura de video (0 para webcam o ruta a archivo de video)
video_path = "tu_video_de_prueba.mp4"
cap = cv2.VideoCapture(video_path)

# Obtener propiedades del video
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = int(cap.get(cv2.CAP_PROP_FPS))

print(f"Video cargado correctamente: {width}x{height} a {fps} FPS")
⚠️ Advertencia: Asegúrate de reemplazar `tu_video_de_prueba.mp4` por la ruta real de un archivo de video en tu equipo, o cambia la variable a `0` si deseas probar con tu cámara web en tiempo real.

Integración del Rastreo Nativo y Personalizado

Aunque existen implementaciones externas complejas para DeepSORT, Ultralytics YOLOv8 incluye soporte nativo optimizado para algoritmos de seguimiento como BoT-SORT y ByteTRACK, los cuales ofrecen un rendimiento equivalente o superior a DeepSORT con menor complejidad de integración. A continuación, implementaremos el bucle de procesamiento utilizando el rastreador integrado de YOLOv8.

# Bucle principal de procesamiento de video
while cap.isOpened():
    success, frame = cap.read()
    
    if not success:
        print("Fin del video o error al leer el cuadro.")
        break

    # Ejecutar seguimiento con YOLOv8 (usando persist=True para mantener IDs)
    # Puedes cambiar tracker='botsort.yaml' o 'bytetrack.yaml'
    results = model.track(frame, persist=True, tracker="bytetrack.yaml", verbose=False)

    # Extraer cajas y resultados de seguimiento
    current_frame = results[0].plot()

    # Mostrar el resultado en una ventana interactiva
    cv2.imshow("Sistema de Seguimiento - Visión Artificial", current_frame)

    # Romper el bucle si se presiona la tecla 'q'
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# Liberar recursos
cap.release()
cv2.destroyAllWindows()

Filtrado y Análisis Avanzado de Trayectorias

Una vez que somos capaces de rastrear objetos y asignarles un identificador único (ID), el siguiente nivel en visión artificial consiste en extraer información analítica útil a partir de esas trayectorias.

Extracción de Coordenadas y Conteo de Objetos

Modificaremos nuestro bucle para acceder directamente a las coordenadas de las cajas delimitadoras (boxes), las confianzas y los identificadores de seguimiento (track_id), permitiéndonos contar cuántos objetos únicos han aparecido en la escena.

# Inicializar conjunto para almacenar IDs únicos detectados
seen_ids = set()

while cap.isOpened():
    success, frame = cap.read()
    if not success:
        break

    results = model.track(frame, persist=True, tracker="bytetrack.yaml", verbose=False)
    
    # Verificar si hay cajas detectadas con IDs de seguimiento
    if results[0].boxes.id is not None:
        boxes = results[0].boxes.xyxy.cpu().numpy()
        track_ids = results[0].boxes.id.int().cpu().numpy()
        confidences = results[0].boxes.conf.cpu().numpy()
        classes = results[0].boxes.cls.int().cpu().numpy()

        for box, track_id, conf, cls in zip(boxes, track_ids, confidences, classes):
            seen_ids.add(track_id)
            x1, y1, x2, y2 = map(int, box)
            class_name = model.names[cls]

            # Dibujar caja personalizada y etiqueta
            cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)
            label = f"{class_name} ID:{track_id} ({conf:.2f})"
            cv2.putText(frame, label, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)

    # Mostrar contador total en pantalla
    cv2.putText(frame, f"Objetos Únicos Totales: {len(seen_ids)}", (30, 50),
                cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)

    cv2.imshow("Análisis Avanzado", frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

Optimización del Rendimiento

Cuando trabajamos con secuencias de video en alta definición (1080p o 4K), el procesamiento por cuadro puede volverse lento. Aquí tienes una tabla comparativa de estrategias para optimizar tu sistema:

Estrategia de OptimizaciónDescripciónImpacto en PrecisiónImpacto en Velocidad
------------
Reducción de ResoluciónEscalar el video a 640x640 antes de la inferencia.BajoMuy Alto 🚀
Uso de Modelos Nano/SmallUtilizar yolov8n en lugar de yolov8m o yolov8x.ModeradoAlto ⚡
------------
Inferencia con TensorRTExportar el modelo a formato TensorRT para GPUs NVIDIA.NingunoExtremo 🔥
Salto de Cuadros (Frame Skipping)Procesar solo 1 de cada N cuadros para el rastreo.ModeradoAlto 📈
💡 Consejo: Si necesitas exportar tu modelo optimizado para producción, ejecuta yolo export model=yolov8n.pt format=engine para generar un motor TensorRT ultra rápido.

Preguntas Frecuentes (FAQ)

¿Qué diferencia hay entre ByteTRACK y DeepSORT? ByteTRACK es un algoritmo de seguimiento basado en la asociación de todas las cajas detectadas (incluso las de baja puntuación) en lugar de depender únicamente de la apariencia visual mediante redes neuronales secundarias. Esto lo hace generalmente más rápido y eficiente en escenarios concurridos.
¿Cómo puedo contar objetos que cruzan una línea virtual? Puedes definir una línea mediante dos puntos `(x1, y1)` y `(x2, y2)` en tu espacio de video y evaluar si las coordenadas del centroide o la base de la caja delimitadora cruzan dicha línea utilizando ecuaciones de producto cruzado vectorial.
¿Funciona este sistema con múltiples cámaras? Para múltiples cámaras se requiere un paso adicional llamado Re-Identificación (Re-ID) multicanal y correspondencia global, ya que el algoritmo estándar de este tutorial opera sobre una única fuente de video continua.

Conclusión

¡Felicidades! Has implementado con éxito un sistema completo de detección y seguimiento de objetos utilizando YOLOv8 y algoritmos de rastreo avanzados en Python. Este tipo de arquitecturas son la base fundamental para sistemas modernos de videovigilancia inteligente, análisis deportivo, vehículos autónomos y automatización industrial.

Te animamos a experimentar modificando los umbrales de confianza, probando diferentes modelos de YOLO y adaptando el código para resolver problemas específicos en tus propios proyectos de inteligencia artificial.

Tutoriales relacionados

Comentarios (0)

Aún no hay comentarios. ¡Sé el primero!