7.2 KiB
PRD:全离线生成 face_gallery.db(每人多条 embedding,Windows+Python+ONNX)
- 背景与目标 • 在 Windows 电脑上离线处理“注册照片”,为每个人生成多条 512D 人脸特征(每张有效照片 1 条 embedding),写入 SQLite 数据库 face_gallery.db。 • RK3588 运行时 ai_face_recog 以 gallery.backend=sqlite 读取该库,实现识别(无需改线上阈值/配置逻辑)。
──────────────────────────────────────────
- 范围(In/Out)
In Scope • 数据集扫描(按人目录) • 人脸检测(含 5 点关键点)+ 对齐到 112×112 • ArcFace/MobileFaceNet ONNX 推理生成 512D embedding • 生成 SQLite:person、embedding 两表 • 生成构建报告(统计、异常、可选相似度抽检)
Out of Scope • 在线注册/写库接口 • RKNN 推理/设备端工具 • 人脸库增量热更新(只生成 db 文件)
──────────────────────────────────────────
- 用户与使用方式
目标用户 • 开发/测试人员(在 Windows 上离线准备人脸库)
使用方式(CLI)
提供脚本:build_gallery.py 示例:
bash python build_gallery.py ^ --dataset "D:\faces\dataset" ^ --db_out "D:\faces\face_gallery.db" ^ --det_model "D:\models\face_det.onnx" ^ --recog_model "D:\models\mobilefacenet_arcface_bs1.onnx" ^ --expected_dim 512 ^ --max_imgs_per_person 10 ^ --pick_face largest ^ --min_face_size 80 ^ --fail_on_empty true
──────────────────────────────────────────
- 输入数据规范
目录结构
dataset/
张三/
001.jpg
002.jpg
李四/
a.png
b.png
• 文件夹名作为 person.name(UTF-8) • 每人建议 3~10 张图(允许混合:标准大头照 + 摄像头位照片)
图片支持格式 • jpg/jpeg/png/bmp(由 OpenCV 读取)
──────────────────────────────────────────
- 模型与前处理规范(必须严格一致)
识别模型(已确定) • 输入:float32 [1,3,112,112],输出:float32 [1,512] • 输入图像为 对齐后的 112×112 RGB • 归一化:(x - 127.5) / 128.0,其中 x 为 uint8 0..255 • HWC→CHW→NCHW
检测模型(你不要求我管来源,但脚本必须满足) • det ONNX 推理输出至少包含:bbox + 5 landmarks • 必须明确 landmark 顺序(开发在配置/代码中固定)
对齐目标点(112×112,必须固定为以下值) • (38.2946, 51.6963) • (73.5318, 51.5014) • (56.0252, 71.7366) • (41.5493, 92.3655) • (70.7299, 92.2041)
对齐方法: • 基于 5 点求相似变换(Similarity / affine partial)→ warpAffine 到 112×112,双线性插值
──────────────────────────────────────────
- 特征生成与入库(每人多条 embedding)
对每张有效图片:
- 检测 → 选择人脸(默认:最大脸)
- 5 点对齐 → 112×112 RGB
- 预处理 + ONNX 推理 → 512D embedding
- L2 normalize(单样本)
对每个人: • 取最多 max_imgs_per_person 张有效样本 embedding(不足也可) • 每张有效样本保留 1 条 embedding • 同一 person 可写入多条 embedding
──────────────────────────────────────────
- SQLite 数据库规范(必须与现有插件兼容)
文件 • 输出文件名:face_gallery.db(路径由 --db_out 指定)
表结构(最小要求)
sql CREATE TABLE IF NOT EXISTS person ( id INTEGER PRIMARY KEY, name TEXT NOT NULL UNIQUE );
CREATE TABLE IF NOT EXISTS embedding (
person_id INTEGER NOT NULL,
emb BLOB NOT NULL,
FOREIGN KEY(person_id) REFERENCES person(id)
);
CREATE INDEX IF NOT EXISTS idx_embedding_person_id ON embedding(person_id);
写入规则 • person.name = 文件夹名 • embedding.emb = 单张样本 embedding 的 float32 原始字节(BLOB) • 长度必须为 expected_dim * 4(512→2048 bytes) • 每个 person 可对应多行 embedding
──────────────────────────────────────────
- 质量控制与异常处理
过滤规则(可配置) • min_face_size:bbox 宽或高小于阈值则丢弃 • 检测不到脸:记录为失败样本 • 多脸:默认选最大脸;可配置 --pick_face(largest/first/highest_score)
容错策略(可配置) • 单人所有图片都失败:该 person 不写入库,并在报告中列出 • --fail_on_empty true:若最终 person 数为 0 或 embedding 数为 0,则脚本返回非 0 退出码
──────────────────────────────────────────
- 输出报告(必须)
脚本运行结束输出: • 总人数、成功入库人数、总图片数、成功样本数、失败样本数 • 每人使用的样本数量 • 失败原因统计(no_face / small_face / align_fail / infer_fail 等) • 数据库自检: • COUNT(person)、COUNT(embedding) • 随机抽查 N 条 length(emb)==2048
(可选增强)打印每人 centroid 的 L2 norm(应接近 1.0)
──────────────────────────────────────────
- 依赖与运行环境 • Windows 10/11 • Python 3.9+ • 依赖包: • numpy • opencv-python • onnxruntime • sqlite3:使用 Python 标准库
──────────────────────────────────────────
- 验收标准(可直接验)
- 生成的 face_gallery.db 能被你当前 ai_face_recog 加载,设备日志出现:gallery loaded: n=<入库人数> dim=512
- SQLite 校验: • SELECT COUNT() FROM person; == 入库人数 • SELECT COUNT() FROM embedding; >= 入库人数 • SELECT length(emb) FROM embedding LIMIT 5; 全为 2048
- 实测:对至少 3 人,每人 3 张注册图 + 1 条现场图,识别能输出对应姓名(阈值用现有配置不强制修改)
──────────────────────────────────────────
- 与设备端配置的对接要求(提醒开发) • gallery.backend="sqlite" • gallery.path 指向拷贝后的 face_gallery.db • gallery.expected_dim=512 • 设备端检索需要按 person 聚合,避免同人多条 embedding 互相占据 top2