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

[K10教程] 【花雕动手做】 行空板 K10 实验之人脸识别自动照相机

[复制链接]
【花雕动手做】 行空板 K10 实验之人脸识别自动照相机图1

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

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


【花雕动手做】 行空板 K10 实验之人脸识别自动照相机图2

驴友花雕  高级技神
 楼主|

发表于 5 小时前

【花雕动手做】 行空板 K10 实验之人脸识别自动照相机

主打:人工智能模块

【花雕动手做】 行空板 K10 实验之人脸识别自动照相机图1

人脸检测相关说明

【花雕动手做】 行空板 K10 实验之人脸识别自动照相机图2

【花雕动手做】 行空板 K10 实验之人脸识别自动照相机图3


回复

使用道具 举报

驴友花雕  高级技神
 楼主|

发表于 5 小时前

【花雕动手做】 行空板 K10 实验之人脸识别自动照相机

辅助:屏幕显示相关积木
【花雕动手做】 行空板 K10 实验之人脸识别自动照相机图1


LED控制模块


【花雕动手做】 行空板 K10 实验之人脸识别自动照相机图2
回复

使用道具 举报

驴友花雕  高级技神
 楼主|

发表于 5 小时前

【花雕动手做】 行空板 K10 实验之人脸识别自动照相机

【花雕动手做】 行空板 K10 实验之人脸识别自动照相机图3

知识点:行空板 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 实验之人脸识别自动照相机图1
回复

使用道具 举报

驴友花雕  高级技神
 楼主|

发表于 5 小时前

【花雕动手做】 行空板 K10 实验之人脸识别自动照相机

人脸检测的几张案例图片

【花雕动手做】 行空板 K10 实验之人脸识别自动照相机图2

【花雕动手做】 行空板 K10 实验之人脸识别自动照相机图3

【花雕动手做】 行空板 K10 实验之人脸识别自动照相机图1
回复

使用道具 举报

驴友花雕  高级技神
 楼主|

发表于 5 小时前

【花雕动手做】 行空板 K10 实验之人脸识别自动照相机

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

  1. // 引入行空板K10硬件驱动库:包含屏幕、RGB、按键、摄像头、画布等全部外设接口
  2. #include "unihiker_k10.h"
  3. // 引入离线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 startDetectFlag = false;   // 相机总开关:false=待机不检测人脸,true=开启人脸抓拍逻辑
  19. float nowFaceID = 0;            // 存储当前识别匹配成功的人脸编号,第一张录入ID=1,第二张ID=2
  20. unsigned long faceHoldTimer = 0;// 人脸稳定计时戳:记录最后一次识别到人脸的系统毫秒时间
  21. const unsigned long FACE_SHOOT_DELAY = 2000; // 人脸稳定阈值2000ms=2秒,满足时长触发抓拍提示
  22. unsigned long blinkTimer = 0;   // RGB红灯闪烁无阻塞计时戳,控制倒计时灯光刷新间隔
  23. bool blinkState = false;        // 灯光亮灭状态标记,true亮红灯、false熄灭
  24. unsigned long shootTime = 0;    // 抓拍成功提示文字计时戳,控制提示停留时长
  25. bool shootFlag = false;         // 单次抓拍锁:同一人脸周期只触发一次抓拍提示,防止循环刷屏
  26. /**
  27. * @brief 统一绘制待机界面封装函数
  28. * 作用:开机、人脸超时、录入完成后统一调用,复用绘图代码,简化程序
  29. * 功能:清空画布、打印操作指引、关闭全部RGB彩灯
  30. */
  31. void showStandbyUI()
  32. {
  33.   k10.canvas->canvasClear(); // 清空画布所有残留文字画面
  34.   // 红色标题文字,坐标X0 Y0,24号中文字体,透明度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.   k10.canvas->updateCanvas(); // 将画布缓存刷新到LCD屏幕显示
  39.   k10.rgb->write(-1, 0x000000); // -1代表全部RGB灯珠,0x000000黑色,关闭所有氛围灯
  40. }
  41. /**
  42. * @brief 模拟抓拍函数(因库拍照接口不兼容,仅做屏幕提示标记,无TF卡存储)
  43. * 逻辑:将抓拍标记置为true,记录抓拍时间戳,用于屏幕显示抓拍成功文字
  44. */
  45. void takePhoto()
  46. {
  47.   shootFlag = true; // 标记本次人脸周期已完成抓拍,不再重复触发
  48.   shootTime = millis(); // 获取当前系统毫秒时间,作为提示文字起始计时
  49. }
  50. /**
  51. * @brief 上电初始化函数,仅开机/复位执行1次
  52. * 执行流程:硬件初始化→屏幕→AI加速器→摄像头→绑定按键→切换人脸AI模式→加载待机界面
  53. */
  54. void setup() {
  55.         k10.begin();                // 初始化行空板底层IO、供电、总线等全部硬件
  56.         k10.initScreen(screen_dir); // 根据screen_dir参数初始化显示屏驱动
  57.         ai.initAi();                // 启动ESP32-S3内置NPU AI加速芯片,加载人脸推理模型
  58.         k10.initBgCamerImage();     // 初始化摄像头后台画面渲染,支持摄像头画面投屏显示
  59.         k10.setBgCamerImage(false); // 初始化阶段临时关闭摄像头画面,避免画面干扰初始化流程
  60.         k10.creatCanvas();          // 创建绘图缓存画布,绘图先存缓存再统一刷新,消除屏幕闪烁
  61.         ai.switchAiMode(ai.NoMode); // 临时切换AI为无识别模式,清空上一轮残留AI状态,防止冲突
  62.         // 给A、B物理按键绑定按下中断回调,按键触发不受delay延时阻塞
  63.         k10.buttonB->setPressedCallback(onButtonBPressed);
  64.         k10.buttonA->setPressedCallback(onButtonAPressed);
  65.         k10.setBgCamerImage(true);  // 开启摄像头实时画面投屏,屏幕持续显示镜头取景画面
  66.         ai.switchAiMode(ai.Face);   // 切换AI工作模式为人脸识别模式,同时支持人脸录入、人脸特征比对
  67.         k10.rgb->brightness(5);     // RGB亮度参数:K10硬件有效范围0~10,设置5为适中柔和亮度
  68.         // 硬件初始化完成,加载安静待机界面,无识别、无灯光
  69.         showStandbyUI();
  70. }
  71. /**
  72. * @brief 主循环函数,上电后无限循环执行,程序核心业务逻辑
  73. * 分层逻辑:待机拦截 → 识别到人脸(计时+红灯闪烁+抓拍提示) → 人脸丢失(分短暂遮挡/超时退出)
  74. */
  75. void loop() {
  76.         // 判断相机总开关关闭:直接终止本次循环,保持待机界面,不执行任何人脸检测运算
  77.         if (!startDetectFlag) {
  78.                 return;
  79.         }
  80.         bool hasFace = ai.isRecognized(); // 判断AI是否匹配本地已录入人脸:true=识别到家人,false=无匹配人脸
  81.         unsigned long nowTime = millis(); // 获取系统开机累计运行毫秒数,无阻塞计时,画面不卡顿
  82.         // 抓拍成功提示文字停留2秒后自动清除
  83.         if (shootFlag && nowTime - shootTime > 2000)
  84.         {
  85.                 shootFlag = false;
  86.         }
  87.         // ========== 场景1:摄像头识别到已录入的合法人脸 ==========
  88.         if (hasFace)
  89.         {
  90.                 faceHoldTimer = nowTime; // 持续刷新人脸稳定计时,只要人脸在镜头内就重置2秒倒计时
  91.                 nowFaceID = ai.getRecognitionID(); // 读取当前匹配成功的人脸专属编号ID
  92.                 k10.canvas->canvasClear(); // 清空上一轮屏幕文字残留
  93.                 k10.canvas->canvasText("检测人脸 ID:" + String(nowFaceID), 0, 0, 0xFFFFFF, k10.canvas->eCNAndENFont24, 50, true);
  94.                 // 人脸稳定停留满2秒,进入红灯闪烁倒计时抓拍提示
  95.                 if (nowTime - faceHoldTimer >= FACE_SHOOT_DELAY)
  96.                 {
  97.                         k10.canvas->canvasText("即将自动抓拍...", 0, 40, 0xFF9900, k10.canvas->eCNAndENFont24, 50, true);
  98.                         // 每300ms切换一次红灯状态,实现交替闪烁倒计时效果
  99.                         if (nowTime - blinkTimer > 300)
  100.                         {
  101.                                 blinkTimer = nowTime;
  102.                                 blinkState = !blinkState; // 翻转灯光状态
  103.                                 if (blinkState)
  104.                                         k10.rgb->write(-1, 0xFF0000); // 红灯亮起
  105.                                 else
  106.                                         k10.rgb->write(-1, 0x000000); // 灯光熄灭
  107.                         }
  108.                         // 仅抓拍一次,防止循环内反复触发提示
  109.                         if (!shootFlag)
  110.                         {
  111.                                 takePhoto();
  112.                         }
  113.                 }
  114.                 else
  115.                 {
  116.                         // 人脸停留不足2秒,灯光保持熄灭,提示用户稳住人脸
  117.                         k10.rgb->write(-1, 0x000000);
  118.                         k10.canvas->canvasText("人脸稳定2秒自动拍照", 0, 40, 0x00FFFF, k10.canvas->eCNAndENFont24, 50, true);
  119.                 }
  120.                 // 抓拍完成后,屏幕显示绿色成功提示文字
  121.                 if (shootFlag)
  122.                 {
  123.                         k10.canvas->canvasText("抓拍成功!", 0, 70, 0x00FF00, k10.canvas->eCNAndENFont24, 50, true);
  124.                 }
  125.                 k10.canvas->updateCanvas(); // 将当前所有文字刷新到LCD屏幕
  126.         }
  127.         // ========== 场景2:摄像头未识别到录入人脸(人脸遮挡、转头、完全离开、陌生人) ==========
  128.         else
  129.         {
  130.                 // 判断人脸消失时长是否超过2秒阈值
  131.                 if (nowTime - faceHoldTimer > FACE_SHOOT_DELAY)
  132.                 {
  133.                         faceHoldTimer = nowTime; // 重置人脸稳定计时
  134.                         shootFlag = false;      // 重置抓拍标记,下次识别人脸可重新触发抓拍提示
  135.                         k10.rgb->write(-1, 0x000000); // 关闭全部彩灯
  136.                         k10.canvas->canvasClear();
  137.                         k10.canvas->canvasText("等待人脸进入画面...", 0, 0, 0xAAAAAA, k10.canvas->eCNAndENFont24, 50, true);
  138.                         k10.canvas->updateCanvas();
  139.                 }
  140.                 // 人脸消失不足2秒:短暂遮挡,不做任何操作,保持上一轮画面
  141.         }
  142. }
  143. /**
  144. * @brief A按键按下回调函数:执行人脸录入学习功能
  145. * 流程:显示采集提示 → 下发人脸录入指令 → 阻塞3秒采集人脸特征 → 提示录入完成 → 1.2秒后切回待机界面
  146. */
  147. void onButtonAPressed() {
  148.         k10.canvas->canvasClear();
  149.         // 蓝色提示文字,提醒用户正对摄像头完****脸采集
  150.         k10.canvas->canvasText("采集人脸中,请正对镜头", 0, 0, 0x0066FF, k10.canvas->eCNAndENFont24, 50, true);
  151.         k10.canvas->updateCanvas();
  152.         ai.sendFaceCmd(ENROLL); // 下发AI录入指令:采集当前人脸特征,本地存储并自动分配ID(第一张=1,第二张=2)
  153.         delay(3000); // 阻塞3秒,给AI充足时间完****脸特征采集,避免录入失败
  154.         k10.canvas->canvasClear();
  155.         // 绿色文字提示录入成功
  156.         k10.canvas->canvasText("人脸录入完成!", 0, 0, 0x00FF00, k10.canvas->eCNAndENFont24, 50, true);
  157.         k10.canvas->canvasText("按B键开启人脸自动相机",0,35,0xFFFFFF,k10.canvas->eCNAndENFont24,50,true);
  158.         k10.canvas->updateCanvas();
  159.         delay(1200); // 停留1.2秒,让用户看清录入成功提示
  160.         showStandbyUI(); // 人脸录入结束,自动返回安静待机界面
  161. }
  162. /**
  163. * @brief B按键按下回调函数:开启人脸自动相机检测工作模式
  164. * 流程:打开识别总开关 → 重置全部计时标记 → 下发人脸比对指令 → 弹出启动提示界面
  165. */
  166. void onButtonBPressed() {
  167.         startDetectFlag = true;          // 打开相机总开关,loop循环开始执行人脸检测、灯光控制逻辑
  168.         faceHoldTimer = millis();       // 初始化人脸稳定计时,按下B瞬间开始计算2秒缓冲倒计时
  169.         blinkTimer = millis();         // 重置红灯闪烁计时戳
  170.         shootFlag = false;             // 重置抓拍标记,新周期可正常触发抓拍提示
  171.         ai.sendFaceCmd(RECOGNIZE);      // 下发AI识别比对指令,持续实时匹配镜头人脸与本地人脸库
  172.         k10.canvas->canvasClear();
  173.         k10.canvas->canvasText("人脸自动相机已启动", 0, 0, 0x0066FF, k10.canvas->eCNAndENFont24, 50, true);
  174.         k10.canvas->canvasText("识别到人脸稳定2秒自动拍照",0,35,0xFFFFFF,k10.canvas->eCNAndENFont24,50,true);
  175.         k10.canvas->updateCanvas();
  176.         delay(1000); // 启动提示界面停留1秒,之后进入loop实时人脸检测逻辑
  177. }
复制代码


回复

使用道具 举报

驴友花雕  高级技神
 楼主|

发表于 5 小时前

【花雕动手做】 行空板 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();
复制代码

提前声明 A、B 按键的中断回调函数,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 startDetectFlag = false;   // 相机总开关
  2. float nowFaceID = 0;            // 当前识别到的人脸编号
  3. unsigned long faceHoldTimer = 0;// 人脸稳定停留计时戳
  4. const unsigned long FACE_SHOOT_DELAY = 2000; // 人脸稳定2秒触发抓拍提示
  5. unsigned long blinkTimer = 0;   // 红灯闪烁无阻塞计时戳
  6. bool blinkState = false;        // 红灯亮灭状态标记
  7. unsigned long shootTime = 0;    // 抓拍成功提示文字计时戳
  8. bool shootFlag = false;         // 单次抓拍锁,防止循环重复触发提示
复制代码

startDetectFlag:程序分两种模式,false= 待机不检测人脸,true= 开启人脸抓拍逻辑;
faceHoldTimer + FACE_SHOOT_DELAY:实现人脸 2 秒稳定缓冲,短暂转头、挡脸不会立刻重置逻辑;
blinkTimer / blinkState:无阻塞控制红灯交替闪烁做抓拍倒计时提示,不卡顿画面;
shootFlag:单次抓拍锁,同一人脸稳定周期只弹出一次抓拍成功提示,避免刷屏。

四、封装函数:待机界面 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 彩灯,待机状态无灯光。

五、封装函数:模拟抓拍 takePhoto ()

  1. void takePhoto()
  2. {
  3.   shootFlag = true;
  4.   shootTime = millis();
  5. }
复制代码

说明
因当前 Mind + 内置 K10 库缺少统一拍照存储接口,删除 TF 卡保存图片逻辑,仅做软件标记:
shootFlag=true 标记当前人脸周期已完成抓拍;
记录当前系统时间戳,用于控制 “抓拍成功” 提示文字停留 2 秒自动消失。

六、setup () 上电初始化(仅开机执行 1 次)
执行流程:底层硬件初始化 → AI 加速器 → 摄像头 → 绑定按键 → 切换人脸 AI 模式 → 加载待机界面

  1. void setup() {
  2.         k10.begin();                // 初始化主板全部IO、供电、总线外设
  3.         k10.initScreen(screen_dir); // 初始化LCD显示屏
  4.         ai.initAi();                // 启动ESP32-S3内置NPU AI硬件加速模块
  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);     // RGB亮度适配修复:K10亮度有效区间0~10,5为柔和适中亮度
  15.         showStandbyUI(); // 开机直接进入安静待机界面,无识别、无灯光
  16. }
复制代码

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

  1. void loop() {
  2.         // 分支0:相机总开关关闭,直接终止本次循环,保持待机,不做任何人脸运算
  3.         if (!startDetectFlag) {
  4.                 return;
  5.         }
  6.         bool hasFace = ai.isRecognized(); // 判断是否匹配本地已录入人脸
  7.         unsigned long nowTime = millis(); // 获取系统运行毫秒,无阻塞计时不卡顿画面
  8.         // 抓拍成功提示文字停留满2秒,自动清除提示标记
  9.         if (shootFlag && nowTime - shootTime > 2000)
  10.         {
  11.                 shootFlag = false;
  12.         }
  13.         // ========== 分支1:识别到已录入家人人脸 ==========
  14.         if (hasFace)
  15.         {
  16.                 faceHoldTimer = nowTime; // 持续刷新2秒稳定倒计时,人脸在镜头内就重置计时
  17.                 nowFaceID = ai.getRecognitionID(); // 读取当前匹配人脸ID
  18.                 k10.canvas->canvasClear();
  19.                 k10.canvas->canvasText("检测人脸 ID:" + String(nowFaceID), 0, 0, 0xFFFFFF, k10.canvas->eCNAndENFont24, 50, true);
  20.                 // 子分支1.1:人脸稳定停留满2秒,进入红灯闪烁倒计时
  21.                 if (nowTime - faceHoldTimer >= FACE_SHOOT_DELAY)
  22.                 {
  23.                         k10.canvas->canvasText("即将自动抓拍...", 0, 40, 0xFF9900, k10.canvas->eCNAndENFont24, 50, true);
  24.                         // 每300ms切换一次红灯状态,实现交替闪烁倒计时效果
  25.                         if (nowTime - blinkTimer > 300)
  26.                         {
  27.                                 blinkTimer = nowTime;
  28.                                 blinkState = !blinkState;
  29.                                 if (blinkState)
  30.                                         k10.rgb->write(-1, 0xFF0000);
  31.                                 else
  32.                                         k10.rgb->write(-1, 0x000000);
  33.                         }
  34.                         // 仅触发一次抓拍标记,防止循环内反复弹出提示
  35.                         if (!shootFlag)
  36.                         {
  37.                                 takePhoto();
  38.                         }
  39.                 }
  40.                 // 子分支1.2:人脸不足2秒,无灯光,提示稳住人脸
  41.                 else
  42.                 {
  43.                         k10.rgb->write(-1, 0x000000);
  44.                         k10.canvas->canvasText("人脸稳定2秒自动拍照", 0, 40, 0x00FFFF, k10.canvas->eCNAndENFont24, 50, true);
  45.                 }
  46.                 // 抓拍完成,屏幕显示绿色成功提示文字
  47.                 if (shootFlag)
  48.                 {
  49.                         k10.canvas->canvasText("抓拍成功!", 0, 70, 0x00FF00, k10.canvas->eCNAndENFont24, 50, true);
  50.                 }
  51.                 k10.canvas->updateCanvas();
  52.         }
  53.         // ========== 分支2:无匹配人脸(遮挡、转头、人脸离开、陌生人) ==========
  54.         else
  55.         {
  56.                 // 人脸消失超过2秒,重置全部计时与抓拍标记
  57.                 if (nowTime - faceHoldTimer > FACE_SHOOT_DELAY)
  58.                 {
  59.                         faceHoldTimer = nowTime;
  60.                         shootFlag = false;
  61.                         k10.rgb->write(-1, 0x000000);
  62.                         k10.canvas->canvasClear();
  63.                         k10.canvas->canvasText("等待人脸进入画面...", 0, 0, 0xAAAAAA, k10.canvas->eCNAndENFont24, 50, true);
  64.                         k10.canvas->updateCanvas();
  65.                 }
  66.                 // 人脸消失不足2秒:短暂遮挡,不做任何操作,保持上一帧画面
  67.         }
  68. }
复制代码

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

v
  1. oid 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,第一张ID=1,第二张ID=2
  6.         delay(3000); // 阻塞3秒,给AI充足时间完****脸采集,避免录入失败
  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); // 停留1.2秒,让用户看清录入成功提示
  12.         showStandbyUI(); // 录入结束自动返回待机界面
  13. }
复制代码

操作流程:按下 A → 屏幕提示采集人脸 → 等待 3 秒采集 → 提示录入完成 → 自动切回待机。

九、B 按键回调函数 onButtonBPressed ():启动人脸相机检测

  1. void onButtonBPressed() {
  2.         startDetectFlag = true;          // 打开相机总开关,loop开始执行人脸检测逻辑
  3.         faceHoldTimer = millis();       // 初始化人脸稳定2秒倒计时
  4.         blinkTimer = millis();         // 重置红灯闪烁计时
  5.         shootFlag = false;             // 重置抓拍标记,新识别周期可正常触发抓拍提示
  6.         ai.sendFaceCmd(RECOGNIZE);      // 下发实时人脸比对指令,摄像头持续识别人脸库
  7.         k10.canvas->canvasClear();
  8.         k10.canvas->canvasText("人脸自动相机已启动", 0, 0, 0x0066FF, k10.canvas->eCNAndENFont24, 50, true);
  9.         k10.canvas->canvasText("识别到人脸稳定2秒自动拍照",0,35,0xFFFFFF,k10.canvas->eCNAndENFont24,50,true);
  10.         k10.canvas->updateCanvas();
  11.         delay(1000); // 启动提示界面停留1秒,之后进入loop实时检测
  12. }
复制代码

按下 B 后正式进入工作模式,摄像头持续识别人脸、控制红灯倒计时、弹出抓拍成功提示。

十、完整运行流程总结
开机:自动待机,屏幕仅显示按键操作指引,RGB 灯全灭,不检测人脸;
录入人脸:对准人脸按 A,等待 3 秒采集完成,1.2 秒后自动回到待机;第一张人脸 ID=1,第二张 ID=2;
启动相机:按下 B 开启人脸检测工作模式;
人脸稳定停留满 2 秒:RGB 红灯 300ms 交替闪烁倒计时,屏幕显示「即将自动抓拍...」,弹出一次绿色「抓拍成功!」提示,提示持续 2 秒消失;
人脸短暂遮挡、低头、转头(2 秒内):画面不切换、不重置抓拍标记,保持当前界面;
人脸完全离开镜头超过 2 秒:重置全部计时与抓拍标记,屏幕显示「等待人脸进入画面...」;
如需再次触发抓拍,必须人脸重新进入镜头累计满 2 秒稳定时长。

核心优化亮点
移除 TF 卡拍照存储代码,规避老旧库拍照接口不存在的编译报错;
2 秒人脸缓冲机制,解决人脸轻微晃动、遮挡导致界面反复跳转;
红灯交替闪烁倒计时视觉提示,交互直观;
单次抓拍锁,同一人脸周期只弹出一次成功提示,不会无限刷屏;
超时自动重置逻辑,无需手动关闭,逻辑分层清晰,待机 / 识别 / 人脸丢失三种场景互不干扰。

回复

使用道具 举报

驴友花雕  高级技神
 楼主|

发表于 5 小时前

【花雕动手做】 行空板 K10 实验之人脸识别自动照相机

实验场景图与视频记录

【花雕动手做】 行空板 K10 实验之人脸识别自动照相机图5

【花雕动手做】 行空板 K10 实验之人脸识别自动照相机图1

【花雕动手做】 行空板 K10 实验之人脸识别自动照相机图2

【花雕动手做】 行空板 K10 实验之人脸识别自动照相机图3

【花雕动手做】 行空板 K10 实验之人脸识别自动照相机图4
回复

使用道具 举报

驴友花雕  高级技神
 楼主|

发表于 5 小时前

【花雕动手做】 行空板 K10 实验之人脸识别自动照相机

【花雕动手做】 行空板 K10 实验之人脸识别自动照相机图4

【花雕动手做】 行空板 K10 实验之人脸识别自动照相机图3

【花雕动手做】 行空板 K10 实验之人脸识别自动照相机图2

【花雕动手做】 行空板 K10 实验之人脸识别自动照相机图1

【花雕动手做】 行空板 K10 实验之人脸识别自动照相机图5
回复

使用道具 举报

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

本版积分规则

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

硬件清单

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

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

mail