Analítica de video
Sistema de análisis automático de videos de dashcam desplegado como Google Cloud Functions Gen2. Procesa videos almacenados en Google Cloud Storage y publica el resultado a la API.
Funciones desplegadas
visual-analytics — trigger Cloud Storage
Se dispara automáticamente cuando se sube un archivo .mp4 al bucket configurado.
Trigger: google.cloud.storage.object.v1.finalized
Detector utilizado: se resuelve a partir del campo eventType en los metadatos del objeto GCS:
eventType en metadata | Detector |
|---|---|
tapado_camara_tapa | oclusion_s |
tapado_camara_valvula | oclusion_v |
LEFT_LANE_DEPARTURE | cambio_carril |
| ausente o sin detector asignado | estado_rutas (fallback) |
Metadatos del objeto GCS esperados:
metadata.incidenteId → ID del incidente asociado
metadata.eventType → tipo de evento (determina el detector)
visual-analytics-http — trigger HTTP
Permite disparar el análisis a demanda vía POST HTTP. Requiere autenticación IAM (roles/run.invoker).
URL: https://us-central1-{PROJECT}.cloudfunctions.net/visual-analytics-http
Body JSON:
{
"id": 438,
"bucket": "playback-producto",
"object": "a4137452-8c6e-41aa-94b6-059a7d86021f.mp4",
"incidenteId": "262951694",
"detector": "cambio_carril"
}
| Campo | Requerido | Descripción |
|---|---|---|
bucket | ✅ | Nombre del bucket GCS |
object | ✅ | Path del archivo en el bucket |
detector | ✅ | Nombre canónico del detector (ver tabla abajo) |
id | No | ID del registro AnaliticaVideo a actualizar con el resultado |
incidenteId | No | ID del incidente asociado |
Nombre canónico de detectores (campo detector):
detector | Equivalente eventType Cloud Storage |
|---|---|
oclusion_s | tapado_camara_tapa |
oclusion_v | tapado_camara_valvula |
cambio_carril | LEFT_LANE_DEPARTURE |
estado_rutas | (fallback) |
Respuestas:
| Código | Descripción |
|---|---|
| 200 | Procesamiento completado |
| 400 | Faltan campos requeridos o detector desconocido |
| 501 | Detector válido pero aún no implementado en la Cloud Function |
| 500 | Error interno durante el procesamiento |
Detectores implementados
oclusion_s / oclusion_v
Detecta oclusión de cámara (tapaduras). oclusion_s analiza la mitad superior del frame, oclusion_v la mitad inferior.
Output:
{
"estado": "TAPADO | LIBRE",
"causa": "...",
"n_eventos": 2,
"hay_intervencion": true,
"frac_ocluida_max": 0.87,
"fps_detectado": 15.0,
"frames_totales": 450,
"alerta_activa": true
}
cambio_carril
Detecta cambio de carril no señalizado mediante segmentación de calzada.
Output:
{
"estado": "CAMBIO_DE_CARRIL | SIN_CAMBIO | REVISAR_MANUAL | ERROR",
"n_eventos": 1,
"alerta_activa": true
}
estado_rutas
Detecta el estado de la calzada por análisis de vibración inter-frame. No requiere modelo de ML.
Utiliza un filtro de Kalman 1D para separar la vibración de alta frecuencia (irregularidades de la ruta) del movimiento general de cámara. La clasificación requiere que se cumplan dos condiciones simultáneamente:
hf_p75 ≥ umbral_rugosidad(4.0 por defecto)pct_alto ≥ min_pct_alto(35% de frames con vibración sostenida)
Output:
{
"estado": "MAL_ESTADO | BUEN_ESTADO | SIN_DATOS | ERROR",
"algoritmo_version": "kalman_v1",
"rugosidad_score": 4.21,
"hf_p75": 4.21,
"pct_alto": 0.67,
"cv_diffs": 1.03,
"jerk_p75": 14.5,
"diff_media": 8.3,
"diff_std": 4.1,
"n_frames": 497,
"alerta_activa": true
}
Output común (publicado a la API)
Ambas funciones publican el resultado via POST a ANALITICA_VIDEO_API_URL:
{
"incidenteId": "262951694",
"id": 438,
"estado": "SUCCESS",
"detector": "estado_rutas",
"bucket": "playback-producto",
"object": "a4137452-8c6e-41aa-94b6-059a7d86021f.mp4",
"resultado": { ... }
}
El campo id solo está presente cuando la función fue invocada vía HTTP con un id en el body.
Dónde se guarda el resultado
El resultado se persiste en el modelo AnaliticaVideo de la API (api.silsx.com/api/analiticaVideos).
- Si el POST incluye
id: actualiza el registro existente (updateAttributes). - Si el POST no incluye
id: crea un registro nuevo.
El hook after save del modelo re-encola una nueva tarea de análisis solo cuando se crea un registro sin campo resultado (es decir, una tarea pendiente nueva). Cuando la Cloud Function postea su resultado (que siempre incluye resultado), no se re-dispara.
Adicionalmente, si alerta_activa es true y PUBSUB_TOPIC está configurado, la función publica el payload completo en el topic de Pub/Sub correspondiente.
Visualización del resultado
El resultado del análisis se puede consultar desde la vista Histórico de video de la plataforma. Cada evento de video tiene un botón que abre un modal con el detector utilizado y el JSON de resultado.

El modal muestra:
- Detector: nombre del detector que procesó el video (ej.
LEFT_LANE_DEPARTURE) - Resultado: JSON completo con el estado y las métricas calculadas
Variables de entorno requeridas
| Variable | Descripción |
|---|---|
ANALITICA_VIDEO_API_URL | URL del endpoint de la API donde se publica el resultado |
ANALITICA_VIDEO_API_AUTH | Header de autorización (Basic BASE64(usuario:password)) |
PUBSUB_TOPIC | Topic de Pub/Sub para alertas (opcional) |