🧪 新教程持续更新中 · 从机械臂到传感器,跟着教程从零搭建
跳到主要内容

第 8 章:人脸识别

淘宝店铺

本章目标:注册人脸特征,让 NanoCam 认出“你是谁”,搭建完整门禁方案。

原理

人脸识别 = 人脸检测(MSR01+MNP01 双阶段流水线)+ 特征提取(FaceRecognition112V1S8 MFN 神经网络)+ 余弦相似度比对

Plain
摄像头 RGB565 帧
  → MSR01 粗检测(320×240, 0.3F 阈值)
  → MNP01 精检测(基于粗检候选框, 0.4F 阈值)
  → 10 个面部关键点提取(双眼/鼻尖/嘴角)
  → 关键点对齐 → 裁剪 112×112 人脸
  → MFN 卷积网络 → 512 维特征向量
  → L2 归一化
  → 与 Flash 中所有已注册 ID 的向量逐一计算余弦距离
  → 最大余弦相似度 > 阈值(0.55) → 匹配成功 → 输出 ID
  → 所有相似度 < 阈值 → 陌生人 → 输出 "who?"

性能优化

MFN 特征提取和全库比对运算量较大,每帧都跑会导致画面卡顿。当前实现采用跳帧策略:人脸检测每帧运行(廉价),MFN 识别每 10 帧运行一次(昂贵),标签使用上一次识别结果持续叠加显示。这样画面保持流畅,ID 标签不闪烁。

人脸特征存储

已注册的人脸特征(id + 512维 embedding)持久化存储在 Flash 的 fr 分区(96 KB,最多 47 个人脸 ID)。掉电不丢失。

硬件准备

  • NanoCam 核心板 + 底板

  • USB-C 数据线(接电脑供电+串口)

  • 串口助手(波特率 115200)

步骤

8.1 进入人脸识别模式

Plain
ai_mode:4

设备自动重启进入 FaceID 模式,WS2812 RGB LED (GPIO18 DIN, VDD50 供电) 显示紫色。重启后串口应看到:

Plain
I (5526) MFN: fr partition size: 98304 bytes, maxminum 47 IDs can be stored
I (5526) MFN: No face ID in flash

No face ID in flash 表示还没有注册过任何人脸,正常。

8.2 注册人脸

让人脸正对摄像头(距离 30-50cm,光照均匀),确保画面中只有一张人脸。在串口发送:

Plain
face_eril

设备检测到人脸后自动提取特征并注册到 Flash:

Plain
I (xxxx) ENROLL: ID 1 is enrolled

画面叠加蓝色文字 Enroll: ID 1,持续约 0.5 秒后消失。

注意:命令是 face_eril(enroll 缩写),不是 face_enroll。如果看到 fail: unknown command,检查拼写。

8.3 辨认识别人脸

注册完成后,发送识别命令:

Plain
face_rz

系统进入持续识别模式。当前人脸与 Flash 中所有已注册 ID 比对:

  • 匹配成功:串口输出 Similarity: 0.85, Match ID: 1,画面持续叠加绿色 ID: 1

  • 陌生人:串口输出 Similarity: 0.32, Match ID: 0,画面持续叠加红色 who?

标签持续显示不会消失。要退出识别模式,发送 face_detect 返回纯检测模式。

8.4 删除人脸

Plain
face_del

删除最后注册的人脸 ID,串口返回 N IDs left,画面短暂显示剩余 ID 数量。Flash 中的特征同步删除。

8.5 退出识别模式

Plain
face_detect

返回纯人脸检测模式(只画框+关键点,不识别),ID 标签清除。

关于 DETECT 模式: 在 ESP32-S3 上,纯人脸检测模式的串口坐标打印被禁用(#if !CONFIG_IDF_TARGET_ESP32S3),这是为了避免串口被检测日志刷屏。进入识别模式(face_rz)后才会输出 detection_result 坐标日志。

完整命令速查

命令功能标签行为是否持续
face_eril注册当前检测到的人脸蓝色 "Enroll: ID N"闪现 0.5s
face_rz进入持续识别模式绿色 "ID: N" / 红色 "who?"✅ 持续
face_del删除最后注册的 ID红色 "N IDs left"闪现 0.5s
face_detect退出识别,返回纯检测清除所有标签

完整指令见串口协议手册

操作流程示例

Plain
ai_mode:4                          # 进入人脸识别模式
[设备重启,LED 紫色]

face_eril                          # 注册第一个人脸(张三)
→ ID 1 is enrolled

face_eril                          # 注册第二个人脸(李四)
→ ID 2 is enrolled

face_rz                            # 开始持续识别
→ 张三站摄像头前: 画面持续显示 "ID: 1"
→ 李四站摄像头前: 画面持续显示 "ID: 2"
→ 陌生人站摄像头前: 画面持续显示 "who?"

face_detect                        # 退出识别模式
→ 标签消失,只画检测框

face_del                           # 删除李四 (ID 2)
→ 1 IDs left

face_rz                            # 再次识别
→ 张三站摄像头前: "ID: 1"
→ 李四站摄像头前: "who?" (已被删除)

人脸识别模式内存占用较大(MFN 模型 + 人脸检测双模型),Type-C 串口(UART0)正常工作。如遇串口无响应,先检查波特率是否为 115200。

代码

核心识别逻辑

components/modules/ai/who_human_face_recognition.cpp — 跳帧识别策略:

C++
case RECOGNIZE:
{
    // 跳帧:每 10 次检测执行 1 次 MFN 识别
    static int recog_skip = 0;
    if (recog_skip <= 0) {
        recognize_result = recognizer->recognize(
            (uint16_t *)frame->buf,
            {(int)frame->height, (int)frame->width, 3},
            detect_results.front().keypoint);
        recog_skip = 10;
    }
    recog_skip--;
    frame_show_state = SHOW_STATE_RECOGNIZE;
    break;
}

故障排除

症状可能原因解决
No face ID in flash正常,还没注册过发送 face_eril 注册
识别结果始终 who?光照不足/角度偏/相似度低于阈值重新注册,正对摄像头,光度均匀
注册时没反应画面中人脸 ≠ 1 张确保只有一张脸,距离 30-50cm
识别时画面卡顿正常,MFN 推理需要时间已通过跳帧优化,每 10 帧跑一次
标签闪烁已修复,标签持续显示不消失
fail: unknown command命令拼写错误检查命令:face_eril 不是 face_enroll

效果

注册人脸→持续识别显示 ID→I2C/串口输出结果→控制继电器/舵机,完整门禁方案。

下一章:第 9 章:语音对话