# Piloto 03: Amalia — personas, POS y revisión asistida Demo local del video completo A06_20260928084532.mp4 con los cuatro tickets reales compartidos por el usuario. No es monitoreo en vivo. El original reporta 13,538 cuadros, 15 FPS, 960 × 1088 y unos 15 min 3 s. Se decodificó completo secuencialmente; saltar directamente en el original produce errores HEVC en OpenCV. La copia completa H.264 facilita la reproducción en navegador. El reloj visible inicial marca 2026-09-28 08:45:29; el nombre sugiere 08:45:32. No usar el nombre para sincronizar automáticamente. ## Abrir Desde esta carpeta, con Python 3: ```sh python servir.py ``` Abrir http://127.0.0.1:8766. El servidor escucha solo en la máquina local y soporta HTTP Range para navegar por el MP4. Ctrl+C lo detiene. ## Datos incorporados y sincronización Los dos resultados SQL fueron pegados en el chat por el usuario y transcritos en pos.js. No hubo conexión directa a Hostinger. Cuatro tickets, cinco renglones, $197 MXN; pagos guardados una vez por ticket. Las sumas de detalle coinciden con efectivo + tarjeta en los cuatro tickets. Con desfase cero, dentro del video: ticket 83119 ($10, segundo 64) y ticket 83120 ($42, segundo 320). Sus artículos se registraron en los segundos 61 y 317. Los tickets 83117 ($102) y 83118 ($43) son anteriores al inicio. Total del horario del video: $52; no es una cifra de venta diaria. El ajuste es POS menos DVR, en segundos. Un POS adelantado 60 segundos requiere +60; el segundo del video se calcula como hora POS - inicio DVR - desfase. La correlación no ha sido validada visualmente. La etiqueta junto al video aparece a ±15 segundos del registro del artículo o ticket. No demuestra entrega del producto ni irregularidad. El umbral usa mayor estricto, por ticket completo, solo entre tickets cuya hora cae en el video con el desfase elegido. Los ajustes son temporales y vuelven a cero/$100 al recargar. Las decisiones del supervisor se guardan en localStorage, separadas por configuración de reglas, zona, desfase y versión del análisis. No se publican en Hostinger. Validación de tiempos, totales y umbral: `node sync.test.cjs`. Validación de revisión, presencia y cobertura: `node revision.test.cjs`. ## Revisión asistida incorporada Se analizaron los 902.533 segundos a 1 Hz: 903 muestras. YOLOv8s, entrada 640, confianza mínima 0.45, ensanchamiento horizontal experimental 1.5 solo para inferencia. Las cajas se transforman a las coordenadas del video original. Se compararon proporciones en cinco fotogramas y se inspeccionaron diez muestras adicionales; no es una validación independiente de precisión. El archivo de video no se altera por ese ajuste. Se suprimen cajas duplicadas con IoU > 0.5, conservando la de mayor puntuación; las suprimidas quedan en datos.json. Con zona de toda la imagen y desfase cero: - Máximo detectado: 1 persona simultánea (no personas únicas ni clientes). - Suma de muestras positivas: 276.533 s, mostrados como 04:36. - 8 revisiones: 2 tickets y 6 intervalos de presencia sin registro POS cercano. - Ticket 83119: máximo 1 detección en ±15 s; ticket 83120: 0 detecciones en esa ventana. Cero detecciones no demuestra que no hubiera una persona. La regla de presencia necesita al menos 15 s de muestras positivas. Une huecos de hasta 3 s, que no suman tiempo observado. Busca artículos o tickets en un margen de 45 s antes y después de cada intervalo. Si ese margen queda fuera de la exportación, muestra falta de cobertura en lugar de ausencia de POS. Zona, margen y presencia mínima son configurables. La zona cuenta centros de cajas; no identifica roles. La actividad de un cajero puede generar estos avisos sin que exista ninguna irregularidad. No se detectan productos, cobros omitidos ni entrega de tickets. No se estiman pérdidas ni se toman decisiones sobre personal. Estados del supervisor: Pendiente, Revisado sin hallazgo, Descartado y Requiere seguimiento; permite notas y exportación JSON del contexto y las decisiones. Se verificó persistencia al recargar y aislamiento al cambiar el desfase; los datos de prueba se retiraron y las ocho revisiones quedaron pendientes. Ocho clips MP4 están en clips/, con contexto de 15 s antes/después, limitado por los extremos del video. Se verificaron decodificación y duración. clips.json registra sus posiciones en el original. Son recortes de la copia H.264 de revisión, sin audio; no sustituyen el archivo original. Las descargas aparecen cuando el intervalo coincide con un clip existente. Cambiar reglas puede producir otros intervalos: el botón Ver segmento reproduce el tramo del video completo y pausa al final, pero no genera nuevos archivos automáticamente. revision-inicial.json contiene las reglas y resultados iniciales para reproducir el recorte. `python exportar_clips.py` regenera los clips de ese resultado con FFmpeg instalado; si se cambia el análisis hay que actualizar primero ese JSON. ## Reproducir análisis Usar el entorno de vision_prueba (OpenCV, Ultralytics y sus dependencias). El script no tiene rutas absolutas ni cambia la aplicación del hotel. ```sh ffmpeg -i ../A06_20260928084532.mp4 -t 60 -an -vf scale=480:544 -c:v libx264 -preset fast -crf 23 -movflags +faststart muestra.mp4 ffmpeg -i ../A06_20260928084532.mp4 -an -vf scale=480:544 -c:v libx264 -preset fast -crf 23 -movflags +faststart amalia-completo.mp4 python analizar.py --model /ruta/al/yolov8s.pt --device cpu ``` Video completo, con detecciones precalculadas a 1 Hz. analizar.py usa por defecto amalia-completo.mp4 y escribe datos.json/datos.js al terminar. No reemplaza la versión anterior si la decodificación queda incompleta. Usa --video muestra.mp4 para analizar solo el extracto. Si no hay muestra, no se reutiliza la última ni se interpreta como cero personas. Las cajas no son seguimiento por identidad y quedan fijas entre muestras. Los conteos incluyen empleados y clientes, pueden omitir personas y no son aforo total, ventas ni incidentes. No se identifican productos ni se evalúa entrega de ticket. Se retiró el audio. ## Consulta para futuras exportaciones Ejecutar consulta_amalia.sql en Hostinger. Confirmar primero el nombre exacto de sucursal. Exportar por separado detalle y tickets en CSV con encabezados. Consulta revisada contra database/hostinger/schema_hostinger.sql; no ejecutada en la base remota. No se requieren contraseñas para entregar los resultados. La ventana 08:35–09:10 deja margen para desfase del DVR y diferencias entre registro del artículo y cierre del ticket. El nombre del artículo es del catálogo actual; el precio procede de la venta histórica. No sumar los pagos repetidos en el resultado de detalle. Ausencia de datos puede ser falta de sincronización. ## Etapas propuestas 1. Validar manualmente el desfase de los tickets vinculados con el supervisor. La vinculación provisional, artículos, cantidades e importes ya están incorporados. 2. El video completo ya está analizado. Falta validar con el usuario la zona de clientes/caja o incorporar una segunda cámara. Medir detecciones falsas y omisiones con muestras etiquetadas independientes; no inferir horas pico diarias a partir de quince minutos. 3. Piloto de una caja en vivo: RTSP + eventos de la base local de solo lectura, búfer de video y clips antes/después del evento. Mantener evidencia y estados pendiente, descartado y confirmado por supervisor. 4. Reglas iniciales: ticket sobre umbral configurable; actividad sin ticket cercano solo con sincronización saludable. Distinguir alertas, confirmaciones e importe revisado; no llamar pérdida al importe de una alerta. 5. Identificación de productos/entregas como experimento separado, sujeto a cámara, visibilidad y datos etiquetados. Un detector de personas no resuelve ese problema. ## Hardware y cotización La sesión de desarrollo detectó GeForce MX150; no es una medición del equipo i9. Validar GPU/VRAM y medir FPS, latencia, RAM, temperaturas y recuperación durante 24–72 horas en el equipo piloto antes de fijar mínimo o cámaras por máquina. Mantener Python/OpenCV/FastAPI del proyecto existente y elegir CPU/CUDA/MPS según disponibilidad, verificando cada plataforma; esta demo solo se probó en Windows. Propuesta de arquitectura a validar: procesamiento local y envío de eventos/clips al panel central, con cola cuando falta Internet. La sincronización nocturna sirve para revisión histórica; alertas en vivo necesitan datos locales oportunos. Cotizar por separado instalación por sucursal, equipo, mensualidad por cámara/caja, retención, soporte y posibles licencias. No hay precio comercial calculado aún. Presupuesto de almacenamiento decimal: GB/día ≈ Mbps × 10.8 por cámara continua. Ejemplo matemático: 2 Mbps × 14 cámaras × 30 días ≈ 9.07 TB, sin redundancia. Guardar solo clips reduce ese volumen según actividad y duración, a medir. Confirmar sucursales productivas: el README distingue 14 registradas e incluye OFICINA y DEVELOPMENT de pruebas; el usuario reporta 14 sucursales operativas. Revisar licencia de Ultralytics al cotizar la distribución comercial: https://www.ultralytics.com/license