Caso práctico: Seguimiento de objetos con OpenCV en RPi 4

Caso práctico: Seguimiento de objetos con OpenCV en RPi 4 — hero

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._create (en OpenCV 4.10.0.84 los trackers están en el módulo 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

Ir a 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.

Quiz rápido

Pregunta 1: ¿Qué sistema operativo se utiliza en este caso práctico?




Pregunta 2: ¿Cuál es la versión de Python utilizada?




Pregunta 3: ¿Qué versión de OpenCV se especifica en el artículo?




Pregunta 4: ¿Qué dispositivo se menciona en el artículo?




Pregunta 5: ¿Qué librería se utiliza para la gestión de GPIOs?




Pregunta 6: ¿Cuál es la versión de pip que se debe usar?




Pregunta 7: ¿Qué componente de hardware se utiliza para la captura de imágenes?




Pregunta 8: ¿Qué herramienta se menciona para crear entornos virtuales en Python?




Pregunta 9: ¿Qué versión de libcamera-apps se indica en el artículo?




Pregunta 10: ¿Qué versión de virtualenv se menciona en el artículo?




Carlos Núñez Zorrilla
Carlos Núñez Zorrilla
Electronics & Computer Engineer

Ingeniero Superior en Electrónica de Telecomunicaciones e Ingeniero en Informática (titulaciones oficiales en España).

Sígueme:
error: Contenido Protegido / Content is protected !!
Scroll to Top