Objetivo y caso de uso
Qué construirás: Un sistema de seguimiento de objetos en tiempo real utilizando OpenCV en una Raspberry Pi 4 con cámara HQ.
Para qué sirve
- Seguimiento de personas en entornos de seguridad mediante detección de movimiento.
- Control de calidad en líneas de producción al identificar objetos defectuosos.
- Interacción en proyectos de robótica, permitiendo que un robot siga a un objeto específico.
- Monitorización de tráfico en tiempo real para análisis de flujos vehiculares.
Resultado esperado
- Latencia de procesamiento de imágenes menor a 100 ms.
- Precisión de seguimiento superior al 90% en condiciones de luz adecuadas.
- Capacidad de procesar 30 FPS (fotogramas por segundo) en resolución 1080p.
- Detección de objetos en un rango de 5 metros con un 95% de fiabilidad.
Público objetivo: Desarrolladores y entusiastas de la visión por computadora; Nivel: Avanzado
Arquitectura/flujo: Captura de video desde la cámara HQ, procesamiento de imágenes en tiempo real con OpenCV, y salida de datos a través de MQTT para visualización remota.
Nivel: Avanzado
Prerrequisitos (SO, toolchain y versiones exactas)
Este caso práctico está probado y documentado para el siguiente entorno. Usa exactamente estas versiones o superiores compatibles cuando se indique; donde fijamos versiones con pip, debes respetarlas para reproducibilidad.
- Sistema operativo:
- Raspberry Pi OS Bookworm 64‑bit (Debian 12), imagen oficial para Raspberry Pi 4. Kernel Linux 6.6.x.
- Dispositivo:
- Raspberry Pi 4 Model B (2/4/8 GB) + HQ Camera (sensor Sony IMX477, conexión CSI-2).
- Toolchain y librerías (usuarios/espacio de usuario):
- Python 3.11 (Bookworm lo instala por defecto; versión probada 3.11.2).
- pip 24.2 (gestor de paquetes Python).
- virtualenv 20.26.3 (o venv estándar de Python).
- OpenCV (contrib) para Python: opencv-contrib-python==4.10.0.84
- NumPy==1.26.4
- Picamera2 (vía apt, bindings sobre libcamera): versión probada 0.3.16
- libcamera y utilidades de cámara (vía apt): libcamera-apps 0.1.0 (serie 0.1.x)
- gpiozero==1.6.2 (opcional; instalable con apt, útil para GPIOs si añades un botón físico).
- spidev y smbus2 (opcionales; no utilizados en el núcleo del proyecto).
- Compiladores (no estrictamente necesarios en este flujo, pero útiles para extensiones nativas):
- GCC 12.x (de Debian 12)
- CMake 3.25+ (si compilas OpenCV desde fuente; aquí usamos wheels de pip)
Notas:
– Elegimos Picamera2 para la captura porque integra libcamera (stack moderno de cámaras en Raspberry Pi OS Bookworm) y entrega imágenes como arrays de NumPy listos para OpenCV, evitando capas legacy (MMAL/raspicam).
– Fijamos opencv-contrib-python a 4.10.0.84 para disponer de los trackers CSRT y KCF del módulo contrib, necesarios para opencv-object-tracking con buen rendimiento/precisión.
Materiales
- 1× Raspberry Pi 4 Model B (cualquier RAM).
- 1× Raspberry Pi High Quality Camera (HQ Camera, sensor IMX477).
- 1× Cable plano CSI-2 oficial para cámara (largo según montaje).
- 1× Objetivo compatible (C o CS mount; ej., 6mm o 12mm) con su anillo adaptador.
- 1× Tarjeta microSD (≥32 GB, clase A1/A2) con Raspberry Pi OS Bookworm 64‑bit.
- 1× Fuente de alimentación oficial 5V/3A USB‑C.
- 1× Monitor HDMI, teclado y ratón (o acceso por SSH).
- 1× Trípode o soporte estable para la HQ Camera.
- Opcional:
- 1× Carcasa con soporte para cámara.
- Botón/LED conectados a GPIO (para triggers/feedback en variantes).
Asegúrate de referirte siempre al conjunto “Raspberry Pi 4 Model B + HQ Camera” en montaje, comandos y pruebas.
Preparación y conexión
Conexión física de la HQ Camera
- Apaga la Raspberry Pi y desconecta la alimentación.
- Monta el objetivo en la HQ Camera (rosca C/CS) y fija el anillo según el tipo de objetivo.
- Conecta el cable CSI-2:
- En Raspberry Pi 4 Model B, usa el conector marcado “CAMERA” (cerca del puerto micro‑HDMI más cercano al conector USB‑C).
- Levanta la pestaña del conector, inserta el cable con los contactos metálicos hacia el conector HDMI (orientación correcta: contactos mirando a los puertos HDMI), y baja la pestaña.
- En la HQ Camera, inserta el cable de forma que los contactos queden hacia el sensor (respeta la orientación del conector).
- Fija la cámara en trípode/soporte; evita vibraciones.
- Alimenta la Raspberry Pi y arranca.
Tabla de referencia de puertos y elementos relevantes
| Componente | Puerto/Conector | Detalle | Notas |
|---|---|---|---|
| HQ Camera (IMX477) | CSI-2 cámara | Cable plano CSI-2 | Orientación correcta de los contactos |
| Raspberry Pi 4 Model B | Conector “CAMERA” | Cerca de micro‑HDMI | No confundir con conector “DISPLAY” |
| MicroSD | Slot microSD | – | Raspberry Pi OS Bookworm 64‑bit |
| Alimentación | USB‑C | 5V/3A | Fuente oficial recomendable |
| Video | micro‑HDMI 0/1 | 1080p o superior | Para ver la ventana OpenCV |
| Red | Ethernet/Wi‑Fi | – | Opcional para SSH |
Habilitar interfaces y configuración del sistema
- Verifica/ajusta configuración de cámara y memoria GPU.
- Opción A: raspi-config
- Abre terminal:
sudo raspi-config - System Options → Performance Options → GPU Memory → establece 128 (o 256 si vas a usar 1080p/alta tasa).
- Interface Options:
- Camera: en Bookworm ya no es necesario legado; no habilites “Legacy Camera”. Dejaremos libcamera por defecto.
- SSH: habilita si vas a trabajar remoto.
-
Finaliza y reinicia.
-
Opción B: editar /boot/firmware/config.txt (equivalente y explícito)
- Abre el fichero:
sudo nano /boot/firmware/config.txt - Asegura estas líneas (añádelas si no existen):
camera_auto_detect=1
gpu_mem=128
No añadas start_x ni dtoverlay=vc4-kms-v3d-pi4 deshabilitado; deja el compositor KMS por defecto. - Guarda y reinicia:
sudo reboot
Comprobación básica de la cámara
Tras reiniciar, valida la HQ Camera con libcamera:
libcamera-hello -t 3000
- Debes ver vista previa 3 segundos. Si falla, revisa Troubleshooting.
Código completo con OpenCV y Picamera2
Implementaremos un seguidor de objetos con OpenCV (trackers CSRT/KCF) y captura con Picamera2. Permitiremos seleccionar una ROI con el ratón en tiempo de ejecución, cambiar de tracker por parámetro y mostrar FPS.
Características:
– Captura en RGB888 1280×720 @ 30 FPS vía Picamera2.
– Conversión a BGR para OpenCV.
– Trackers disponibles: CSRT (preciso), KCF (rápido). Elegibles por CLI.
– Teclas:
– s: seleccionar ROI y (re)inicializar tracker
– r: reiniciar tracker (sin ROI)
– p: pausar/continuar
– q/ESC: salir
– Overlay: bounding box, nombre del tracker, FPS.
Estructura del proyecto
- venv para aislamiento de Python 3.11.
- Script principal: track.py
- Script de diagnóstico rápido: cam_check.py
Código: cam_check.py (diagnóstico de cámara y latencia)
#!/usr/bin/env python3
# cam_check.py
from picamera2 import Picamera2
import time
def main():
picam2 = Picamera2()
# Configuración de previsualización a 1280x720 RGB888
config = picam2.create_preview_configuration(
main={"format": "RGB888", "size": (1280, 720)},
buffer_count=4
)
picam2.configure(config)
picam2.start()
t0 = time.time()
frames = 60
for i in range(frames):
frame = picam2.capture_array() # numpy array (H, W, 3), RGB
t1 = time.time()
fps = frames / (t1 - t0)
print(f"Picamera2 OK. Resolución 1280x720. FPS estimado: {fps:.2f}")
picam2.stop()
if __name__ == "__main__":
main()
Código: track.py (seguimiento de objetos con OpenCV)
#!/usr/bin/env python3
# track.py
# Uso:
# python track.py --tracker csrt
# python track.py --tracker kcf
import argparse
import time
import sys
import numpy as np
import cv2
from picamera2 import Picamera2
TRACKERS = {
"csrt": cv2.legacy.TrackerCSRT_create,
"kcf": cv2.legacy.TrackerKCF_create,
}
def build_tracker(name: str):
key = name.lower()
if key not in TRACKERS:
raise ValueError(f"Tracker '{name}' no soportado. Usa uno de: {list(TRACKERS.keys())}")
return TRACKERS[key]()
def draw_hud(frame, bbox, tracker_name, fps, state_text=None):
h, w = frame.shape[:2]
# Caja
if bbox is not None:
x, y, bw, bh = bbox
p1 = (int(x), int(y))
p2 = (int(x + bw), int(y + bh))
cv2.rectangle(frame, p1, p2, (0, 255, 0), 2)
# HUD
overlay = [
f"Tracker: {tracker_name.upper()}",
f"FPS: {fps:.2f}",
f"Resolucion: {w}x{h}"
]
if state_text:
overlay.append(state_text)
y0 = 24
for i, line in enumerate(overlay):
cv2.putText(frame, line, (10, y0 + i * 22), cv2.FONT_HERSHEY_SIMPLEX, 0.65, (255, 255, 255), 2, cv2.LINE_AA)
def select_roi(frame):
# OpenCV espera BGR; cv2.selectROI devuelve (x, y, w, h)
bbox = cv2.selectROI("RoiSelector", frame, fromCenter=False, showCrosshair=True)
cv2.destroyWindow("RoiSelector")
if bbox == (0, 0, 0, 0):
return None
return bbox
def main():
parser = argparse.ArgumentParser(description="Seguimiento de objetos con OpenCV en Raspberry Pi 4 + HQ Camera")
parser.add_argument("--tracker", type=str, default="csrt", choices=list(TRACKERS.keys()),
help="Algoritmo de tracking: csrt (precisión) o kcf (rapidez)")
parser.add_argument("--width", type=int, default=1280, help="Ancho de captura")
parser.add_argument("--height", type=int, default=720, help="Alto de captura")
parser.add_argument("--display", action="store_true", help="Mostrar ventana de OpenCV (necesario para seleccionar ROI)")
parser.add_argument("--warmup", type=int, default=5, help="Frames de calentamiento antes del tracking")
args = parser.parse_args()
# Inicializar cámara
picam2 = Picamera2()
config = picam2.create_preview_configuration(
main={"format": "RGB888", "size": (args.width, args.height)},
buffer_count=4
)
picam2.configure(config)
picam2.start()
# Calentamiento
for _ in range(args.warmup):
_ = picam2.capture_array()
# Estado del tracker
tracker = build_tracker(args.tracker)
has_target = False
bbox = None
paused = False
last_t = time.time()
fps = 0.0
window_name = "OpenCV Object Tracking"
if args.display:
cv2.namedWindow(window_name, cv2.WINDOW_NORMAL)
cv2.resizeWindow(window_name, args.width, args.height)
print("Controles:")
print(" s: seleccionar ROI y (re)iniciar tracker")
print(" r: reiniciar tracker sin ROI")
print(" p: pausar/continuar")
print(" q/ESC: salir")
while True:
if not paused:
# Captura en RGB, convertimos a BGR para OpenCV
frame_rgb = picam2.capture_array()
frame = cv2.cvtColor(frame_rgb, cv2.COLOR_RGB2BGR)
else:
# En pausa, no actualizamos frame
pass
# Tracking
state_text = None
if has_target and bbox is not None and not paused:
ok, newbox = tracker.update(frame)
if ok:
bbox = newbox
else:
state_text = "Perdido: presiona 's' para seleccionar ROI"
has_target = False
# FPS
t = time.time()
dt = t - last_t
last_t = t
if dt > 0:
fps = 1.0 / dt
# Dibujo
if args.display:
draw_hud(frame, bbox if has_target else None, args.tracker, fps, state_text=state_text)
cv2.imshow(window_name, frame)
# Interacción
key = cv2.waitKey(1) & 0xFF if args.display else 0xFF
if key in (ord('q'), 27): # 'q' o ESC
break
elif key == ord('p'):
paused = not paused
elif key == ord('r'):
tracker = build_tracker(args.tracker)
has_target = False
bbox = None
elif key == ord('s'):
if not args.display:
print("La selección de ROI requiere --display")
else:
# Seleccionar ROI sobre el frame actual
# Aseguramos frame reciente si estaba en pausa
if paused:
frame_rgb = picam2.capture_array()
frame = cv2.cvtColor(frame_rgb, cv2.COLOR_RGB2BGR)
paused = False
sel = select_roi(frame)
if sel is not None and sel[2] > 0 and sel[3] > 0:
tracker = build_tracker(args.tracker)
ok = tracker.init(frame, sel)
if ok:
bbox = sel
has_target = True
else:
print("No se pudo inicializar el tracker con la ROI seleccionada")
if args.display:
cv2.destroyAllWindows()
picam2.stop()
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
sys.exit(0)
Breve explicación de partes clave:
– Picamera2:
– create_preview_configuration con formato RGB888 y tamaño 1280×720 para un equilibrio entre latencia y calidad.
– capture_array entrega un ndarray RGB; convertimos a BGR para OpenCV.
– Trackers CSRT/KCF:
– Se crean vía cv2.legacy.
– CSRT: más preciso, costoso en CPU.
– KCF: más rápido, algo menos robusto ante oclusiones/escala.
– selectROI: permite al usuario definir el objeto a seguir.
– HUD: renderiza caja, FPS, nombre del tracker y estado.
Compilación/instalación/ejecución (pasos reproducibles)
Trabajaremos en una venv con Python 3.11, instalando dependencias con apt y pip.
1) Actualiza el sistema
sudo apt update
sudo apt full-upgrade -y
sudo reboot
2) Instala paquetes del sistema (libcamera y Picamera2, entre otros)
sudo apt install -y \
python3-venv python3-dev \
libatlas-base-dev \
libcamera-apps \
python3-picamera2 \
git pkg-config \
libgtk-3-0 libgtk-3-dev \
libjpeg-dev libpng-dev libtiff-dev \
libavcodec-dev libavformat-dev libswscale-dev \
libqt5gui5 libqt5widgets5 libqt5core5a \
libopenblas-dev
Notas:
– python3-picamera2 instala Picamera2 (versión probada 0.3.16 en Bookworm).
– libcamera-apps proporciona libcamera-hello, -still, -vid para validación y utilidades.
3) Crea y activa un entorno virtual (Python 3.11)
python3 -V
# Debe mostrar Python 3.11.x
python3 -m venv ~/venvs/pi-opencv-track
source ~/venvs/pi-opencv-track/bin/activate
python -m pip install --upgrade pip==24.2 setuptools==68.2.2 wheel==0.44.0
4) Instala dependencias Python exactas (vía pip, con versiones fijadas)
pip install numpy==1.26.4
# Usamos contrib para disponer de trackers (csrt/kcf):
pip install opencv-contrib-python==4.10.0.84
# Para ejecutarse sin display, puedes añadir opencv-python-headless==4.10.0.84,
# pero para selección de ROI con ventana es preferible opencv-contrib-python.
5) Crea el directorio del proyecto y añade los scripts
mkdir -p ~/projects/opencv-object-tracking
cd ~/projects/opencv-object-tracking
nano cam_check.py
# pega el contenido del cam_check.py mostrado
nano track.py
# pega el contenido del track.py mostrado
chmod +x cam_check.py track.py
6) Validación rápida de Picamera2
source ~/venvs/pi-opencv-track/bin/activate
python cam_check.py
- Debe imprimir “Picamera2 OK…” con FPS aproximados (p.ej., 45–60 FPS en 1280×720 sin procesamiento, dependiente de carga).
7) Ejecución del seguimiento (con ventana)
source ~/venvs/pi-opencv-track/bin/activate
python track.py --tracker csrt --display
- Se abrirá la ventana. Pulsa ‘s’ para seleccionar el objeto y ver la caja verde.
8) Opciones útiles
– Para usar KCF (más ligero):
python track.py --tracker kcf --display
– Para cambiar resolución (más FPS, menos calidad):
python track.py --width 960 --height 540 --tracker kcf --display
– Para headless (sin display) y ROI fija (editar el código para setear bbox inicial) o usar un frontend remoto (VNC/SSH X11).
Validación paso a paso
1) Validar hardware y cámara
– Comando:
libcamera-hello -t 3000
– Esperado: ventana de vista previa 3 segundos sin errores en consola.
2) Verificar versión de Picamera2 y libcamera
– Comando:
python -c "from picamera2 import __version__ as v; print('Picamera2', v)"
libcamera-hello --version
– Esperado:
– Picamera2 0.3.16 (o cercano 0.3.x).
– libcamera-hello v0.1.0 (serie 0.1.x).
3) Verificar paquete OpenCV dentro de la venv
– Comando:
source ~/venvs/pi-opencv-track/bin/activate
python -c "import cv2; import numpy as np; print('OpenCV', cv2.__version__); print('Has contrib?', hasattr(cv2, 'legacy'))"
– Esperado:
– OpenCV 4.10.0 (coincide con 4.10.0.84).
– Has contrib? True (módulo cv2.legacy disponible).
4) Test de capturas rápidas
– Comando:
python cam_check.py
– Esperado:
– Mensaje “Picamera2 OK. Resolución 1280×720. FPS estimado: XX.XX”.
5) Ejecución del seguidor con CSRT y selección de ROI
– Comando:
python track.py --tracker csrt --display
– Pasos:
1. Aparece ventana «OpenCV Object Tracking».
2. Pulsa ‘s’, se abre una ventana de selección (RoiSelector).
3. Dibuja un rectángulo alrededor del objeto a seguir y confirma (ENTER o doble clic).
4. Debe verse una caja verde en el objeto; el overlay mostrará “Tracker: CSRT” y “FPS: …”.
– Validaciones:
– La caja sigue el objeto mientras lo mueves moderadamente.
– FPS entre 10–25 en CSRT @1280×720 en RPi 4, dependiendo de iluminación y carga.
– Si pierdes el objeto, mensaje “Perdido: presiona ‘s’ para seleccionar ROI”.
6) Conmutar a KCF para mejorar FPS
– Comando:
python track.py --tracker kcf --display
– Esperado:
– FPS superior (p.ej., 20–35 FPS @720p), tracking robusto a movimientos medios.
7) Ajustar resolución para validar latencia/precisión
– Comando:
python track.py --tracker kcf --width 960 --height 540 --display
– Esperado:
– FPS más altos; tracking con algo menos de detalle.
8) Medición de CPU y estabilidad
– Comandos:
top -d 1
# o
vcgencmd measure_temp
– Esperado:
– CPU de 120–250% (en total, multi-core) según tracker/resolución.
– Temperatura < 80°C (aconsejable disipador/ventilador si supera 70°C en cargas largas).
Troubleshooting (errores típicos y soluciones)
1) libcamera-hello falla con “No cameras available” o “ERROR: *** no cameras found ***”
– Causas:
– Cable CSI invertido o mal asentado.
– HQ Camera no detectada por DT.
– Soluciones:
– Revisa orientación y firmeza del cable en Pi y HQ Camera.
– Asegura camera_auto_detect=1 en /boot/firmware/config.txt.
– Prueba añadir explícitamente el overlay del sensor:
echo "dtoverlay=imx477" | sudo tee -a /boot/firmware/config.txt
sudo reboot
2) Picamera2 ImportError: cannot import name ‘Picamera2’
– Causas: paquete no instalado, venv activada sin acceso a apt libs.
– Soluciones:
– Instala vía apt (fuera de la venv, es un paquete del sistema):
sudo apt install -y python3-picamera2
– Lanza Python desde venv; la librería del sistema es visible.
3) cv2.legacy no existe o error “module ‘cv2’ has no attribute ‘legacy’”
– Causas: instalaste opencv-python y no opencv-contrib-python.
– Solución:
pip uninstall -y opencv-python opencv-contrib-python
pip install opencv-contrib-python==4.10.0.84
4) Ventana de OpenCV no abre (display vacío) o selectROI no aparece
– Causas: sin servidor X, sesión SSH sin reenvío X11, dependencia GTK faltante.
– Soluciones:
– Ejecuta en consola local con monitor conectado.
– Instala dependencias de GUI:
sudo apt install -y libgtk-3-0 libgtk-3-dev
– Para SSH, usa VNC o X11 forwarding (ssh -X), aunque puede afectar rendimiento.
5) Bajos FPS/lag alto
– Causas: resolución elevada, tracker CSRT muy costoso, GPU mem insuficiente.
– Soluciones:
– Reduce resolución: –width 960 –height 540
– Usa –tracker kcf
– Aumenta gpu_mem a 256 si usas múltiples ventanas o alta resolución.
– Cierra procesos en segundo plano (Chromium, etc.).
6) Tracking pierde el objeto tras oclusión o cambio de escala
– Causas: trackers KCF/CSRT tienen límites ante oclusiones prolongadas.
– Soluciones:
– Re-selecciona ROI con ‘s’.
– Cambia a CSRT si usabas KCF.
– Iluminación constante y enfoque nítido del objetivo.
7) Errores de memoria o “Illegal instruction” al instalar OpenCV
– Causas: wheel incompatible, conflictos entre pip y apt.
– Soluciones:
– Borra e instala limpio en venv:
pip uninstall -y opencv-python opencv-contrib-python numpy
pip cache purge
pip install numpy==1.26.4 opencv-contrib-python==4.10.0.84
– Evita mezclar apt get python3-opencv con pip opencv-contrib-python en la misma venv.
8) Imagen invertida o colores extraños
– Causas: conversión de color omitida (RGB→BGR).
– Solución: asegura cv2.cvtColor(frame_rgb, cv2.COLOR_RGB2BGR) antes del tracker.
Mejoras y variantes
- Multi-objeto con MultiTracker:
- Usa cv2.legacy.MultiTracker_create y permite seleccionar varias ROIs (repite selectROI hasta cancelar) e inicializar múltiples trackers (p.ej., KCF para cada objeto).
- Re-identificación y robustez:
- Integra un detector (YOLOv5/YOLOv8 nano) para re‑detectar y re‑inicializar el tracker si se pierde.
- Usa un filtro de Kalman para suavizar trayectorias, mejorando estabilidad en jitter.
- Registro de trayectorias:
- Guarda en CSV (timestamp, bbox, tracker, FPS).
- Visualiza heatmap de trayectorias en tiempo real.
- Rendimiento:
- Baja resolución (960×540) y KCF para mayor FPS en CPU.
- Compila OpenCV con NEON/VFPv4 y TBB/OpenBLAS si buscas exprimir rendimiento (avanzado).
- Streaming remoto:
- Servidor RTSP o WebRTC: procesa con OpenCV y transmite la vista anotada (gstreamer + uv4l o aiortc).
- Control por GPIO:
- Usa gpiozero para iniciar/pausar tracking con un botón físico, y LED para estado (útil en montajes sin pantalla).
- Servicio systemd:
- Ejecuta track.py automáticamente al arranque (en entornos headless), escribiendo salida a archivo o stream.
- Auto ROI:
- Inicializa ROI automáticamente con el objeto más grande en movimiento (diferenciación de frames o detección simple con MOG2).
Ejemplo de fragmento para MultiTracker (orientativo):
# Dentro del main, tras elegir tracker base, permitir múltiples ROIs
multi = cv2.legacy.MultiTracker_create()
rois = []
while True:
sel = select_roi(frame)
if sel is None or sel[2] == 0 or sel[3] == 0:
break
rois.append(sel)
multi.add(build_tracker(args.tracker), frame, sel)
# En el loop:
ok, boxes = multi.update(frame)
for b in boxes:
x, y, bw, bh = [int(v) for v in b]
cv2.rectangle(frame, (x, y), (x+bw, y+bh), (0, 255, 255), 2)
Checklist de verificación
- [ ] Raspberry Pi 4 Model B con HQ Camera conectada correctamente (CSI “CAMERA”; orientación del cable verificada).
- [ ] Raspberry Pi OS Bookworm 64‑bit instalado y actualizado (sudo apt full-upgrade).
- [ ] GPU memory configurada a 128 MB o más en /boot/firmware/config.txt (gpu_mem=128/256).
- [ ] libcamera-hello muestra vista previa (cámara detectada, sin errores).
- [ ] Entorno virtual creado y activado: ~/venvs/pi-opencv-track.
- [ ] pip y setuptools actualizados dentro de la venv (pip 24.2, setuptools 68.2.2).
- [ ] Paquetes Python instalados con versiones exactas:
- [ ] numpy==1.26.4
- [ ] opencv-contrib-python==4.10.0.84
- [ ] Picamera2 instalado vía apt (python3-picamera2, versión 0.3.x).
- [ ] cam_check.py ejecuta y reporta FPS estimado sin errores.
- [ ] track.py abre ventana, permite seleccionar ROI con ‘s’, muestra bbox y FPS.
- [ ] CSRT y KCF probados; KCF ofrece mayor FPS, CSRT mayor precisión.
- [ ] Troubleshooting consultado si hay errores (sin “No cameras available”, sin ImportError de cv2.legacy).
- [ ] Validación final: seguimiento estable del objeto en al menos 30 segundos con FPS aceptable para la aplicación objetivo.
Con esto, dispones de un pipeline robusto de “opencv-object-tracking” puro CPU sobre Raspberry Pi 4 Model B + HQ Camera, basado en libcamera/Picamera2, con control interactivo, reproducible y ampliable a variantes más avanzadas.
Encuentra este producto y/o libros sobre este tema en Amazon
Como afiliado de Amazon, gano con las compras que cumplan los requisitos. Si compras a través de este enlace, ayudas a mantener este proyecto.



