William Zhang2026-09-20

基于 reComputer R2135的智能人脸识别系统

使用 YOLOv8n + SCRFD-10G + ArcFace MobileFaceNet 在 reComputer(Hailo-8 NPU)上对视频进行行人/人脸检测、对齐与聚类,自动生成按人员归档的「人脸相册」,并通过极简 Web 页面浏览。

CVFace RecognitionYOLOGitHub

基于 reComputer 的视频人脸自动相册构建

基于 Hailo-8 / SCRFD / ArcFace 的端侧人脸相册自动归档项目。

你可以在 GitHub 上查看本项目源代码:https://github.com/doublelf/person_face_sign


一、项目概述

Person Face Sign 是一个在边缘设备(reComputer + Hailo-8 NPU)上离线构建「人脸相册」的项目。它的核心目标是把一段监控/活动视频中所有出现的人脸自动归入各自的「身份相册」,方便事后翻查、统计或归档。

解决的典型问题

  • 来访登记 / 访客管理:把若干小时的前台摄像头录像交给脚本,自动生成「今天来了 23 个人,每人 N 张图」的结果。
  • 课堂 / 会议签到辅助:把课程录像按人头归档,作为电子点名依据。
  • 活动照片自动整理:把多机位、多角度的现场录像合并聚类,自动产出按人分组的相册。
  • 视频素材的二次检索:以人找人,而非以时间戳找人。

核心 Pipeline

Code
视频 (data/*.mp4)
    │
    ▼
[VideoSampler] —— 每 1 秒采 1 帧 (1280×720)
    │
    ▼
[YOLOv8n] —— 行人检测 (640×640)
    │
    ▼
[IoUTracker] —— 行人跟踪 + 节流采脸 (可关)
    │
    ▼
[SCRFD-10G] —— 人脸检测 + 5 点 landmarks
    │
    ▼
[FaceAlign 5pt] —— 仿射对齐到 112×112
    │
    ▼
[ArcFace MobileFaceNet] —— 512-d L2-norm embedding
    │
    ▼
[AlbumCluster] —— pHash 优先 / Faiss HNSW 兜底 → 分配 person_id
    │
    ▼
[AlbumStorage] —— 写文件 + 双去重 + 更新 manifest.json
    │
    ▼
[Web Browser :8080] —— 浏览/检索产物

二、快速开始

下面是一份端到端的复现流程,按顺序执行即可在 reComputer 上构建出一个可浏览的人脸相册。

2.1 克隆仓库

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

2.2 创建虚拟环境

推荐使用 venv(Python 内置,无需额外安装)。

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

2.3 安装 Python 依赖

bash
pip install -r requirements.txt

2.4 安装系统级前置依赖

build_album.py 通过 subprocess 调用 ffmpeg / ffprobe 跳帧采帧,需要在系统层安装:

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

# 验证
ffmpeg -version | head -n 1
ffprobe -version | head -n 1

2.5 准备 HEF 模型文件

Code
person_face_sign/
└── models/
    ├── yolov8n.hef                    # ~4.3 MB
    ├── scrfd_10g.hef                  # ~10 MB
    └── arcface_mobilefacenet.hef      # ~5 MB
用途模型默认路径(build_album.py 硬编码)实际来源
行人检测YOLOv8n<项目根>/models/yolov8n.hef官方 Docker 镜像内置,容器内路径 /app/model/yolov8n.hef
人脸检测SCRFD-10G<项目根>/models/scrfd_10g.hefHailoRT deb 包自带(可拷贝到 models/)
人脸嵌入ArcFace MobileFaceNet<项目根>/models/arcface_mobilefacenet.hefHailoRT deb 包自带(可拷贝到 models/)

2.5.1 获取 SCRFD + ArcFace(最简单)

SCRFD-10G 与 ArcFace MobileFaceNet 的 HEF 是 Hailo 官方预编译模型,随 hailort deb 包安装到 /usr/local/hailo/resources/models/hailo8/,直接拷贝到本项目 models/ 即可:

bash
sudo apt install hailort
ls /usr/local/hailo/resources/models/hailo8/
# 应当能看到:
#   arcface_mobilefacenet.hef
#   scrfd_10g.hef
#   以及若干其他官方示例模型

# 拷贝到项目本地 models/ 目录
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 获取 YOLOv8n

见 https://sensecraft.seeed.cc/ai-lab/en/models/yolov8/hailo-8,YOLOv8n HEF 已打包 ghcr.io/seeed-projects/recomputer-r20-cv/yolov8:latest 内,容器中路径为 /app/model/yolov8n.hef

bash
mkdir -p models

# 1. 拉取官方镜像
docker pull ghcr.io/seeed-projects/recomputer-r20-cv/yolov8:latest

# 2. 用 create 起一个不运行的容器实例(只为了拿到文件)
docker create --name yolov8-temp ghcr.io/seeed-projects/recomputer-r20-cv/yolov8:latest

# 3. 从容器里把 yolov8n.hef 拷到项目 models/ 下
docker cp yolov8-temp:/app/model/yolov8n.hef models/yolov8n.hef

# 4. 清理临时容器
docker rm yolov8-temp

# 5. 验证
ls -lh models/yolov8n.hef

2.6 构建人脸相册(核心步骤)

仓库自带一段演示视频 data/tex.mp4(约 11 MB)。运行下面这条命令即可生成相册:

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

参数含义:

参数取值说明
--videodata/tex.mp4输入视频,可多次指定或用逗号分隔
--outdata/album相册输出目录
--no-trackerflag关闭 IoU tracker,每帧每脸都采(短样本视频推荐)
--scrfd-score0.6SCRFD 人脸检测置信度阈值(默认 0.60)
--cluster-thresh0.85宽松聚合:cosine distance 阈值;详见 4.2 节
--skip-dedupflag跳过写入时的 pHash / embedding 双去重(仍会保留 pHash 优先的聚类)

构建完成后,data/album/ 下会出现:

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 启动 Web 相册浏览服务

构建完成后,另开一个终端,启动极简 Web 服务:

bash
python apps/web_browser.py --port 8080

浏览器访问 http://<reComputer-IP>:8080/:

  • 顶部统计条显示总人数、总图片数、源视频数;
  • 主体网格按「每张图 = 1 个人」展示缩略图(缩略图来自 representative.jpg,按图片数降序);
  • 点击某个人进入详情页,列出该 person 的所有 img_*.jpg;
  • 点击任意图片弹出全屏查看器。

三、产物解读

3.1 数据目录结构

Code
data/album/
├── manifest.json                    # 全局统计 + 人员列表(Web UI 的数据源)
├── thumbnails/
│   └── person_<id>.jpg              # 缩略图(= representative.jpg 的副本)
└── person_<NNNN>/                   # 每个身份一个目录,NNNN 为 4 位 zero-padded id
    ├── info.json                    # 单个人元数据:count / first_ts / last_ts / best_score / source_videos
    ├── embeddings.npz               # 该 person 排名前 N 的 embedding(默认 N=5,按 score 排序)
    ├── representative.jpg           # 得分最高的「封面照」,同步写到 thumbnails/
    └── img_<NNNN>_ts_<ts>s_score_<score>.jpg  # 每张保留的人脸 (112×112 对齐后)

文件命名规范示例:

  • person_0001/img_0001_ts_2.00s_score_0.78.jpg:第 1 张,2.00 秒,SCRFD score = 0.78
  • person_0001/img_0014_ts_18.50s_score_0.82.jpg:第 14 张,18.50 秒

3.2 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"
    },
    ...
  ]
}

字段含义:

字段含义
total_persons已聚类的人员总数(持续 build 时单调递增)
total_images所有人脸图片总数(去重后)
config本次 build 的参数快照(写回相册,便于追溯)
persons[].count该 person 的人脸图数量
persons[].first_ts / last_ts首次 / 末次出现的时间戳(秒)
persons[].best_score最高 SCRFD 检测分数

3.3 Web 界面交互

Web 端基于纯 http.server + 静态 HTML/CSS/JS,无数据库依赖,所有数据都从 manifest.json 与文件系统实时读取。

主要交互路径:

  1. 首页(/):拉取 /manifest.json,按 count 降序列出所有 person 的缩略图;
  2. 进入个人详情:点击缩略图 → 后端 glob person_<id>/img_*.jpg → 列出所有图;
  3. 大图预览:点击单图 → <dialog> 全屏弹窗;
  4. 刷新:点击顶部 ↻ 重新拉 manifest.json。