Saltar al contenido principal

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 metadataDetector
tapado_camara_tapaoclusion_s
tapado_camara_valvulaoclusion_v
LEFT_LANE_DEPARTUREcambio_carril
ausente o sin detector asignadoestado_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"
}
CampoRequeridoDescripción
bucket✅Nombre del bucket GCS
object✅Path del archivo en el bucket
detector✅Nombre canónico del detector (ver tabla abajo)
idNoID del registro AnaliticaVideo a actualizar con el resultado
incidenteIdNoID del incidente asociado

Nombre canónico de detectores (campo detector):

detectorEquivalente eventType Cloud Storage
oclusion_stapado_camara_tapa
oclusion_vtapado_camara_valvula
cambio_carrilLEFT_LANE_DEPARTURE
estado_rutas(fallback)

Respuestas:

CódigoDescripción
200Procesamiento completado
400Faltan campos requeridos o detector desconocido
501Detector válido pero aún no implementado en la Cloud Function
500Error 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.

Resultado del análisis de video en Histórico de video

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​

VariableDescripción
ANALITICA_VIDEO_API_URLURL del endpoint de la API donde se publica el resultado
ANALITICA_VIDEO_API_AUTHHeader de autorización (Basic BASE64(usuario:password))
PUBSUB_TOPICTopic de Pub/Sub para alertas (opcional)