William Zhang2026-09-20

Sistema inteligente de reconocimiento facial con reComputer R2135

Detección, alineación y agrupamiento de personas y rostros en vídeo directamente en el reComputer (NPU Hailo-8) con YOLOv8n + SCRFD-10G + ArcFace MobileFaceNet. Genera automáticamente un "álbum de rostros" archivado por persona, explorable a través de una página web minimalista.

CVFace RecognitionYOLOGitHub

Construcción automática del álbum de rostros a partir de vídeo en reComputer

Un proyecto de archivado automático de álbumes de rostros basado en Hailo-8 / SCRFD / ArcFace en el dispositivo.

Puedes consultar el código fuente de este proyecto en GitHub: https://github.com/doublelf/person_face_sign


1. Descripción del proyecto

Person Face Sign es un proyecto para construir sin conexión un "álbum de rostros" en un dispositivo edge (reComputer + NPU Hailo-8). El objetivo principal es asignar automáticamente todos los rostros que aparecen en un vídeo de vigilancia o de actividad a sus respectivos "álbumes de identidad", para facilitar su consulta, contabilización o archivo posterior.

Problemas típicos que resuelve

  • Registro de visitas / gestión de visitantes: entrega al script varias horas de grabación de la cámara de recepción y genera automáticamente "hoy vinieron 23 personas, cada una con N imágenes".
  • Apoyo a la asistencia a clase / reuniones: las grabaciones de clase se archivan por persona, como base para el pase de lista electrónico.
  • Organización automática de fotos de eventos: fusiona y agrupa grabaciones multicámara y multiángulo del lugar para generar automáticamente álbumes agrupados por persona.
  • Búsqueda secundaria en material de vídeo: buscar por persona, no por marca de tiempo.

Pipeline principal

Code
Vídeo (data/*.mp4)
    │
    ▼
[VideoSampler] —— 1 fotograma por segundo (1280×720)
    │
    ▼
[YOLOv8n] —— Detección de personas (640×640)
    │
    ▼
[IoUTracker] —— Seguimiento de personas + muestreo de rostros limitado (desactivable)
    │
    ▼
[SCRFD-10G] —— Detección de rostros + 5 landmarks
    │
    ▼
[FaceAlign 5pt] —— Alineación afín a 112×112
    │
    ▼
[ArcFace MobileFaceNet] —— Embedding L2-norm de 512-d
    │
    ▼
[AlbumCluster] —— pHash preferente / Faiss HNSW como respaldo → asignación de person_id
    │
    ▼
[AlbumStorage] —— Escritura de archivos + doble dedup + actualización de manifest.json
    │
    ▼
[Web Browser :8080] —— Navegar / buscar el resultado

2. Inicio rápido

A continuación se muestra un flujo de extremo a extremo que, ejecutado en orden, permite construir un álbum de rostros navegable en el reComputer.

2.1 Clonar el repositorio

bash
git clone https://github.com/doublelf/person_face_sign.git
cd person_face_sign

2.2 Crear el entorno virtual

Se recomienda usar venv (incluido en Python, sin instalación adicional).

bash
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip

2.3 Instalar dependencias de Python

bash
pip install -r requirements.txt

2.4 Instalar las dependencias previas a nivel de sistema

build_album.py invoca ffmpeg / ffprobe a través de subprocess para el muestreo de fotogramas, por lo que deben instalarse a nivel de sistema:

bash
# Debian / Ubuntu (incluido reComputer)
sudo apt update
sudo apt install -y ffmpeg

# Verificar
ffmpeg -version | head -n 1
ffprobe -version | head -n 1

2.5 Preparar los archivos del modelo HEF

Code
person_face_sign/
└── models/
    ├── yolov8n.hef                    # ~4.3 MB
    ├── scrfd_10g.hef                  # ~10 MB
    └── arcface_mobilefacenet.hef      # ~5 MB
UsoModeloRuta predeterminada (hard-coded en build_album.py)Origen real
Detección de personasYOLOv8n<raíz del proyecto>/models/yolov8n.hefIntegrado en la imagen Docker oficial, ruta en contenedor /app/model/yolov8n.hef
Detección de rostrosSCRFD-10G<raíz del proyecto>/models/scrfd_10g.hefIncluido en el paquete .deb de HailoRT (puede copiarse a models/)
Embedding de rostrosArcFace MobileFaceNet<raíz del proyecto>/models/arcface_mobilefacenet.hefIncluido en el paquete .deb de HailoRT (puede copiarse a models/)

2.5.1 Obtener SCRFD + ArcFace (lo más sencillo)

Los HEF de SCRFD-10G y ArcFace MobileFaceNet son modelos precompilados oficialmente por Hailo. Se instalan en /usr/local/hailo/resources/models/hailo8/ con el paquete hailort — solo cópialos al directorio models/ de este proyecto:

bash
sudo apt install hailort
ls /usr/local/hailo/resources/models/hailo8/
# Deberías ver:
#   arcface_mobilefacenet.hef
#   scrfd_10g.hef
#   además de otros modelos de ejemplo oficiales

# Copiar al directorio models/ local del proyecto
cp /usr/local/hailo/resources/models/hailo8/scrfd_10g.hef            models/
cp /usr/local/hailo/resources/models/hailo8/arcface_mobilefacenet.hef models/
ls -lh models/

2.5.2 Obtener YOLOv8n

Consulta https://sensecraft.seeed.cc/ai-lab/en/models/yolov8/hailo-8. El HEF de YOLOv8n ya está empaquetado en ghcr.io/seeed-projects/recomputer-r20-cv/yolov8:latest. La ruta dentro del contenedor es /app/model/yolov8n.hef.

bash
mkdir -p models

# 1. Descargar la imagen oficial
docker pull ghcr.io/seeed-projects/recomputer-r20-cv/yolov8:latest

# 2. Crear una instancia de contenedor que no se ejecuta con `create` (solo para obtener el archivo)
docker create --name yolov8-temp ghcr.io/seeed-projects/recomputer-r20-cv/yolov8:latest

# 3. Copiar yolov8n.hef desde el contenedor al directorio models/ del proyecto
docker cp yolov8-temp:/app/model/yolov8n.hef models/yolov8n.hef

# 4. Limpiar el contenedor temporal
docker rm yolov8-temp

# 5. Verificar
ls -lh models/yolov8n.hef

2.6 Construir el álbum de rostros (paso principal)

El repositorio incluye un vídeo de demostración data/tex.mp4 (unos 11 MB). Ejecuta el siguiente comando para generar el álbum:

bash
python apps/build_album.py \
  --video data/tex.mp4 \
  --out data/album \
  --no-tracker \
  --scrfd-score 0.6 \
  --cluster-thresh 0.85 \
  --skip-dedup

Parámetros:

ParámetroValorDescripción
--videodata/tex.mp4Vídeo de entrada; puede especificarse varias veces o separarse por comas
--outdata/albumDirectorio de salida del álbum
--no-trackerflagDesactiva el IoU tracker; toma cada rostro en cada fotograma (recomendado para vídeos cortos)
--scrfd-score0.6Umbral de confianza de detección de rostros SCRFD (predeterminado 0.60)
--cluster-thresh0.85Agrupamiento laxo: umbral de distancia coseno; ver sección 4.2 para más detalles
--skip-dedupflagSalta el doble dedup pHash/embedding al escribir (mantiene el clustering con prioridad pHash)

Tras la compilación, en data/album/ aparecerá:

Code
data/album/
├── manifest.json
├── thumbnails/
│   ├── person_0001.jpg
│   ├── person_0002.jpg
│   └── ...
├── person_0001/
│   ├── representative.jpg
│   ├── info.json
│   ├── embeddings.npz
│   └── img_0001_ts_2.00s_score_0.78.jpg
│   └── img_0002_ts_5.00s_score_0.74.jpg
│   └── ...
├── person_0002/
└── ...

2.7 Iniciar el servicio web de navegación del álbum

Tras la compilación, abre otra terminal e inicia el servicio web minimalista:

bash
python apps/web_browser.py --port 8080

Accede en el navegador a http://<reComputer-IP>:8080/:

  • La barra superior de estadísticas muestra el número total de personas, de imágenes y de vídeos de origen;
  • La cuadrícula principal muestra, según "1 imagen = 1 persona", las miniaturas (procedentes de representative.jpg, ordenadas de forma descendente por número de imágenes);
  • Haz clic en una persona para acceder a la página de detalle con todas sus img_*.jpg;
  • Haz clic en cualquier imagen para abrir el visor a pantalla completa.

3. Interpretación del resultado

3.1 Estructura del directorio de datos

Code
data/album/
├── manifest.json                    # Estadísticas globales + lista de personas (fuente de datos de la Web UI)
├── thumbnails/
│   └── person_<id>.jpg              # Miniatura (copia de representative.jpg)
└── person_<NNNN>/                   # Un directorio por identidad; NNNN es un ID con relleno de ceros de 4 dígitos
    ├── info.json                    # Metadatos por persona: count / first_ts / last_ts / best_score / source_videos
    ├── embeddings.npz               # Top-N embeddings de esta persona (predeterminado N=5, ordenados por score)
    ├── representative.jpg           # "Foto de portada" con mejor puntuación, también escrita en thumbnails/
    └── img_<NNNN>_ts_<ts>s_score_<score>.jpg  # Cada rostro retenido (tras alineación 112×112)

Ejemplos de convención de nombres:

  • person_0001/img_0001_ts_2.00s_score_0.78.jpg: 1.ª imagen, 2.00 segundos, SCRFD score = 0.78
  • person_0001/img_0014_ts_18.50s_score_0.82.jpg: 14.ª imagen, 18.50 segundos

3.2 Campos clave de manifest.json

json
{
  "version": "1.0",
  "created_at": "2026-09-26T10:23:11",
  "updated_at": "2026-09-26T10:24:48",
  "total_persons": 6,
  "total_images": 142,
  "source_videos": ["tex"],
  "config": {
    "interval_s": 1.0,
    "cosine_distance_threshold": 0.85,
    "min_face_size": [40, 40],
    "min_face_score": 0.6,
    "best_n_embeddings": 5,
    "phash_max_dist": 4
  },
  "persons": [
    {
      "id": 1,
      "count": 28,
      "first_ts": 2.0,
      "last_ts": 82.0,
      "best_score": 0.85,
      "source_videos": ["tex"],
      "thumbnail": "thumbnails/person_0001.jpg"
    },
    ...
  ]
}

Significado de los campos:

CampoSignificado
total_personsNúmero total de personas agrupadas (crece monotónicamente con builds incrementales)
total_imagesNúmero total de imágenes de rostros (tras deduplicación)
configSnapshot de los parámetros de este build (se reescribe en el álbum para trazabilidad)
persons[].countNúmero de imágenes de rostro de esta persona
persons[].first_ts / last_tsMarca de tiempo de la primera / última aparición (segundos)
persons[].best_scoreMayor puntuación de detección SCRFD

3.3 Interacciones de la UI web

El frontend usa solo http.server + HTML/CSS/JS estático, sin base de datos; todos los datos se leen en tiempo real desde manifest.json y el sistema de archivos.

Flujos principales de interacción:

  1. Página de inicio (/): carga /manifest.json y lista las miniaturas de todas las personas en orden descendente por count;
  2. Detalle de persona: haz clic en una miniatura → el backend hace glob de person_<id>/img_*.jpg → lista todas las imágenes;
  3. Vista previa de imagen: haz clic en una imagen → <dialog> modal a pantalla completa;
  4. Actualizar: haz clic en ↻ arriba para volver a cargar manifest.json.