🧪 新教程持續更新中 · 由機械臂到傳感器,跟隨教程從零搭建
跳到主要內容

第 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 章:語音對話(XiaoZhi AI)