Visión por computadora profesional con Python: cámara, detección de objetos, tracking y eventos con YOLO
Un prototipo serio de visión por computadora no debe limitarse a “dibujar cuadros” sobre la webcam. Debe capturar video de forma estable, usar modelos modernos, asignar IDs a objetos, filtrar falsos positivos, registrar eventos, proteger la privacidad y estar preparado para crecer hacia producción. Esta guía muestra una arquitectura práctica con Python, OpenCV, YOLO y tracking en tiempo real.
Por Equipo Starbyte
Visión por computadora profesional con Python: cámara, detección de objetos, tracking y eventos con YOLO
Problema real: detectar objetos no basta para un proyecto serio
Muchos tutoriales de visión por computadora muestran una webcam, algunos cuadros sobre la imagen y un mensaje como “persona detectada”. Eso sirve para aprender, pero no alcanza para un proyecto serio.
Un sistema profesional necesita responder preguntas más importantes:
- ¿Qué objeto fue detectado?
- ¿Con qué nivel de confianza?
- ¿Durante cuánto tiempo apareció?
- ¿Entró o salió de una zona?
- ¿Es el mismo objeto en varios frames o son objetos distintos?
- ¿Cuántas veces ocurrió el evento?
- ¿Se debe guardar evidencia?
- ¿Cómo evitar falsos positivos?
- ¿Qué pasa si la cámara se desconecta?
- ¿Cómo se protege la privacidad de las personas?
- ¿Cómo se deja registro para auditoría o análisis?
Por eso, esta guía no será solo “abrir la cámara y detectar”. El objetivo es construir una base profesional para un sistema de visión por computadora usando Python, OpenCV, YOLO y tracking.
Qué vas a construir
Construiremos un prototipo profesional con estas capacidades:
- Captura de cámara con OpenCV.
- Detección de objetos con YOLO.
- Seguimiento de objetos con IDs persistentes.
- Filtrado por clases relevantes.
- Zona de interés.
- Registro de eventos en CSV.
- Captura de evidencia.
- Métricas básicas de rendimiento.
- Buenas prácticas de privacidad.
- Estructura lista para crecer.
Diferencia entre demo y sistema serio
| Demo básica | Sistema más serio |
|---|---|
| Solo muestra cámara | Controla errores de cámara |
| Dibuja cuadros | Registra eventos |
| Detecta todo | Filtra clases importantes |
| No guarda evidencia | Guarda capturas controladas |
| No mide rendimiento | Muestra FPS y tiempos |
| No distingue objetos | Usa tracking con IDs |
| No define zonas | Usa áreas de interés |
| No considera privacidad | Aplica reglas de protección |
| Funciona solo en condiciones ideales | Maneja fallos y reconexión |
La diferencia no está solo en el modelo. Está en la arquitectura.
Herramientas que usaremos
| Herramienta | Uso |
|---|---|
| Python | Lenguaje principal |
| OpenCV | Captura de video, dibujo y ventanas |
| Ultralytics YOLO | Detección de objetos y tracking |
| ByteTrack / BoT-SORT | Seguimiento de objetos entre frames |
| CSV | Registro simple de eventos |
| Webcam o cámara IP | Fuente de video |
| Entorno virtual | Aislar dependencias |
OpenCV ofrece VideoCapture para capturar video desde cámaras, archivos o secuencias de imágenes. Ultralytics YOLO incluye modos para detección, tracking, segmentación, clasificación y pose; su modo track permite seguimiento multiobjeto en video y streams en tiempo real usando algoritmos como ByteTrack o BoT-SORT.
Requisitos previos
Necesitas:
- Python 3.10 o superior.
- Webcam o cámara IP.
- Windows, Linux o macOS.
- Conexión a internet para instalar paquetes y descargar el modelo inicial.
- Conocimientos básicos de terminal.
- Equipo con al menos 8 GB de RAM.
- GPU opcional, pero recomendable para cargas más pesadas.
Verifica Python:
python --version
o en Windows:
py --version
Paso 1: crea la estructura del proyecto
Crea una carpeta de trabajo:
mkdir vision-profesional-yolo
cd vision-profesional-yolo
Estructura recomendada:
vision-profesional-yolo/
├── app.py
├── config.py
├── requirements.txt
├── eventos/
├── evidencias/
└── modelos/
Crea carpetas:
mkdir eventos evidencias modelos
Paso 2: crea un entorno virtual
En Windows:
py -m venv .venv
.\.venv\Scripts\activate
En Linux o macOS:
python3 -m venv .venv
source .venv/bin/activate
Paso 3: instala dependencias
Crea el archivo:
requirements.txt
Contenido:
opencv-python
ultralytics
numpy
Instala:
pip install -r requirements.txt
Verifica:
python -c "import cv2; print('OpenCV:', cv2.__version__)"
python -c "from ultralytics import YOLO; print('YOLO listo')"
Paso 4: define configuración separada
No mezcles toda la configuración dentro del script principal. Crea:
config.py
Contenido:
# Fuente de video:
# 0 = webcam principal
# también puede ser una URL RTSP de cámara IP
FUENTE_VIDEO = 0
# Modelo YOLO recomendado para iniciar.
# yolov8n.pt es rápido; yolov8s.pt mejora precisión.
MODELO_YOLO = "yolov8n.pt"
# Confianza mínima de detección
CONF_MINIMA = 0.50
# Clases de interés usando nombres COCO
CLASES_INTERES = {"person", "cell phone", "laptop", "backpack"}
# Guardar evidencia cuando haya evento relevante
GUARDAR_EVIDENCIA = True
# Carpeta de evidencias
CARPETA_EVIDENCIAS = "evidencias"
# Carpeta de eventos
CARPETA_EVENTOS = "eventos"
# Mostrar ventana de monitoreo
MOSTRAR_VIDEO = True
# Resolución de captura recomendada para prototipo
ANCHO_FRAME = 1280
ALTO_FRAME = 720
# Tracking: botsort.yaml o bytetrack.yaml
TRACKER = "bytetrack.yaml"
Ventaja:
Si luego cambias cámara, modelo o clases, no rompes el código principal.
Paso 5: crea el sistema principal
Crea:
app.py
Código completo:
import csv
import time
from datetime import datetime
from pathlib import Path
import cv2
from ultralytics import YOLO
from config import (
FUENTE_VIDEO,
MODELO_YOLO,
CONF_MINIMA,
CLASES_INTERES,
GUARDAR_EVIDENCIA,
CARPETA_EVIDENCIAS,
CARPETA_EVENTOS,
MOSTRAR_VIDEO,
ANCHO_FRAME,
ALTO_FRAME,
TRACKER,
)
def crear_carpetas():
Path(CARPETA_EVIDENCIAS).mkdir(exist_ok=True)
Path(CARPETA_EVENTOS).mkdir(exist_ok=True)
def ruta_csv_eventos():
fecha = datetime.now().strftime("%Y%m%d")
return Path(CARPETA_EVENTOS) / f"eventos_{fecha}.csv"
def inicializar_csv():
ruta = ruta_csv_eventos()
if not ruta.exists():
with open(ruta, "w", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
writer.writerow([
"timestamp",
"track_id",
"clase",
"confianza",
"x1",
"y1",
"x2",
"y2",
"evidencia"
])
def registrar_evento(track_id, clase, confianza, bbox, evidencia=""):
x1, y1, x2, y2 = bbox
timestamp = datetime.now().isoformat(timespec="seconds")
with open(ruta_csv_eventos(), "a", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
writer.writerow([
timestamp,
track_id,
clase,
round(float(confianza), 4),
int(x1),
int(y1),
int(x2),
int(y2),
evidencia
])
def guardar_evidencia(frame, clase, track_id):
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
nombre = f"{timestamp}_{clase}_id{track_id}.jpg"
ruta = Path(CARPETA_EVIDENCIAS) / nombre
cv2.imwrite(str(ruta), frame)
return str(ruta)
def dibujar_zona_interes(frame):
alto, ancho = frame.shape[:2]
# Zona central de ejemplo
x1 = int(ancho * 0.20)
y1 = int(alto * 0.20)
x2 = int(ancho * 0.80)
y2 = int(alto * 0.85)
cv2.rectangle(frame, (x1, y1), (x2, y2), (255, 180, 0), 2)
cv2.putText(
frame,
"Zona de interes",
(x1, y1 - 10),
cv2.FONT_HERSHEY_SIMPLEX,
0.7,
(255, 180, 0),
2,
)
return (x1, y1, x2, y2)
def centro_en_zona(bbox, zona):
x1, y1, x2, y2 = bbox
zx1, zy1, zx2, zy2 = zona
cx = int((x1 + x2) / 2)
cy = int((y1 + y2) / 2)
return zx1 <= cx <= zx2 and zy1 <= cy <= zy2
def main():
crear_carpetas()
inicializar_csv()
modelo = YOLO(MODELO_YOLO)
camara = cv2.VideoCapture(FUENTE_VIDEO)
if not camara.isOpened():
raise RuntimeError("No se pudo abrir la fuente de video.")
camara.set(cv2.CAP_PROP_FRAME_WIDTH, ANCHO_FRAME)
camara.set(cv2.CAP_PROP_FRAME_HEIGHT, ALTO_FRAME)
eventos_registrados = set()
tiempo_inicio = time.time()
frames = 0
print("Sistema iniciado. Presiona Q para salir.")
while True:
ret, frame = camara.read()
if not ret:
print("No se pudo leer frame. Reintentando...")
time.sleep(1)
continue
frames += 1
zona = dibujar_zona_interes(frame)
resultados = modelo.track(
frame,
persist=True,
conf=CONF_MINIMA,
tracker=TRACKER,
verbose=False
)
if resultados and resultados[0].boxes is not None:
boxes = resultados[0].boxes
for box in boxes:
clase_id = int(box.cls[0])
clase = modelo.names[clase_id]
confianza = float(box.conf[0])
if clase not in CLASES_INTERES:
continue
x1, y1, x2, y2 = box.xyxy[0].tolist()
bbox = (x1, y1, x2, y2)
track_id = "sin_id"
if box.id is not None:
track_id = int(box.id[0])
dentro_zona = centro_en_zona(bbox, zona)
color = (0, 255, 0) if dentro_zona else (0, 180, 255)
cv2.rectangle(
frame,
(int(x1), int(y1)),
(int(x2), int(y2)),
color,
2
)
etiqueta = f"{clase} ID:{track_id} {confianza:.2f}"
cv2.putText(
frame,
etiqueta,
(int(x1), max(20, int(y1) - 10)),
cv2.FONT_HERSHEY_SIMPLEX,
0.6,
color,
2
)
if dentro_zona:
clave_evento = (track_id, clase)
if clave_evento not in eventos_registrados:
evidencia = ""
if GUARDAR_EVIDENCIA:
evidencia = guardar_evidencia(frame, clase, track_id)
registrar_evento(
track_id=track_id,
clase=clase,
confianza=confianza,
bbox=bbox,
evidencia=evidencia
)
eventos_registrados.add(clave_evento)
tiempo_transcurrido = time.time() - tiempo_inicio
fps = frames / tiempo_transcurrido if tiempo_transcurrido > 0 else 0
cv2.putText(
frame,
f"FPS: {fps:.1f}",
(20, 40),
cv2.FONT_HERSHEY_SIMPLEX,
0.9,
(255, 255, 255),
2
)
if MOSTRAR_VIDEO:
cv2.imshow("Vision profesional con YOLO - Q para salir", frame)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
camara.release()
cv2.destroyAllWindows()
if __name__ == "__main__":
main()
Ejecuta:
python app.py
Qué hace este sistema
Este prototipo:
- Abre la cámara.
- Ejecuta YOLO sobre cada frame.
- Realiza tracking con IDs.
- Filtra clases importantes.
- Dibuja una zona de interés.
- Detecta si el centro del objeto entra en esa zona.
- Registra el evento en CSV.
- Guarda evidencia en imagen.
- Muestra FPS.
- Mantiene configuración separada.
Esto ya se parece más a una base profesional que a una demo simple.
Paso 6: usar cámara IP o RTSP
Si tienes una cámara IP, cambia en config.py:
FUENTE_VIDEO = "rtsp://usuario:password@192.168.1.50:554/stream1"
Ejemplos comunes:
rtsp://usuario:clave@IP:554/stream1
rtsp://usuario:clave@IP:554/live
rtsp://usuario:clave@IP:554/cam/realmonitor?channel=1&subtype=0
Depende del fabricante.
Recomendaciones:
- Usa red cableada si es posible.
- Evita exponer cámaras directamente a internet.
- Cambia contraseñas por defecto.
- Usa VPN si necesitas acceso remoto.
- Prueba primero con VLC para confirmar el stream.
Paso 7: elegir modelo según el caso
| Modelo | Uso recomendado |
|---|---|
yolov8n.pt |
Prototipo rápido, laptop común |
yolov8s.pt |
Mejor equilibrio entre precisión y velocidad |
yolov8m.pt |
Más precisión, requiere mejor hardware |
yolov8l.pt |
Mayor precisión, más pesado |
| Modelo entrenado propio | Objetos específicos del proyecto |
Para producción, no basta con usar un modelo general. Si necesitas detectar cascos, chalecos, placas, herramientas, uniformes o productos específicos, probablemente necesitarás entrenar un modelo personalizado.
Paso 8: definir clases útiles
No detectes todo. Detecta solo lo necesario.
Ejemplo para seguridad básica:
CLASES_INTERES = {"person", "backpack", "cell phone"}
Ejemplo para oficina:
CLASES_INTERES = {"person", "laptop", "cell phone", "chair"}
Ejemplo para control de aforo:
CLASES_INTERES = {"person"}
Menos clases relevantes significa:
- Menos ruido.
- Menos eventos falsos.
- Más claridad en reportes.
- Mejor rendimiento visual.
Paso 9: registrar eventos, no todos los frames
Un error común es guardar una imagen por cada frame detectado. Eso llena el disco y genera datos inútiles.
Mejor registra eventos.
Ejemplo de evento:
2026-05-13 10:34:12 | person | ID 7 | entró a zona de interés | evidencia.jpg
Esto es más útil que guardar miles de imágenes repetidas.
Paso 10: medir rendimiento
Un sistema serio debe medir al menos:
| Métrica | Por qué importa |
|---|---|
| FPS | Indica fluidez |
| Latencia | Tiempo de respuesta |
| Falsos positivos | Detecciones incorrectas |
| Falsos negativos | Objetos no detectados |
| Uso de CPU/GPU | Capacidad del equipo |
| Tamaño de evidencias | Control de almacenamiento |
| Tiempo activo | Estabilidad del sistema |
Si el sistema funciona a 4 FPS, puede servir para análisis lento, pero quizá no para monitoreo en tiempo real.
Paso 11: evitar falsos positivos
Técnicas prácticas:
- Subir confianza mínima:
CONF_MINIMA = 0.65
- Filtrar clases.
- Definir zona de interés.
- Registrar evento solo si dura varios frames.
- Mejorar iluminación.
- Ajustar ángulo de cámara.
- Usar modelo más preciso.
- Entrenar modelo propio.
- Usar tracking para no duplicar eventos.
- Revisar evidencias manualmente en fase piloto.
Paso 12: agregar persistencia mínima de evento
Para evitar registrar algo que apareció solo un frame, puedes exigir persistencia.
Ejemplo conceptual:
Solo registrar evento si el objeto aparece en la zona durante 10 frames consecutivos.
Esto reduce falsas alertas por sombras, reflejos o detecciones momentáneas.
Paso 13: privacidad por diseño
Si el sistema procesa personas, debes considerar privacidad desde el inicio.
Buenas reglas:
- No grabar audio si no es necesario.
- No guardar video continuo si basta con eventos.
- No identificar personas si solo necesitas contarlas.
- Desenfocar rostros si no son necesarios.
- Informar si hay monitoreo.
- Limitar acceso a evidencias.
- Definir tiempo de retención.
- Evitar subir imágenes sensibles a servicios externos.
- Cumplir normativa de datos personales aplicable.
- Documentar finalidad del sistema.
Diferencia importante:
| Acción | Nivel de riesgo |
|---|---|
| Detectar que hay una persona | Menor |
| Identificar quién es la persona | Mucho mayor |
| Guardar rostro asociado a nombre | Alto |
| Cruzar con base de datos biométrica | Muy alto |
Paso 14: no confundir detección facial con reconocimiento facial
Este post se enfoca en detección y tracking de objetos.
| Concepto | Significado |
|---|---|
| Detección de rostro | Saber que hay una cara en la imagen |
| Reconocimiento facial | Identificar de quién es la cara |
| Detección de objetos | Detectar clases como persona, celular o laptop |
| Tracking | Mantener un ID del objeto entre frames |
Para proyectos serios, evita reconocimiento facial de identidad salvo que tengas base legal, consentimiento, seguridad, finalidad clara y controles estrictos.
Caso práctico 1: control de aforo
Objetivo:
Contar personas que entran en una zona.
Configuración:
CLASES_INTERES = {"person"}
CONF_MINIMA = 0.60
Reglas:
- Cámara fija.
- Zona de interés en entrada.
- Tracking activo.
- Registrar persona solo una vez por ID.
- No guardar rostros si no es necesario.
Uso:
- Oficinas.
- Eventos.
- Laboratorios.
- Salas de espera.
- Aulas.
Caso práctico 2: detección de celulares en área restringida
Objetivo:
Detectar uso visible de celulares en una zona.
Configuración:
CLASES_INTERES = {"cell phone"}
CONF_MINIMA = 0.50
Advertencia:
YOLO puede fallar con celulares pequeños o parcialmente ocultos. Para un proyecto serio, probablemente necesites:
- Cámara cercana.
- Buena resolución.
- Dataset propio.
- Entrenamiento adicional.
- Validación humana.
- Política clara de privacidad.
Caso práctico 3: detección de EPP en obra
Objetivo:
Detectar casco o chaleco.
Problema:
Los modelos generales normalmente no son suficientes para EPP específico.
Solución profesional:
- Recolectar imágenes del entorno real.
- Etiquetar casco, chaleco, botas u otros elementos.
- Entrenar modelo YOLO personalizado.
- Validar con datos no usados en entrenamiento.
- Probar en cámara real.
- Medir falsos positivos y falsos negativos.
- Definir umbral de confianza.
- Integrar alertas.
Caso práctico 4: monitoreo de objetos en almacén
Objetivo:
Detectar presencia de cajas, pallets, personas o vehículos.
Recomendaciones:
- Cámara fija.
- Buena iluminación.
- Zonas de interés.
- Clases bien definidas.
- Registro por evento.
- Validación manual en fase piloto.
- Integración posterior con base de datos.
Errores comunes y soluciones
Error 1: usar la webcam de prueba como si fuera producción
Solución:
Prueba con la cámara real, ubicación real, iluminación real y ángulo real.
Error 2: detectar todas las clases
Solución:
Filtra solo lo que realmente importa.
Error 3: guardar video continuo sin necesidad
Solución:
Guarda eventos y evidencias puntuales.
Error 4: no medir falsos positivos
Solución:
Durante el piloto, revisa cada evento y clasifica si fue correcto o incorrecto.
Error 5: usar reconocimiento facial sin base clara
Solución:
Si solo necesitas contar personas, no identifiques personas.
Error 6: no controlar desconexión de cámara
Solución:
Agrega reconexión, logs y monitoreo del proceso.
Error 7: no separar configuración del código
Solución:
Usa config.py o archivo .yaml.
Buenas prácticas profesionales
-
Define el objetivo antes de elegir modelo.
-
Usa cámara y escenario reales desde el piloto.
-
Filtra clases relevantes.
-
Usa tracking para evitar duplicados.
-
Registra eventos, no todos los frames.
-
Mide FPS, falsos positivos y falsos negativos.
-
Evita reconocimiento biométrico si no es necesario.
-
Aplica privacidad por diseño.
-
Entrena modelo propio si los objetos son específicos.
-
Documenta configuración, modelo y versión.
Checklist para considerar el sistema “serio”
| Revisión | Estado |
|---|---|
| Objetivo definido | ☐ |
| Cámara real probada | ☐ |
| Modelo elegido por rendimiento y precisión | ☐ |
| Tracking activo | ☐ |
| Zona de interés definida | ☐ |
| Eventos registrados | ☐ |
| Evidencias guardadas de forma controlada | ☐ |
| Falsos positivos medidos | ☐ |
| Privacidad evaluada | ☐ |
| Logs disponibles | ☐ |
| Configuración separada | ☐ |
| Prueba piloto ejecutada | ☐ |
Próximos pasos para producción
Si quieres pasar de prototipo a producción, considera:
- Ejecutarlo como servicio.
- Guardar eventos en SQLite o PostgreSQL.
- Crear dashboard web.
- Agregar autenticación.
- Usar Docker.
- Implementar logs rotativos.
- Integrar alertas por correo o Telegram.
- Usar GPU o edge device.
- Entrenar modelo propio.
- Definir política de retención de evidencias.
- Documentar consentimiento y finalidad.
Idea clave
Un proyecto serio de visión por computadora no se mide solo por detectar objetos, sino por convertir detecciones en eventos confiables, trazables y útiles. La combinación de OpenCV, YOLO, tracking, zonas de interés, registro de eventos y privacidad por diseño permite construir una base profesional sobre la cual sí se puede crecer hacia producción.
Tips relacionados
Videos verticales con IA: cómo crear Reels, Shorts y TikToks sin grabar desde cero
Los generadores de video con IA están entre los temas más buscados porque prometen crear contenido para redes sin cámara, locación ni equipo de producción. Esta guía explica cómo producir videos verticales con IA de forma profesional: idea, guion, prompt visual, formato 9:16, edición, revisión de errores y publicación responsable.
Inteligencia artificial aplicadaGemini Intelligence en Android: cómo preparar tu celular para la nueva generación de asistentes con IA
Google anunció Gemini Intelligence para Android, una nueva etapa donde el asistente no solo responde preguntas, sino que puede automatizar tareas entre apps, resumir páginas, llenar formularios, crear widgets y ayudar de forma más contextual. Esta guía explica qué significa, qué beneficios trae, qué riesgos revisar y cómo preparar tu celular antes de activar funciones de IA más proactivas.
Inteligencia artificial aplicadaConecta tu cámara con Python: detección de rostros y objetos en tiempo real con OpenCV y YOLO
Aprende a convertir tu webcam en un sistema básico de visión por computadora. Esta guía práctica muestra cómo abrir la cámara con Python, detectar rostros con OpenCV, detectar objetos con YOLO y aplicar buenas prácticas para crear un prototipo útil sin complicarte con teoría innecesaria.