18浏览
查看: 18|回复: 8

[K10教程] 【花雕动手做】行空板 K10 实验之人脸录入和识别氛围灯

[复制链接]
【花雕动手做】行空板 K10 实验之人脸录入和识别氛围灯图1

行空板K10是一款专为快速体验物联网和学习人工智能而设计的开发学习板,100%采用国产芯片,知识产权自主可控,符合信息科技课程中编程学习、物联网及人工智能等教学需求。该板集成2.8寸LCD彩屏、WiFi蓝牙、摄像头、麦克风、扬声器、RGB指示灯、多种传感器及丰富的扩展接口。凭借高度集成的板载资源,教学过程中无需额外连接其他设备,便可轻松实现传感器控制、物联网应用以及人脸识别、语音识别、语音合成等AI人工智能项目。

主要特点
集成摄像头&内置算法,可进行离线图像检测
集成麦克风&内置算法,可进行离线语音识别
集成扬声器&内置算法,可进行离线语音合成
2.8寸彩色屏幕,数据展示更清晰
集成度高,利于教学
接口丰富,兼容软件多,扩展性好


【花雕动手做】行空板 K10 实验之人脸录入和识别氛围灯图2

驴友花雕  高级技神
 楼主|

发表于 6 小时前

【花雕动手做】行空板 K10 实验之人脸录入识别氛围灯

主打:人工智能模块

【花雕动手做】行空板 K10 实验之人脸录入和识别氛围灯图1

人脸检测相关说明

【花雕动手做】行空板 K10 实验之人脸录入和识别氛围灯图2

【花雕动手做】行空板 K10 实验之人脸录入和识别氛围灯图3


回复

使用道具 举报

驴友花雕  高级技神
 楼主|

发表于 6 小时前

【花雕动手做】行空板 K10 实验之人脸录入识别氛围灯

辅助:屏幕显示相关积木

【花雕动手做】行空板 K10 实验之人脸录入和识别氛围灯图1

LED控制模块

【花雕动手做】行空板 K10 实验之人脸录入和识别氛围灯图2


回复

使用道具 举报

驴友花雕  高级技神
 楼主|

发表于 6 小时前

【花雕动手做】行空板 K10 实验之人脸录入识别氛围灯

【花雕动手做】行空板 K10 实验之人脸录入和识别氛围灯图1

知识点:行空板 K10 人脸检测

一、什么是行空板人脸检测
行空板 K10 内置 ESP32-S3 AI 硬件加速 NPU,搭配板载摄像头,依托unihiker_k10.h内置 AI 视觉库,本地离线完****脸检测,不需要联网、不需要云端运算,设备单独就能识别画面里是否存在人脸、输出人脸坐标。
区别于人脸识别:人脸检测只找 “人脸区域”,不区分是谁;人脸识别会比对人脸特征区分不同人。
核心硬件基础
主控:ESP32-S3 内置 AI 加速器,专门处理图像识别算法;
外设:板载前置摄像头,实时采集画面;
输出载体:K10 彩色显示屏、RGB 彩灯、扬声器、按键;
存储:TF 卡可保存人脸截图、训练模型。

二、核心基础功能
1、离线实时检测
摄像头持续刷新画面,AI 实时框选画面内所有人脸,输出人脸左上角、右下角坐标,能获取人脸宽度、高度。
2、画面可视化标记
画布直接绘制红色矩形框,把识别到的人脸圈出来,直观展示检测结果。
3、状态联动反馈
检测到人脸 / 无人脸可联动硬件:
RGB 彩灯:有人脸亮绿灯、无人脸亮红灯;
音频:检测到人脸播放提示音;
屏幕文字:实时打印「检测到人脸」「未识别人脸」;
4、配套拓展功能
人脸抓拍:检测到人脸自动保存截图到 TF 卡;
延时计数:持续 3 秒检测到人脸再触发动作,过滤瞬间路过干扰;
多人脸识别:支持同时识别画面内多张人脸。

三、底层运行逻辑
摄像头采集图像数据流;
NPU 硬件加速运行轻量化人脸检测模型;
算法输出人脸矩形坐标数据;
程序读取坐标,在屏幕画布绘制方框;
循环持续采集 + 推理,实现实时动态追踪人脸。

【花雕动手做】行空板 K10 实验之人脸录入和识别氛围灯图2

四、两种编程实现方式(Mind+)

方式 1:图形化积木(新手首选,无编译报错)
扩展库加载「AI 视觉 - 人脸检测」,积木逻辑:
初始化摄像头、AI 人脸检测;
循环采集画面;
判断是否检测到人脸;
分支:有人脸→画框、亮绿灯、播放提示音;无人脸→清框、红灯;
优势:不用处理库冲突、无多重定义报错,课堂教学首选。

方式 2:C/C++ 代码(进阶自主开发)
依托unihiker_k10.h内置 AI 接口,核心流程:
初始化摄像头 AI 模块 k10.initAI();
循环调用人脸检测函数获取人脸数组;
判断人脸数量大于 0,遍历所有人脸坐标;
画布绘制矩形框标记人脸;
联动灯光、音频、存储。

五、典型落地应用场景
1、人脸门禁提醒装置
检测到人脸自动亮绿灯、播放欢迎音效,无人时红灯待机;可拓展继电器控制门锁。
2、课堂人脸考勤记录仪
持续检测画面内人脸,检测到人脸自动抓拍保存照片到 TF 卡,记录到场人员画面。
3、桌面智能护眼监测
检测人脸距离屏幕过近时,屏幕弹出提示文字、蜂鸣器报警,提醒保持观看距离。
4、智能人体感应灯光
识别到人脸自动开启 RGB 氛围灯,人脸离开几秒后自动关灯。
5、互动趣味装置
对准屏幕人脸触发特效、播放音乐,人脸消失特效关闭。

六、使用优缺点
优势
完全离线本地运行,不用 WiFi、不用物联网平台,断网也能用;
ESP32-S3 硬件 AI 加速,画面流畅不卡顿,不占用 CPU;
配套 K10 屏幕、灯光、音频、TF 卡全套硬件,拓展简单;
Mind + 图形化 + 代码双模式,零基础、进阶学员都适配;
接口高度封装,不用学习复杂 AI 算法,直接调用现成函数。
局限
仅支持人脸检测,原生不自带人脸比对(区分不同人),如需人脸识别需要额外训练模型;
光线过暗、侧脸、遮挡口罩会降低识别准确率;
高帧率连续抓拍会小幅占用内存,多 AI 任务(人脸 + 物体识别)同时运行会卡顿;
抓拍图片默认覆盖存储,如需多图存档需要自定义命名逻辑。

七、实操关键注意事项
光线充足:暗光环境识别率大幅下降,建议室内正常灯光下实验;
人脸正对摄像头:侧脸、低头、口罩遮挡容易漏检;
硬件初始化顺序:必须先k10.begin()、初始化摄像头,再开启 AI 人脸检测;
不要叠加多余图形库(TFT_eSPI),避免多重定义编译报错;
循环内减少delay()阻塞延时,否则人脸画面卡顿、检测失效;
抓拍保存照片需提前执行k10.initSDFile()初始化 TF 卡。


【花雕动手做】行空板 K10 实验之人脸录入和识别氛围灯图3
回复

使用道具 举报

驴友花雕  高级技神
 楼主|

发表于 6 小时前

【花雕动手做】行空板 K10 实验之人脸录入识别氛围灯

人脸检测的几张案例图片

【花雕动手做】行空板 K10 实验之人脸录入和识别氛围灯图3

【花雕动手做】行空板 K10 实验之人脸录入和识别氛围灯图1

【花雕动手做】行空板 K10 实验之人脸录入和识别氛围灯图4

【花雕动手做】行空板 K10 实验之人脸录入和识别氛围灯图2
回复

使用道具 举报

驴友花雕  高级技神
 楼主|

发表于 6 小时前

【花雕动手做】行空板 K10 实验之人脸录入识别氛围灯


【花雕动手做】行空板 K10 系列实验之人脸检测的人脸录入识别氛围灯
实验开源代码


  1. // 引入行空板K10综合硬件驱动库:封装屏幕、按键、RGB彩灯、摄像头、画布等全部外设底层接口
  2. #include "unihiker_k10.h"
  3. // 引入ESP32-S3离线AI视觉库:提供人脸采集录入、人脸特征比对识别、AI模式切换功能
  4. #include "AIRecognition.h"
  5. // 提前声明A、B物理按键的中断回调函数,setup绑定按键时编译器可提前识别函数
  6. void onButtonBPressed();
  7. void onButtonAPressed();
  8. // ===================== 硬件对象实例化 =====================
  9. // 行空板K10主控全局对象,所有屏幕、灯光、摄像头操作统一通过该对象调用
  10. UNIHIKER_K10  k10;
  11. // 屏幕旋转参数:2=正向正常显示,可修改0/1/2/3切换画面横竖翻转
  12. uint8_t       screen_dir=2;
  13. // AI人脸识别专用对象,负责人脸模型初始化、下发录入/识别指令、读取人脸ID
  14. AIRecognition ai;
  15. // 音频播放对象,本案例未使用音乐功能,保留用于兼容原有工程结构
  16. Music         music;
  17. // ===================== 全局状态控制变量 =====================
  18. bool startRecogFlag = false;   // 人脸识别总开关:false=待机不检测人脸,true=开启实时人脸比对氛围灯
  19. float nowFaceID = 0;           // 存储当前识别匹配成功的人脸编号,第一张录入人脸ID=1,第二张ID=2
  20. unsigned long faceLostTimer = 0;// 人脸丢失时间戳:记录最后一次识别到人脸的系统毫秒时间,用于3秒缓冲计时
  21. const unsigned long FACE_KEEP_DELAY = 3000; // 人脸消失缓冲阈值3000ms=3秒,短暂遮挡不立刻关灯退出识别
  22. unsigned long breathTimer = 0; // RGB呼吸灯光刷新计时戳,控制渐变刷新间隔,无阻塞不卡顿画面
  23. int breathVal = 30;             // 灯光初始基础亮度30,避免识别到人脸瞬间亮度为0看不到灯光
  24. bool breathDir = true;         // 灯光渐变方向标记:true=亮度递增变亮,false=亮度递减变暗
  25. /**
  26. * @brief 统一绘制待机界面封装函数
  27. * @desc 开机初始化、人脸超时退出识别、人脸录入完成后统一调用,复用绘图代码简化程序
  28. * 功能:清空画布、打印操作提示文字、关闭全部RGB氛围灯
  29. */
  30. void showStandbyUI()
  31. {
  32.   // 清空画布上所有文字、画面残留
  33.   k10.canvas->canvasClear();
  34.   // 红色24号中英文字体标题,坐标X0 Y0,透明度50,开启自动换行
  35.   k10.canvas->canvasText("        人脸氛围灯", 0, 0, 0xFF0000, k10.canvas->eCNAndENFont24, 50, true);
  36.   // 白色操作指引文字,坐标X0 Y35,提示按键功能
  37.   k10.canvas->canvasText("A键录人脸  B键氛围灯", 0, 35, 0xFFFFFF, k10.canvas->eCNAndENFont24, 50, true);
  38.   // 将画布缓存内容刷新到实体LCD屏幕显示
  39.   k10.canvas->updateCanvas();
  40.   // -1代表控制主板全部RGB灯珠,0x000000黑色,关闭所有彩灯
  41.   k10.rgb->write(-1, 0x000000);
  42. }
  43. /**
  44. * @brief 上电初始化函数,仅开机/复位时运行1次
  45. * 执行流程:主板硬件初始化→屏幕→AI加速器→摄像头→绑定按键→切换人脸AI模式→加载待机界面
  46. */
  47. void setup() {
  48.         k10.begin();                // 初始化行空板底层总线、IO、供电等全部硬件外设
  49.         k10.initScreen(screen_dir); // 根据screen_dir参数初始化显示屏驱动
  50.         ai.initAi();                // 开启ESP32-S3内置NPU AI硬件加速器,加载AI推理底层资源
  51.         k10.initBgCamerImage();     // 初始化摄像头后台画面渲染功能,支持摄像头取景投屏到屏幕
  52.         k10.setBgCamerImage(false); // 初始化阶段临时关闭摄像头画面,避免画面干扰初始化流程
  53.         k10.creatCanvas();          // 创建屏幕绘图缓存画布,绘图先存入缓存再统一刷新,消除屏幕闪烁
  54.         ai.switchAiMode(ai.NoMode); // 临时切换AI为无识别模式,清空上一轮残留AI模型,防止模式冲突
  55.         // 给A、B物理按键绑定按下中断回调函数,按键触发不受delay延时阻塞
  56.         k10.buttonB->setPressedCallback(onButtonBPressed);
  57.         k10.buttonA->setPressedCallback(onButtonAPressed);
  58.         k10.setBgCamerImage(true);  // 开启摄像头实时画面投屏,屏幕持续显示镜头取景画面
  59.         ai.switchAiMode(ai.Face);   // 切换AI工作模式为人脸识别模式,同时支持人脸录入、人脸特征比对
  60.         // RGB亮度修复:K10板载RGB亮度有效范围0~10,设置适中亮度5,解决之前亮度255导致灯光完全不亮问题
  61.         k10.rgb->brightness(5);
  62.         // 硬件初始化完成,直接加载安静待机界面,无识别、无灯光
  63.         showStandbyUI();
  64. }
  65. /**
  66. * @brief 主循环函数,上电后无限循环执行,程序核心业务逻辑
  67. * 逻辑分层:待机拦截 → 识别到合法人脸(控制对应ID呼吸氛围灯) → 人脸丢失分两种场景(短暂遮挡/超时离开)
  68. */
  69. void loop() {
  70.         // 判断识别总开关关闭:直接终止本次循环,保持待机界面,不执行任何人脸检测、灯光运算
  71.         if (!startRecogFlag) {
  72.                 return;
  73.         }
  74.         bool hasFace = ai.isRecognized(); // 判断AI是否匹配到本地已录入的人脸:true=识别到家人,false=无人脸/陌生人
  75.         unsigned long nowTime = millis(); // 获取系统开机累计运行毫秒数,用于无阻塞计时,不卡顿画面
  76.         // ========== 场景1:摄像头识别到已录入的合法家人人脸 ==========
  77.         if (hasFace) {
  78.                 faceLostTimer = nowTime; // 持续刷新人脸计时戳,只要人脸在镜头内就重置3秒超时倒计时
  79.                 nowFaceID = ai.getRecognitionID(); // 读取当前匹配成功的人脸专属编号ID
  80.                 k10.canvas->canvasClear(); // 清空上一轮屏幕文字
  81.                 k10.canvas->canvasText("检测人脸 ID:" + String(nowFaceID), 0, 0, 0xFFFFFF, k10.canvas->eCNAndENFont24, 50, true);
  82.                 // 灯光渐变刷新控制:间隔100ms更新一次亮度,肉眼清晰观察到柔和呼吸效果
  83.                 if (nowTime - breathTimer > 100) {
  84.                         breathTimer = nowTime; // 刷新渐变计时戳
  85.                         // 亮度自动增减,亮度区间锁定30~200,最低30保证可见、最高200防止灯光过曝刺眼
  86.                         if (breathDir) {
  87.                                 breathVal += 8;
  88.                                 if (breathVal >= 200) breathDir = false; // 亮度到达上限,切换为变暗方向
  89.                         } else {
  90.                                 breathVal -= 8;
  91.                                 if (breathVal <= 30) breathDir = true;  // 亮度到达下限,切换为变亮方向
  92.                         }
  93.                         // 匹配ID=1:老爷专属绿色呼吸氛围灯
  94.                         if (nowFaceID == 1.0) {
  95.                                 k10.canvas->canvasText("ID1 老爷 · 绿光氛围", 0, 40, 0x00FF00, k10.canvas->eCNAndENFont24, 50, true);
  96.                                 uint32_t greenColor = breathVal << 8; // 色彩计算:仅绿色通道随breathVal变化,红、蓝通道为0
  97.                                 k10.rgb->write(-1, greenColor);       // 输出颜色到全部RGB灯珠
  98.                         }
  99.                         // 匹配ID=2:小姐专属蓝色呼吸氛围灯
  100.                         else if (nowFaceID == 2.0) {
  101.                                 k10.canvas->canvasText("ID2 小姐 · 蓝光氛围", 0, 40, 0x0000FF, k10.canvas->eCNAndENFont24, 50, true);
  102.                                 uint32_t blueColor = breathVal;       // 色彩计算:仅蓝色通道随breathVal变化,红、绿通道为0
  103.                                 k10.rgb->write(-1, blueColor);        // 输出颜色到全部RGB灯珠
  104.                         }
  105.                 }
  106.                 k10.canvas->updateCanvas(); // 将当前文字刷新到屏幕
  107.         }
  108.         // ========== 场景2:摄像头未识别到录入人脸(人脸遮挡、转头、完全离开、陌生人) ==========
  109.         else {
  110.                 // 子场景1:人脸消失时长不足3秒,属于短暂遮挡,不切换界面、不关闭灯光,直接跳出本次循环
  111.                 if (nowTime - faceLostTimer < FACE_KEEP_DELAY) {
  112.                         return;
  113.                 }
  114.                 // 子场景2:人脸完全离开镜头超过3秒,自动关闭识别总开关,切回待机界面、熄灭全部彩灯
  115.                 startRecogFlag = false;
  116.                 showStandbyUI();
  117.         }
  118. }
  119. /**
  120. * @brief A按键按下回调函数:执行人脸录入学习功能
  121. * 执行流程:显示采集提示 → 下发人脸录入指令 → 阻塞3秒采集人脸特征 → 提示录入完成 → 1.2秒后自动切回待机界面
  122. */
  123. void onButtonAPressed() {
  124.         k10.canvas->canvasClear();
  125.         // 蓝色提示文字,提醒用户正对摄像头完****脸采集
  126.         k10.canvas->canvasText("采集人脸中,请正对镜头", 0, 0, 0x0066FF, k10.canvas->eCNAndENFont24, 50, true);
  127.         k10.canvas->updateCanvas();
  128.         ai.sendFaceCmd(ENROLL); // 下发AI录入指令:采集当前人脸特征,本地存储并自动分配ID(第一张=1,第二张=2)
  129.         delay(3000); // 阻塞3秒,给AI充足时间完****脸特征采集,避免录入失败
  130.         k10.canvas->canvasClear();
  131.         // 绿色文字提示录入成功
  132.         k10.canvas->canvasText("人脸录入完成!", 0, 0, 0x00FF00, k10.canvas->eCNAndENFont24, 50, true);
  133.         k10.canvas->canvasText("按B键开启人脸氛围灯",0,35,0xFFFFFF,k10.canvas->eCNAndENFont24,50,true);
  134.         k10.canvas->updateCanvas();
  135.         delay(1200); // 停留1.2秒,让用户看清录入成功提示
  136.         showStandbyUI(); // 人脸录入结束,自动返回安静待机界面
  137. }
  138. /**
  139. * @brief B按键按下回调函数:开启人脸识别氛围灯工作模式
  140. * 执行流程:打开识别总开关 → 重置人脸/灯光计时 → 下发AI识别比对指令 → 弹出识别启动提示界面
  141. */
  142. void onButtonBPressed() {
  143.         startRecogFlag = true;          // 打开识别总开关,loop循环开始执行人脸检测、灯光控制逻辑
  144.         faceLostTimer = millis();       // 初始化人脸丢失计时,按下B瞬间开始计算3秒缓冲倒计时
  145.         breathTimer = millis();         // 重置灯光渐变计时,重新开始呼吸效果
  146.         breathVal = 30;                 // 重置灯光基础亮度,保证识别到人脸立刻有可见灯光
  147.         breathDir = true;               // 重置灯光渐变方向,从变亮开始呼吸
  148.         ai.sendFaceCmd(RECOGNIZE);      // 下发AI识别比对指令,持续实时匹配镜头人脸与本地人脸库
  149.         k10.canvas->canvasClear();
  150.         k10.canvas->canvasText("人脸氛围灯已启动", 0, 0, 0x0066FF, k10.canvas->eCNAndENFont24, 50, true);
  151.         k10.canvas->canvasText("正在识别人脸",0,35,0xFFFFFF,k10.canvas->eCNAndENFont24,50,true);
  152.         k10.canvas->updateCanvas();
  153.         delay(1000); // 启动提示界面停留1秒,之后进入loop实时人脸检测与灯光控制
  154. }
复制代码


回复

使用道具 举报

驴友花雕  高级技神
 楼主|

发表于 6 小时前

【花雕动手做】行空板 K10 实验之人脸录入识别氛围灯

人脸氛围灯代码解读

一、头部库文件与函数声明

  1. #include "unihiker_k10.h"
  2. #include "AIRecognition.h"
复制代码

unihiker_k10.h:行空板 K10 全套硬件驱动,包含屏幕、按键、RGB 彩灯、摄像头、画布、喇叭等外设接口;
AIRecognition.h:ESP32-S3 板载 AI 库,专门做人脸录入、人脸比对识别,依托内置 NPU 离线运行,不需要网络。

  1. void onButtonBPressed();
  2. void onButtonAPressed();
复制代码

前置声明两个按键回调函数,setup里绑定按键时编译器能提前识别函数,不会报未定义错误。

二、全局硬件对象

  1. UNIHIKER_K10  k10;
  2. uint8_t       screen_dir=2;
  3. AIRecognition ai;
  4. Music         music;
复制代码

k10:主板总对象,所有屏幕、灯光、按键操作都通过它调用;
screen_dir=2:屏幕正向显示,0/1/2/3 可切换画面翻转;
ai:人脸识别专用对象,负责人脸采集、比对、读取人脸 ID;
music:音频对象,本案例未使用,保留兼容原有工程。

三、全局控制变量(程序核心状态开关)

  1. bool startRecogFlag = false;   // 识别总开关
  2. float nowFaceID = 0;           // 当前识别到的人脸编号
  3. unsigned long faceLostTimer = 0;// 记录最后一次识别到人脸的时间戳
  4. const unsigned long FACE_KEEP_DELAY = 3000; // 人脸消失3秒缓冲时长
  5. unsigned long breathTimer = 0; // 灯光呼吸渐变刷新计时
  6. int breathVal = 30;             // 灯光基础亮度(最低可见亮度,避免刚识别就黑屏)
  7. bool breathDir = true;         // 灯光渐变方向:true变亮,false变暗
复制代码

startRecogFlag:程序分为待机和识别工作两种模式,false = 待机不检测人脸,true = 开启识别 + 氛围灯;
faceLostTimer + FACE_KEEP_DELAY:实现 3 秒缓冲,人脸短暂遮挡不会立刻关灯;
breathTimer / breathVal / breathDir:控制 RGB 呼吸渐变流水灯,无阻塞计时,不卡顿画面。

四、封装函数:待机界面 showStandbyUI ()

  1. void showStandbyUI()
  2. {
  3.   k10.canvas->canvasClear();
  4.   k10.canvas->canvasText("        人脸氛围灯", 0, 0, 0xFF0000, k10.canvas->eCNAndENFont24, 50, true);
  5.   k10.canvas->canvasText("A键录人脸  B键氛围灯", 0, 35, 0xFFFFFF, k10.canvas->eCNAndENFont24, 50, true);
  6.   k10.canvas->updateCanvas();
  7.   k10.rgb->write(-1, 0x000000);
  8. }
复制代码

功能作用
统一管理开机、人脸超时、录入完成后的初始界面,复用绘图代码,减少重复代码:
清空画布文字;
打印标题与按键操作提示;
刷新屏幕;
关闭全部 RGB 彩灯,保持待机安静无灯光。

五、setup () 上电初始化(仅开机执行 1 次)
执行顺序:硬件初始化 → AI 初始化 → 摄像头初始化 → 绑定按键 → 配置 RGB 亮度 → 加载待机界面

  1. void setup() {
  2.         k10.begin();                // 初始化主板全部底层硬件
  3.         k10.initScreen(screen_dir); // 初始化显示屏
  4.         ai.initAi();                // 启动ESP32-S3内置AI加速芯片NPU
  5.         k10.initBgCamerImage();     // 开启摄像头画面投屏功能
  6.         k10.setBgCamerImage(false); // 初始化阶段临时关闭摄像头画面
  7.         k10.creatCanvas();          // 创建绘图缓存,消除屏幕闪烁
  8.         ai.switchAiMode(ai.NoMode); // 清空上一轮AI模式,防止冲突
  9.         // 绑定A、B按键按下回调,按键触发不受delay阻塞
  10.         k10.buttonB->setPressedCallback(onButtonBPressed);
  11.         k10.buttonA->setPressedCallback(onButtonAPressed);
  12.         k10.setBgCamerImage(true);  // 打开摄像头实时画面投屏
  13.         ai.switchAiMode(ai.Face);   // 切换AI为人脸识别模式(支持录入+比对)
  14.         k10.rgb->brightness(5);     // 修复灯光失效:K10亮度范围0~10,设置适中亮度
  15.         showStandbyUI(); // 开机直接进入待机界面
  16. }
复制代码

六、loop () 主循环(程序无限循环,核心业务逻辑)
整体分为三大分支:待机拦截、识别到人脸、人脸丢失判断

  1. void loop() {
  2.         // 1. 识别开关关闭:直接跳出循环,保持待机,不做任何运算
  3.         if (!startRecogFlag) {
  4.                 return;
  5.         }
  6.         bool hasFace = ai.isRecognized(); // 判断是否匹配到已录入人脸
  7.         unsigned long nowTime = millis(); // 获取系统运行毫秒,无阻塞计时
  8.         // ========== 分支1:识别到已录入家人人脸 ==========
  9.         if (hasFace) {
  10.                 faceLostTimer = nowTime; // 持续刷新计时,人脸在镜头内就重置3秒倒计时
  11.                 nowFaceID = ai.getRecognitionID(); // 读取人脸ID
  12.                 k10.canvas->canvasClear();
  13.                 k10.canvas->canvasText("检测人脸 ID:" + String(nowFaceID), 0, 0, 0xFFFFFF, k10.canvas->eCNAndENFont24, 50, true);
  14.                 // 每100ms刷新一次灯光亮度,柔和呼吸渐变
  15.                 if (nowTime - breathTimer > 100) {
  16.                         breathTimer = nowTime;
  17.                         // 亮度30~200来回渐变,防止过暗/过亮
  18.                         if (breathDir) {
  19.                                 breathVal += 8;
  20.                                 if (breathVal >= 200) breathDir = false;
  21.                         } else {
  22.                                 breathVal -= 8;
  23.                                 if (breathVal <= 30) breathDir = true;
  24.                         }
  25.                         // ID1老爷:绿色呼吸灯
  26.                         if (nowFaceID == 1.0) {
  27.                                 k10.canvas->canvasText("ID1 老爷 · 绿光氛围", 0, 40, 0x00FF00, k10.canvas->eCNAndENFont24, 50, true);
  28.                                 uint32_t greenColor = breathVal << 8;
  29.                                 k10.rgb->write(-1, greenColor);
  30.                         }
  31.                         // ID2小姐:蓝色呼吸灯
  32.                         else if (nowFaceID == 2.0) {
  33.                                 k10.canvas->canvasText("ID2 小姐 · 蓝光氛围", 0, 40, 0x0000FF, k10.canvas->eCNAndENFont24, 50, true);
  34.                                 uint32_t blueColor = breathVal;
  35.                                 k10.rgb->write(-1, blueColor);
  36.                         }
  37.                 }
  38.                 k10.canvas->updateCanvas();
  39.         }
  40.         // ========== 分支2:没有识别到人脸(遮挡/离开/陌生人) ==========
  41.         else {
  42.                 // 子分支1:人脸消失不足3秒,短暂遮挡,不做任何操作,保持灯光
  43.                 if (nowTime - faceLostTimer < FACE_KEEP_DELAY) {
  44.                         return;
  45.                 }
  46.                 // 子分支2:人脸离开超过3秒,关闭识别,关灯切回待机
  47.                 startRecogFlag = false;
  48.                 showStandbyUI();
  49.         }
  50. }
复制代码

灯光逻辑说明
ID=1(老爷):只改变绿色通道亮度,呈现绿色明暗呼吸;
ID=2(小姐):只改变蓝色通道亮度,呈现蓝色明暗呼吸;
渐变区间锁定 30~200,最低亮度不会黑到看不见灯光。

七、A 按键回调函数 onButtonAPressed () 人脸录入功能

  1. void onButtonAPressed() {
  2.         k10.canvas->canvasClear();
  3.         k10.canvas->canvasText("采集人脸中,请正对镜头", 0, 0, 0x0066FF, k10.canvas->eCNAndENFont24, 50, true);
  4.         k10.canvas->updateCanvas();
  5.         ai.sendFaceCmd(ENROLL); // 下发录入指令,采集人脸特征并分配ID
  6.         delay(3000); // 预留3秒采集时间,避免录入失败
  7.         k10.canvas->canvasClear();
  8.         k10.canvas->canvasText("人脸录入完成!", 0, 0, 0x00FF00, k10.canvas->eCNAndENFont24, 50, true);
  9.         k10.canvas->canvasText("按B键开启人脸氛围灯",0,35,0xFFFFFF,k10.canvas->eCNAndENFont24,50,true);
  10.         k10.canvas->updateCanvas();
  11.         delay(1200);
  12.         showStandbyUI(); // 录入完成自动返回待机
  13. }
复制代码

操作逻辑:按下 A→屏幕提示采集→3 秒录入→提示录入成功→自动回到待机界面。

八、B 按键回调函数 onButtonBPressed () 开启识别氛围灯

  1. void onButtonBPressed() {
  2.         startRecogFlag = true;          // 打开识别总开关,loop开始执行人脸检测
  3.         faceLostTimer = millis();       // 重置人脸丢失计时
  4.         breathTimer = millis();         // 重置灯光渐变计时
  5.         breathVal = 30;                 // 重置基础亮度,识别立刻亮灯
  6.         breathDir = true;               // 重置渐变方向
  7.         ai.sendFaceCmd(RECOGNIZE);      // 下发人脸比对指令,实时匹配人脸库
  8.         k10.canvas->canvasClear();
  9.         k10.canvas->canvasText("人脸氛围灯已启动", 0, 0, 0x0066FF, k10.canvas->eCNAndENFont24, 50, true);
  10.         k10.canvas->canvasText("正在识别人脸",0,35,0xFFFFFF,k10.canvas->eCNAndENFont24,50,true);
  11.         k10.canvas->updateCanvas();
  12.         delay(1000); // 启动提示停留1秒
  13. }
复制代码

按下 B 后正式进入工作模式,摄像头持续识别人脸、自动控制对应颜色呼吸氛围灯。

九、整体完整运行流程
开机:自动待机,屏幕显示操作提示,RGB 灯全灭,不检测人脸;
录入人脸:对准人脸按 A 键,等待 3 秒采集完成,自动回到待机;第一张人脸 ID=1(绿光),第二张 ID=2(蓝光);
启动氛围灯:按下 B 键,进入识别工作模式;
识别到老爷 ID1:屏幕显示 ID1 绿光提示,RGB 绿色柔和明暗呼吸渐变;
识别到小姐 ID2:屏幕显示 ID2 蓝光提示,RGB 蓝色柔和明暗呼吸渐变;
人脸短暂遮挡、低头、挡脸(3 秒内):灯光持续渐变,不会熄灭、不会切界面;
人脸完全离开镜头超过 3 秒:自动关闭识别,彩灯熄灭,切回干净待机界面;
如需再次使用氛围灯,必须重新按下 B 键启动识别。

十、核心亮点
修复 RGB 亮度参数,解决灯光完全不亮的问题;
3 秒人脸缓冲机制,避免人脸轻微晃动导致灯光反复开关;
不同人脸 ID 匹配专属固定颜色呼吸灯,视觉区分明显;
无阻塞灯光渐变计时,画面流畅不卡顿;
超时自动退出识别,无需手动关闭,回归安静待机;
分层清晰,待机 / 识别 / 人脸丢失三种场景完全隔离,界面不乱跳。

回复

使用道具 举报

驴友花雕  高级技神
 楼主|

发表于 6 小时前

【花雕动手做】行空板 K10 实验之人脸录入识别氛围灯

实验场景图与视频记录

【花雕动手做】行空板 K10 实验之人脸录入和识别氛围灯图4

【花雕动手做】行空板 K10 实验之人脸录入和识别氛围灯图2

【花雕动手做】行空板 K10 实验之人脸录入和识别氛围灯图3

【花雕动手做】行空板 K10 实验之人脸录入和识别氛围灯图1

回复

使用道具 举报

驴友花雕  高级技神
 楼主|

发表于 6 小时前

【花雕动手做】行空板 K10 实验之人脸录入识别氛围灯

【花雕动手做】行空板 K10 实验之人脸录入和识别氛围灯图1

【花雕动手做】行空板 K10 实验之人脸录入和识别氛围灯图4

【花雕动手做】行空板 K10 实验之人脸录入和识别氛围灯图3
【花雕动手做】行空板 K10 实验之人脸录入和识别氛围灯图2



回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4 备案 沪公网安备31011502402448

© 2013-2026 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail