AddFaceTo3588/Readme.md
2026-01-08 13:46:50 +08:00

199 lines
7.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

PRD全离线生成 `face_gallery.db`(每人 1 条 centroidWindows+Python+ONNX
1. 背景与目标
• 在 Windows 电脑上离线处理“注册照片”,为每个人生成 1 条 512D
人脸特征centroid写入 SQLite 数据库 face_gallery.db。
• RK3588 运行时 ai_face_recog 以 gallery.backend=sqlite
读取该库,实现识别(无需改线上阈值/配置逻辑)。
──────────────────────────────────────────
2. 范围In/Out
In Scope
• 数据集扫描(按人目录)
• 人脸检测(含 5 点关键点)+ 对齐到 112×112
• ArcFace/MobileFaceNet ONNX 推理生成 512D embedding
• 每人多图聚合为 centroidL2 normalize 后平均,再 L2 normalize
• 生成 SQLiteperson、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.nameUTF-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. 特征生成与聚合(每人 1 条 centroid
对每张有效图片:
1. 检测 → 选择人脸(默认:最大脸)
2. 5 点对齐 → 112×112 RGB
3. 预处理 + ONNX 推理 → 512D embedding
4. L2 normalize单样本
对每个人:
• 取最多 max_imgs_per_person 张有效样本 embedding不足也可
• centroid 计算:
• centroid = mean(emb_i)(对已归一化 emb 做均值)
• centroid = L2_normalize(centroid)
• 只写入 1 条 embeddingcentroid
──────────────────────────────────────────
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 = centroid 向量的 float32 原始字节BLOB
• 长度必须为 expected_dim * 4512→2048 bytes
• 每个 person 仅 1 行 embedding
──────────────────────────────────────────
8. 质量控制与异常处理
过滤规则(可配置)
• min_face_sizebbox 宽或高小于阈值则丢弃
• 检测不到脸:记录为失败样本
• 多脸:默认选最大脸;可配置 --pick_facelargest/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
• threshold.margin 保持现有值即可(因为每人只有 1 条 centroid不会出现“同人占
top2 导致 margin 过小”的问题)