Seguimiento de objetos en video con OpenCV (MeanShift, CamShift)
En el campo de la visión por computadora, el seguimiento de objetos en video es una tarea muy importante.
El seguimiento de objetos en video se utiliza ampliamente en múltiples áreas como vigilancia, conducción autónoma e interacción persona-computadora.
OpenCV proporciona múltiples algoritmos de seguimiento de objetos, entre los cuales MeanShift y CamShift son dos algoritmos clásicos y de uso común. Este artículo explicará en detalle los principios, los pasos de implementación de estos dos algoritmos y cómo utilizarlos en OpenCV.
1. Algoritmo MeanShift
1.1 Principio del algoritmo
El algoritmo MeanShift (desplazamiento de la media) es un algoritmo de agrupamiento no paramétrico basado en densidad. Inicialmente se utilizó para la segmentación de imágenes y más tarde se introdujo en el campo del seguimiento de objetos. Su idea central es calcular de forma iterativa el centroide de la región objetivo y mover el centro de la ventana a la posición del centroide, logrando así el seguimiento del objeto.
Los pasos básicos del algoritmo MeanShift son los siguientes:
- Inicializar la ventana: En el primer fotograma del video, seleccione manual o automáticamente una región objetivo como ventana inicial.
- Calcular el centroide: En la ventana actual, calcule el centroide de la región objetivo (es decir, la media de los puntos de píxel).
- Mover la ventana: Mueva el centro de la ventana a la posición del centroide.
- Iterar: Repita los pasos 2 y 3 hasta que el centro de la ventana ya no cambie o se alcance el número máximo de iteraciones.
1.2 Implementación en OpenCV
En OpenCV, el algoritmo MeanShift se implementa a través de lacv2.meanShift()función. A continuación se muestra un ejemplo de código simple:
Ejemplo
import numpy as np
# Leer el video
cap = cv2.VideoCapture('video.mp4')
# Leer el primer fotograma
ret, frame = cap.read()
# Establecer la ventana inicial (x, y, width, height)
x, y, w, h = 300, 200, 100, 50
track_window = (x, y, w, h)
# Establecer ROI (Region of Interest)
roi = frame[y:y+h, x:x+w]
# Convertir al espacio de color HSV
hsv_roi = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV)
# Crear la máscara y calcular el histograma
mask = cv2.inRange(hsv_roi, np.array((0., 60., 32.)), np.array((180., 255., 255.)))
roi_hist = cv2.calcHist([hsv_roi], [0], mask, [180], [0, 180])
cv2.normalize(roi_hist, roi_hist, 0, 255, cv2.NORM_MINMAX)
# Establecer la condición de terminación
term_crit = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 1)
while True:
ret, frame = cap.read()
if not ret:
break
# Convertir al espacio de color HSV
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
# Calcular la retroproyección
dst = cv2.calcBackProject([hsv], [0], roi_hist, [0, 180], 1)
# Aplicar el algoritmo MeanShift
ret, track_window = cv2.meanShift(dst, track_window, term_crit)
# Dibujar el resultado del seguimiento
x, y, w, h = track_window
img2 = cv2.rectangle(frame, (x, y), (x+w, y+h), 255, 2)
cv2.imshow('MeanShift Tracking', img2)
if cv2.waitKey(30) & 0xFF == 27:
break
cap.release()
cv2.destroyAllWindows()
1.3 Ventajas y desventajas
Ventajas:
- Simple y fácil de implementar, con alta eficiencia computacional.
- Es insensible a los cambios de forma y tamaño del objetivo.
Desventajas:
- La capacidad para manejar el movimiento rápido o la oclusión del objetivo es deficiente.
- El tamaño de la ventana es fijo y no puede adaptarse automáticamente a los cambios de tamaño del objetivo.
2. Algoritmo CamShift
2.1 Principio del algoritmo
El algoritmo CamShift (Continuously Adaptive MeanShift) es una versión mejorada de MeanShift. Ajusta el tamaño de la ventana de forma adaptativa para lograr un mejor seguimiento del objetivo. Sobre la base de MeanShift, el algoritmo CamShift añade el ajuste del tamaño y la orientación de la ventana, lo que le permite adaptarse a los cambios de tamaño y rotación del objetivo en el video.
Los pasos básicos del algoritmo CamShift son los siguientes:
- Inicializar la ventana: Igual que MeanShift, seleccione la ventana inicial en el primer fotograma del video.
- Calcular el centroide: En la ventana actual, calcule el centroide de la región objetivo.
- Mover la ventana: Mueva el centro de la ventana a la posición del centroide.
- Ajustar el tamaño y la orientación de la ventana: Ajuste la ventana según el tamaño y la orientación del objetivo.
- Iterar: Repita los pasos 2 a 4 hasta que el centro de la ventana ya no cambie o se alcance el número máximo de iteraciones.
2.2 Implementación en OpenCV
En OpenCV, el algoritmo CamShift se implementa a través de lacv2.CamShift()función. A continuación se muestra un ejemplo de código simple:
Ejemplo
import numpy as np
# Leer el video
cap = cv2.VideoCapture('video.mp4')
# Leer el primer fotograma
ret, frame = cap.read()
# Establecer la ventana inicial (x, y, width, height)
x, y, w, h = 300, 200, 100, 50
track_window = (x, y, w, h)
# Establecer ROI (Region of Interest)
roi = frame[y:y+h, x:x+w]
# Convertir al espacio de color HSV
hsv_roi = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV)
# Crear la máscara y calcular el histograma
mask = cv2.inRange(hsv_roi, np.array((0., 60., 32.)), np.array((180., 255., 255.)))
roi_hist = cv2.calcHist([hsv_roi], [0], mask, [180], [0, 180])
cv2.normalize(roi_hist, roi_hist, 0, 255, cv2.NORM_MINMAX)
# Establecer la condición de terminación
term_crit = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 1)
while True:
ret, frame = cap.read()
if not ret:
break
# Convertir al espacio de color HSV
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
# Calcular la retroproyección
dst = cv2.calcBackProject([hsv], [0], roi_hist, [0, 180], 1)
# Aplicar el algoritmo CamShift
ret, track_window = cv2.CamShift(dst, track_window, term_crit)
# Dibujar el resultado del seguimiento
pts = cv2.boxPoints(ret)
pts = np.int0(pts)
img2 = cv2.polylines(frame, [pts], True, 255, 2)
cv2.imshow('CamShift Tracking', img2)
if cv2.waitKey(30) & 0xFF == 27:
break
cap.release()
cv2.destroyAllWindows()
2.3 Ventajas y desventajas
Ventajas:
- Puede adaptarse automáticamente a los cambios de tamaño y orientación del objetivo.
- Posee una buena robustez ante los cambios de forma y rotación del objetivo.
Desventajas:
- La capacidad para manejar el movimiento rápido o la oclusión del objetivo sigue siendo limitada.
- La complejidad computacional es ligeramente superior a la de MeanShift.
Comparación entre MeanShift y CamShift
MeanShift y CamShift son dos algoritmos clásicos de seguimiento de objetos, y ambos tienen implementaciones listas en OpenCV.
El algoritmo MeanShift es simple y eficiente, adecuado para escenarios donde el tamaño y la orientación del objetivo no cambian mucho, mientras que el algoritmo CamShift, mediante el ajuste adaptativo del tamaño y la orientación de la ventana, puede manejar mejor los cambios de tamaño y orientación del objetivo. En aplicaciones prácticas, se puede elegir el algoritmo adecuado según las necesidades específicas.
| Característica | MeanShift | CamShift |
|---|---|---|
| Tamaño de la ventana | Tamaño fijo | Ajuste adaptativo del tamaño y la orientación |
| Escenario aplicable | Escenarios con tamaño de objetivo fijo | Escenarios con cambios de tamaño y orientación del objetivo |
| Complejidad computacional | Baja | Alta |
| Rendimiento en tiempo real | Bueno | Ligeramente inferior |