196 lines
7.2 KiB
Markdown
196 lines
7.2 KiB
Markdown
PRD:全离线生成 `face_gallery.db`(每人多条 embedding,Windows+Python+ONNX)
|
||
|
||
1. 背景与目标
|
||
• 在 Windows 电脑上离线处理“注册照片”,为每个人生成多条 512D
|
||
人脸特征(每张有效照片 1 条 embedding),写入 SQLite 数据库 face_gallery.db。
|
||
• RK3588 运行时 ai_face_recog 以 gallery.backend=sqlite
|
||
读取该库,实现识别(无需改线上阈值/配置逻辑)。
|
||
|
||
──────────────────────────────────────────
|
||
|
||
2. 范围(In/Out)
|
||
|
||
In Scope
|
||
• 数据集扫描(按人目录)
|
||
• 人脸检测(含 5 点关键点)+ 对齐到 112×112
|
||
• ArcFace/MobileFaceNet ONNX 推理生成 512D embedding
|
||
• 生成 SQLite:person、embedding 两表
|
||
• 生成构建报告(统计、异常、可选相似度抽检)
|
||
|
||
Out of Scope
|
||
• 在线注册/写库接口
|
||
• RKNN 推理/设备端工具
|
||
• 人脸库增量热更新(只生成 db 文件)
|
||
|
||
──────────────────────────────────────────
|
||
|
||
3. 用户与使用方式
|
||
|
||
目标用户
|
||
• 开发/测试人员(在 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
|
||
|
||
──────────────────────────────────────────
|
||
|
||
4. 输入数据规范
|
||
|
||
目录结构
|
||
|
||
dataset/
|
||
张三/
|
||
001.jpg
|
||
002.jpg
|
||
李四/
|
||
a.png
|
||
b.png
|
||
|
||
• 文件夹名作为 person.name(UTF-8)
|
||
• 每人建议 3~10 张图(允许混合:标准大头照 + 摄像头位照片)
|
||
|
||
图片支持格式
|
||
• jpg/jpeg/png/bmp(由 OpenCV 读取)
|
||
|
||
──────────────────────────────────────────
|
||
|
||
5. 模型与前处理规范(必须严格一致)
|
||
|
||
识别模型(已确定)
|
||
• 输入: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,双线性插值
|
||
|
||
──────────────────────────────────────────
|
||
|
||
6. 特征生成与入库(每人多条 embedding)
|
||
|
||
对每张有效图片:
|
||
1. 检测 → 选择人脸(默认:最大脸)
|
||
2. 5 点对齐 → 112×112 RGB
|
||
3. 预处理 + ONNX 推理 → 512D embedding
|
||
4. L2 normalize(单样本)
|
||
|
||
对每个人:
|
||
• 取最多 max_imgs_per_person 张有效样本 embedding(不足也可)
|
||
• 每张有效样本保留 1 条 embedding
|
||
• 同一 person 可写入多条 embedding
|
||
|
||
──────────────────────────────────────────
|
||
|
||
7. 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
|
||
|
||
──────────────────────────────────────────
|
||
|
||
8. 质量控制与异常处理
|
||
|
||
过滤规则(可配置)
|
||
• min_face_size:bbox 宽或高小于阈值则丢弃
|
||
• 检测不到脸:记录为失败样本
|
||
• 多脸:默认选最大脸;可配置 --pick_face(largest/first/highest_score)
|
||
|
||
容错策略(可配置)
|
||
• 单人所有图片都失败:该 person 不写入库,并在报告中列出
|
||
• --fail_on_empty true:若最终 person 数为 0 或 embedding 数为 0,则脚本返回非
|
||
0 退出码
|
||
|
||
──────────────────────────────────────────
|
||
|
||
9. 输出报告(必须)
|
||
|
||
脚本运行结束输出:
|
||
• 总人数、成功入库人数、总图片数、成功样本数、失败样本数
|
||
• 每人使用的样本数量
|
||
• 失败原因统计(no_face / small_face / align_fail / infer_fail 等)
|
||
• 数据库自检:
|
||
• COUNT(person)、COUNT(embedding)
|
||
• 随机抽查 N 条 length(emb)==2048
|
||
|
||
(可选增强)打印每人 centroid 的 L2 norm(应接近 1.0)
|
||
|
||
──────────────────────────────────────────
|
||
|
||
10. 依赖与运行环境
|
||
• Windows 10/11
|
||
• Python 3.9+
|
||
• 依赖包:
|
||
• numpy
|
||
• opencv-python
|
||
• onnxruntime
|
||
• sqlite3:使用 Python 标准库
|
||
|
||
──────────────────────────────────────────
|
||
|
||
11. 验收标准(可直接验)
|
||
1. 生成的 face_gallery.db 能被你当前 ai_face_recog 加载,设备日志出现:gallery
|
||
loaded: n=<入库人数> dim=512
|
||
2. SQLite 校验:
|
||
• SELECT COUNT(*) FROM person; == 入库人数
|
||
• SELECT COUNT(*) FROM embedding; >= 入库人数
|
||
• SELECT length(emb) FROM embedding LIMIT 5; 全为 2048
|
||
3. 实测:对至少 3 人,每人 3 张注册图 + 1
|
||
条现场图,识别能输出对应姓名(阈值用现有配置不强制修改)
|
||
|
||
──────────────────────────────────────────
|
||
|
||
12. 与设备端配置的对接要求(提醒开发)
|
||
• gallery.backend="sqlite"
|
||
• gallery.path 指向拷贝后的 face_gallery.db
|
||
• gallery.expected_dim=512
|
||
• 设备端检索需要按 person 聚合,避免同人多条 embedding 互相占据 top2
|