CountIn — Conteo de Ocupación por Visión Artificial en el Navegador
Un sistema de visión artificial para el navegador que cuenta personas en tiempo real. TensorFlow.js hace la detección; un seguidor propio y lógica geométrica de cruce de líneas se encargan del conteo — todo en el cliente, nada sale del dispositivo.
CountIn es un sistema de visión artificial para el navegador que cuenta personas en tiempo real, para gestión de ocupación y analítica de multitudes. Se ejecuta por completo con TensorFlow.js, 100% en local dentro de tu navegador — sin servidor, privacidad completa. Dibuja líneas de conteo virtuales en entradas y salidas y contará a cada persona que las cruce, registrando la dirección (entrantes frente a salientes).
Por qué molestarse
El conteo de ocupación suele resolverse de dos maneras: una persona con un contador manual, o hardware caro (sensores cenitales, cámaras dedicadas con procesamiento integrado) conectado a un backend. Lo primero no escala; lo segundo cuesta dinero de verdad y envía datos a algún sitio.
CountIn es la versión en la que cualquier portátil con webcam se convierte en un contador de ocupación. El modelo y el seguimiento se ejecutan en el navegador. No hay instalación, ni factura en la nube, ni límites de API, y el flujo de la cámara nunca sale del equipo. Eso lo hace útil para eventos puntuales y seguro de apuntar a una sala — no se graba ni transmite nada.
Cómo funciona
El pipeline tiene cuatro etapas, todas en el cliente:
Webcam → detección con TensorFlow.js → seguimiento propio →
detección de cruce de línea → conteos → panel
Detección. Un modelo COCO-SSD cargado con TensorFlow.js identifica personas en cada fotograma y devuelve sus cajas delimitadoras. (RF-DETR está disponible como detector alternativo.) La detección se ejecuta cada dos fotogramas para mantener la UI responsiva.
Seguimiento. Aquí no hay librería de seguimiento, sino una implementación propia basada en centroides. Cada caja detectada se convierte en un objeto seguido identificado por el centro de su caja. Entre fotogramas, las nuevas detecciones se emparejan con los tracks existentes por distancia euclídea, filtradas por un umbral de confianza que elimina los falsos positivos parpadeantes. Cada track guarda un historial corto de posiciones para que su trayectoria sea estable ante oclusiones momentáneas, y los tracks que desaparecen demasiado tiempo se descartan. El resultado es un conjunto de IDs persistentes que sobreviven entre fotogramas.
Cruce de línea. Contar es geometría. El usuario dibuja uno o más segmentos en el canvas; para cada track, el sistema comprueba si el segmento entre su posición anterior y la actual intersecca una línea de conteo. Esa prueba es un producto vectorial — el mismo truco de intersección de segmentos que cabría escribir para cualquier colisión 2D — con un signo direccional que resuelve si el cruce es una entrada o una salida. Cada línea mantiene sus propios conteos de entrada/salida.
El panel. Los conteos se actualizan en tiempo real, por línea, con la ocupación en vivo derivada de la diferencia entrantes/salientes. Hay un registro de eventos de cruce y un gráfico histórico del flujo de multitud a lo largo del tiempo. Todo el estado vive en memoria en la página.
Lo destacable
Seguidor escrito a mano. Recurrir a una librería de seguimiento habría ocultado justo las partes que conviene entender — por qué funciona el emparejamiento por centroides, cómo los umbrales de confianza limpian el ruido, cómo sobrevivir a la oclusión sin perder la identidad. La implementación desde cero deja el sistema totalmente depurable: al desviarse los conteos, la etapa del fallo se localiza con exactitud.
Contar como geometría. La lógica de cruce de línea son unas líneas de matemática vectorial y es la parte más limpia del sistema. Sin heurísticas, sin ML para el conteo en sí — solo un producto vectorial con signo. Un buen recordatorio de que los proyectos de “IA” son a menudo sobre todo ingeniería corriente en torno a un núcleo ML pequeño.
Realmente sin servidor. La privacidad aquí no es un ajuste, es estructural. El permiso de la cámara es el único permiso, el modelo se descarga una vez y se cachea, y tras cargar la página funciona sin conexión. Apuntar una webcam a una multitud y contarla sin que se suba nada es precisamente la idea.
Trabajo de rendimiento real. El rendimiento de TensorFlow.js varía enormemente según el hardware y el modelo puede consumir más de 500 MB de memoria. Procesar cada dos fotogramas, mantener las actualizaciones del DOM al mínimo y renderizar en canvas en vez de en el DOM es lo que hace que se sienta en tiempo real en lugar de una presentación a tirones.
Stack
- ML: TensorFlow.js con COCO-SSD (y RF-DETR) para la detección de personas
- Código propio:
PersonTrackerbasado en centroides,LineManagergeométrico (intersección por producto vectorial) - Frontend: JavaScript plano (ES6+), HTML5 Canvas, CSS — sin framework, sin paso de build
- Arquitectura: orientada a eventos y modular; un tick de detección se propaga al seguimiento, luego al conteo, luego a la UI
Estado
Completado y usable. Listo para producción en uso local, probado en navegadores modernos y en una variedad de dispositivos. La demo en vivo está en countin.ignacio.tech — funciona mejor en un Chrome, Firefox, Safari o Edge reciente, con webcam, buena iluminación y unos 4 GB de RAM. O clona el repo y ejecútalo en local; es solo HTML, JS y CSS estáticos.