基于手势识别的厨房无接触电子食谱助手

2026-09-182

一、项目背景

 

在日常做饭时,我发现电子菜谱和短视频虽然使用方便,但真正操作起来,经常需要一边处理食材、一边查看屏幕和切换步骤。尤其是在双手沾水、油污或食材后,再去触碰手机或屏幕不仅不方便,也很容易打断烹饪节奏。基于这个实际体验,我尝试设计了一款厨房无接触电子食谱助手,以行空板 K10 为主控,通过手势识别传感器完成菜谱选择和步骤切换,并结合语音合成模块播报当前烹饪内容;同时利用 K10 连接的 LED 灯,在手势识别成功后提供直观反馈。整个项目主要希望通过手势、语音和界面交互的结合,让电子菜谱在真实厨房环境中使用起来更加自然方便。

 

二、项目目标

 

完成一个能够通过手势选择菜谱、查看食材、逐步制作并获得语音和计时提示的厨房电子菜谱助手。以下视频是整个项目的体验过程。

三、器材清单

基于手势识别的厨房无接触电子食谱助手_image_1.webp

四、 准备工作

 

1.设置菜单翻页专用手势

在正式编写程序之前·,首先我们要先通过配套的上位机软件来快速体验传感器的核心功能。AI视觉手势/姿势识别传感器的更多详细使用方法见下面的网址:

wiki.dfrobot.com.cn/SKU_SNE0670_Gravity_AI视觉手势和姿势识别传感器

根据下载的AI视觉手势/姿态传感器自带的官方软件,解压后双击.exe文件。

打开之后电脑通过USB线连接传感器,可以看到下图界面,连接端口后点击打开即可显示传感器摄像头画面,打开软件后可以先通过右上角修改显示语言为中文。

基于手势识别的厨房无接触电子食谱助手_image_2.webp

上位机默认为自学习手势识别模式。如下图所示,任意摆出一个手势,传感器将会进行识别,输出对应姿势的ID和置信度,并且输出该手势的21个关键点实时数据。点击学习按钮即可对手势进行学习并记录对应手势ID。本项目自学习两种手势,分别对应ID1和ID2,用于电子菜谱助手的翻页功能。

基于手势识别的厨房无接触电子食谱助手_image_3.webp

接下来切换模式为固定手势识别模式。如下图所示,根据右侧图片中的手势类型,摆出任意一个手势,传感器会识别对应手势的ID和名称。

基于手势识别的厨房无接触电子食谱助手_image_4.webp

另外该传感器还可以切换姿势识别,本项目由于没有进行相关姿势识别的学习,故不对其进行介绍。按照上面的步骤学习手势后,即可开始编写代码,实现一个基于手势识别的厨房无接触电子菜谱助手。

 

2.录入菜谱相关图片

 

在正式编写程序前需要将提前准备好的图片资源上传至TF卡中,之后将TF卡插入行空板K10即可。共使用 20 张图片。每张图片为 140×128 像素的 PNG。注意:插入行空板K10的TF卡建议最大16GB,推荐使用DF商城在售的正品闪迪卡,使用未知品牌的内存卡,易出现读写卡失败、程序崩溃等问题。

下方表格内容为本项目上传的对应菜谱的图片资源文件名。

菜谱文件名前缀步骤编号
西红柿炒鸡蛋recipe_tomato_1~5
蛋炒饭recipe_fried_rice_1~5
可乐鸡翅recipe_cola_wings_1~5
青椒炒肉recipe_pepper_pork_1~5

3.下载编程相关库

 

(1)项目使用 Arduino C 完成,首先需要下载安装Arduino IDE(https://www.arduino.cc/en/software/)。

基于手势识别的厨房无接触电子食谱助手_image_5.webp

 

下载完成后,按提示步骤安装Arduino IDE,配置行空板K10准备开始制作项目。具体如何使用可以参考下方链接:https://www.unihiker.com.cn/wiki/k10/ArduinoIDE_prepare

(2)下载资源附件,找到语音合成和AI视觉姿势/手势传感器的依赖库文件夹。DFRobot_HumanPose和 DFRobot_SpeechSynthesis_M。

 

五、项目搭建

 

1. 流程分析

系统由手势传感器完成本地手势识别,K10读取识别结果并转换为内部操作编号,再由页面状态机结合当前页面确定具体功能。

项目要实现的核心功能如下图:

基于手势识别的厨房无接触电子食谱助手_image_6.webp

 

系统执行过程:

 

首页支持四道菜谱循环选择,并根据选中位置自动调整卡片显示区域;进入食材页后显示对应食材信息,再通过手势进入制作步骤。制作过程中可通过左右摆切换前后步骤,也可随时握拳返回首页。界面显示、语音播报和计时均随当前菜谱及步骤同步更新,同时在手势识别成功后通过数字LED闪烁进行提示。

基于手势识别的厨房无接触电子食谱助手_image_7.webp

本项目使用的手势及功能对应表如下:

具体手势

系统反应

识别标识ID

左摆(自学习手势)

上一个/步

1

右摆(自学习手势)

下一个/步

2

OK(固定手势)

确认选择

8

握拳(固定手势)

返回首页

0

2. 硬件连接

将AI视觉手势/姿势传感器接在行空板K10的I²C接口,LED灯接在P0口,行空板插入扩展板,语音合成模块连接在扩展板上,上传程序时K10通过USB线连接电脑。

说明:当程序通过电脑编程上传至K10后本项目实现也可直接采用充电宝进行供电。

基于手势识别的厨房无接触电子食谱助手_image_8.webp

设备连接成功后,进行程序的完整编写。

3. 编写程序

项目实现的核心逻辑

程序启动后首先进行初始化,然后进入菜谱首页。运行过程中,主循环持续处理LED状态、语音播放状态、手势识别和步骤计时,根据当前页面及识别到的手势决定需要执行的操作。

识别手势的核心逻辑:

  • 程序在 eHandeGesture 两种模型之间轮换。模型每次切换成功后,传感器内部推理结果可能仍然属于上一个模型,或者图像数据尚未稳定。因此程序等待200 ms后才开始读取结果。
  • 等待模型稳定后,程序在当前模型下读取手势结果约650 ms。如果在这个窗口中没有形成有效手势,并且系统没有处于锁定状态,就切换到另一个模型继续识别。
  • 程序第一次识别到有效手势时,只把它记录为候选手势,并通过 candidateSince 记录出现时间,不立即执行操作。只有连续识别为同一个手势达到250 ms,程序才确认该手势有效。
  • 手势稳定确认后,程序先将 gestureLocked 设置为 true,再调用 handleGesture()执行页面操作。数字LED同时点亮200 ms,用于提示用户手势已经被系统接受。
  • 手势执行后,系统进入锁定状态。只有传感器连续约600 ms没有检测到手,程序才解除锁定,允许识别下一次操作。

基于手势识别的厨房无接触电子食谱助手_image_9.webp

项目文件结构

本项目的资源文件结构如下,其中RecipeAssistant_K10.ino 是项目主程序,需要修改菜谱名称、食材、制作步骤、计时时长、界面文字或颜色时,主要修改这个文件。

RecipeAssistant_K10/
│
├─ data/                                   【图片及调试资源】
│  ├─ recipe_images_preview/               【步骤图片,可按规则替换】
│  │  ├─ recipe_tomato_1.png ~ recipe_tomato_5.png
│  │  ├─ recipe_fried_rice_1.png ~ recipe_fried_rice_5.png
│  │  ├─ recipe_cola_wings_1.png ~ recipe_cola_wings_5.png
│  │  └─ recipe_pepper_pork_1.png ~ recipe_pepper_pork_5.png
│  │
│  └─ 白屏排查前代码.ino.txt                【历史备份,不参与编译】
│
└─ RecipeAssistant_K10_c/                   【Arduino程序文件夹】
   │
   ├─ RecipeAssistant_K10.ino              【项目主程序,可修改】
   │
   └─ src/                                 【本地依赖库,通常不要修改】
      │
      ├─ unihiker_k10_local/               【行空板K10适配库】
      │  ├─ unihiker_k10.h
      │  ├─ unihiker_k10.cpp
      │  ├─ GT30L24A3W.h
      │  └─ DFRobot_GT30L24A3W.cpp
      │
      ├─ DFRobot_HumanPose/                【SEN0670手势传感器库】
      │  ├─ DFRobot_HumanPose.h
      │  ├─ DFRobot_HumanPose.cpp
      │  ├─ Result.h
      │  ├─ Result.cpp
      │  ├─ library.properties
      │  └─ LICENSE
      │
      └─ DFRobot_SpeechSynthesis_M/        【语音模块参考库】
         ├─ DFRobot_SpeechSynthesis_M.h
         └─ DFRobot_SpeechSynthesis_M.cpp

部分关键代码如下:

(1)初始化设备与界面

setup() 启动串口和 K10,配置 LED 输出,再创建横屏画布并初始化 TF 卡。先建立背景对象、再创建画布,才能获得有效显示对象。屏幕方向为 1,对应 320×240 像素。以下是相关代码:

void setup() {
  Serial.begin(115200);
  delay(500);
  k10.begin();
  digitalWrite(GESTURE_LED_PIN, GESTURE_LED_ON == HIGH ? LOW : HIGH);
  pinMode(GESTURE_LED_PIN, OUTPUT);
  k10.initScreen(SCREEN_DIR);
  k10.setScreenBackground(COLOR_BG);
  // 当前 K10 库需要先建立背景对象,Canvas 才能取得有效父对象。
  k10.initBgCamerImage();
  k10.creatCanvas();
  k10.setBgCamerImage(false);
  // 使用用户提供的 MindPlus TF 卡初始化接口,只在启动时调用一次。
  Serial.println(F("[TF] Initializing SD file system..."));
  k10.initSDFile();
  Serial.println(F("[TF] SD initialization returned."));

随后初始化 V1 语音模块,再连接手势传感器并选择 eHand 模型。两种设备共用 Wire,但地址与访问时钟不同。

const uint8_t SENSOR_ADDR = 0x3A;
const uint8_t SPEECH_ADDR = 0x40;
const uint32_t GESTURE_I2C_CLOCK = 400000;
const uint32_t SPEECH_I2C_CLOCK = 100000;

(2)映射手势编号并轮换识别模型

自学习模型 eHand 的 ID1、ID2 对应左摆和右摆;固定模型 eGesture 的 ID8、ID0 对应 OK 和握拳。mapGestureResult() 结合当前模型转换原始编号:内部 GESTURE_OK=3、GESTURE_FIST=4 是操作编号,无需额外学习 ID3 或 ID4。自学习模型的 ID0 不触发返回。以下是相关代码:

uint8_t mapGestureResult(uint8_t rawId) {
  if (readingLearnedModel) {
    if (rawId == 1) return GESTURE_LEFT;
    if (rawId == 2) return GESTURE_RIGHT;
  } else {
    if (rawId == 8) return GESTURE_OK;
    if (rawId == 0) return GESTURE_FIST;
  }
  return GESTURE_NONE;
}

两个模型轮换工作。切换成功后等待 200 ms,再进入约 650 ms 的采样窗口;失败时暂停读取,等待 1000 ms 后重试同一目标模型。切换时清除旧结果与候选手势,避免跨模型混用编号。以下是相关代码:

void switchGestureModel() {
  const bool nextLearned = !readingLearnedModel;
  restoreGestureI2CClock();
  const DFRobot_HumanPose::eCmdCode_t status = sensor.setModelType(
    nextLearned ? DFRobot_HumanPose::eHand : DFRobot_HumanPose::eGesture);
  if (status != DFRobot_HumanPose::eOK) {
    // 返回失败时无法确定设备端模型,不读取结果,等待重试同一目标。
    modelSwitchFailed = true;
    modelRetryAt = millis() + MODEL_RETRY_MS;
    Serial.println(F("[Gesture] model switch failed; retrying."));
    return;
  }
  readingLearnedModel = nextLearned;
  modelSwitchFailed = false;
  while (sensor.availableResult()) sensor.popResult();
  candidateGesture = GESTURE_NONE;
  candidateSince = millis();
  modelReadyAt = millis() + MODEL_SETTLE_MS;
  modelWindowSince = modelReadyAt;
}

(3)稳定识别并防止重复触发

首先读取当前模型的结果,映射后选择有效操作中置信度最高的一项;如果通信失败会清空候选,但不当作手已移开。processGestureFrame() 要求同一候选持续至少 250 ms 才执行操作,随后锁定;手移开约 600 ms 后才允许再次触发。

以下是相关代码:

void processGestureFrame(uint8_t id) {
  unsigned long now = millis();
  if (id == GESTURE_NONE) {
    if (now - lastGestureSeen >= 600) {
      gestureLocked = false;
      candidateGesture = GESTURE_NONE;
    }
    return;
  }
  lastGestureSeen = now;
  if (gestureLocked) return;
  if (id != candidateGesture) {
    candidateGesture = id;
    candidateSince = now;
    return;
  }
  if (now - candidateSince >= 250) {
    gestureLocked = true;
    // 稳定识别250ms后只闪一次;持续保持同一手势不会反复闪灯。
    // 即使该手势在当前页没有动作,也反馈“已识别”。
    flashGestureLed();
    handleGesture(id);
  }
}

4. 运行程序

完成接线、手势学习和 TF 图片拷贝后,将完整程序编译上传至 K10。上电后等待语音模块与传感器初始化,出现“请选择菜谱”后开始操作。在Arduino IDE软件中打开文件运行即可查看程序运行效果。

程序运行后,具体实现效果如下图 :

注意:详细程序可查看附件。

基于手势识别的厨房无接触电子食谱助手_image_10.webp

调试与注意事项

  • 传感器连接失败:检查传感器是否处于 I²C 模式,确认地址为 0x3A、SDA/SCL 接线正确、设备共地且供电正常;调整拨码开关后需重新上电。
  • 手势识别不准确或无响应:确认手势ID是否正确,可先通过上位机验证识别结果,并调整手型朝向、光照、背景。每次操作后应将手完全移出识别区域,等待约 0.6 秒再做下一次手势,避免触发锁定影响连续操作。
  • 切换界面没有语音:检查语音模块接线、0x40 地址、V1 模式及音量设置。若上一段语音仍在播放,程序会跳过本次播报,可等待播放结束后再操作。
  • 项目中的食材用量、制作步骤和计时仅供参考,用户可根据实际烹饪经验与需求修改代码中的菜谱数据,并同步更新对应的步骤图片。
  • DFRobot_HumanPose 手势传感器库和项目专用的 unihiker_k10_local 库必须保留在工程的 src 文件夹内。Arduino IDE 打开主程序后会自动编译这些依赖,不需要再次通过库管理器安装。

硬件清单

创作许可协议

本项目采用 CC BY(署名) 进行许可。

所需材料/产品

加载全部

    Gravity: 数字白色LED发光模块(Arduino兼容)

    Gravity: 数字白色LED发光模块(Arduino兼容)

    Gravity: 数字白色LED发光模块(Arduino兼容)

    Gravity:中英文语音合成模块V2.0 - 蘑菇云科创教育

    Gravity:中英文语音合成模块V2.0 - 蘑菇云科创教育

    Gravity:中英文语音合成模块V2.0 - 蘑菇云科创教育

    行空板K10 MicroPython编程AI教学/学习主控板(含两头PH2.0白色硅胶线)- 蘑菇云科创教育

    行空板K10 MicroPython编程AI教学/学习主控板(含两头PH2.0白色硅胶线)- 蘑菇云科创教育

    行空板K10 MicroPython编程AI教学/学习主控板(含两头PH2.0白色硅胶线)- 蘑菇云科创教育

相关推荐

评论(0)
- 没有更多了 -

创作许可协议

本项目采用 CC BY(署名) 进行许可。

相关推荐

所需材料/产品

Gravity: 数字白色LED发光模块(Arduino兼容)

Gravity: 数字白色LED发光模块(Arduino兼容)

Gravity: 数字白色LED发光模块(Arduino兼容)

Gravity:中英文语音合成模块V2.0 - 蘑菇云科创教育

Gravity:中英文语音合成模块V2.0 - 蘑菇云科创教育

Gravity:中英文语音合成模块V2.0 - 蘑菇云科创教育

行空板K10 MicroPython编程AI教学/学习主控板(含两头PH2.0白色硅胶线)- 蘑菇云科创教育

行空板K10 MicroPython编程AI教学/学习主控板(含两头PH2.0白色硅胶线)- 蘑菇云科创教育

行空板K10 MicroPython编程AI教学/学习主控板(含两头PH2.0白色硅胶线)- 蘑菇云科创教育

加载全部