Skip to main content

Grove Vision AI V2 和 XIAO ESP32 示例

释放边缘计算的潜力,探索 AI 视觉的迷人世界,体验 Grove Vision AI V2 和 XIAO ESP32 系列 MCU 的强大组合。在本教程中,我们将带您完成 2~3 个引人入胜的演示,展示这些尖端技术的无缝集成。

无论您是经验丰富的开发者还是好奇的爱好者,这些演示都将为您提供实践经验,帮助您掌握 Grove Vision AI V2 和 XIAO ESP32 的强大功能。从对象检测和识别到智能场景分析,您将发现如何创建突破性的应用程序,挑战可能性的边界。

准备好踏上激动人心的旅程吧!我们将揭开 AI 视觉的秘密,赋予您构建自己开创性项目的能力。让我们一起深入探索,释放 Grove Vision AI V2 和 XIAO ESP32 的魔力!

这段开场描述旨在吸引读者的注意力,突出关键组件(Grove Vision AI V2 和 XIAO ESP32),并简要介绍教程内容。它强调了结合这些技术的激动人心的可能性,并鼓励读者充满热情地探索这些演示。您可以根据教程的风格和语气自由调整和修改这段文字。

入门

硬件准备

本文中的教程和步骤适用于 XIAO ESP32 系列产品(XIAO ESP32S3、XIAO ESP32C3、XIAO ESP32C6 等),您可以选择任意一款 XIAO ESP32 系列产品完成本教程的内容。

除了主控 MCU,我们还需要准备 Grove Vision AI V2 和支持的摄像头,以完成本项目的内容。

如果您想使用其他摄像头,可以阅读支持摄像头列表以获取更多信息。

软件准备

如果这是您第一次使用 Grove Vision AI V2 产品,我们建议您阅读以下 Wiki,学习如何使用 SenseCraft AI 并了解如何上传模型。同时学习如何安装 Grove Vision AI V2 的 Arduino 库。

项目 I:制作一个面部追踪风扇

在这个令人兴奋的演示中,我们将向您展示如何制作一个面部追踪风扇,它会自动跟随您的每一个动作,确保清爽的微风始终吹向您。

使用 Grove Vision AI V2,我们将利用面部识别的魔力实时检测并追踪您的面部。Vision AI V2 将持续输出您的面部坐标,为风扇的精确定位提供必要的数据。

第一步:将面部识别模型上传到 Grove Vision AI V2

在这个项目中,我们将制作一个跟随面部的风扇,因此我们需要为 Grove Vision AI V2 使用一个面部识别模型。您可以使用 SenseCraft AI 上传此模型,并在预览窗口中观看检测效果。

第二步:准备风扇和旋转结构

由于风扇结构不易修改,对于风扇的转向结构,我们计划制作一个由舵机控制的水平转向底座。

然后,使用亚克力板和热熔胶,我们将风扇粘贴到底座舵机上。

舵机的线连接到 XIAO ESP32 的 D6 引脚,并通过 5V 供电。Grove Vision AI V2 通过 Grove 接口简单地连接到 XIAO 的 IIC 接口。这里我们还使用了 XIAO 扩展板底座 以便于布线。

最后,不要忘记将 Grove Vision AI V2 的摄像头粘贴到风扇的中间位置。

第三步:为 XIAO 上传程序

以下是该项目的完整程序,请编译并将此程序上传到 XIAO ESP32 系列。

#include <Seeed_Arduino_SSCMA.h>
SSCMA Infer;

void stop_rotate(void)
{
digitalWrite(D6, HIGH);
delayMicroseconds(1500);
digitalWrite(D6, LOW);
}

void servo_rotate(int rtime, bool revers = false)
{
uint32_t sleep;
if (revers)
{
sleep = 2500;
}
else
{
sleep = 500;
}
digitalWrite(D6, HIGH);

delayMicroseconds(sleep);
digitalWrite(D6, LOW);
delay(30 * rtime);
stop_rotate();
}

void setup()
{
Infer.begin();
Serial.begin(9600);
pinMode(D6, OUTPUT);
}

void loop()
{
if (!Infer.invoke())
{
if (Infer.boxes().size() > 0)
{
if (Infer.boxes()[0].x < 80)
{
servo_rotate(1, true);
}
else if (Infer.boxes()[0].x > 140)
{
servo_rotate(1, false);
}
Serial.print("X==>>");
Serial.print(Infer.boxes()[0].x);
Serial.print("Y==>>");
Serial.println(Infer.boxes()[0].y);
}
}
}

如果程序运行顺利,您应该会看到如下效果。

note

舵机的旋转和角度可能因舵机的不同而有所变化,因此请根据您使用的舵机进行适当调整,这可能需要进行微调。

程序注释

代码结构如下:

  1. 库引入

    • Seeed_Arduino_SSCMA.h:用于启用 Grove Vision AI V2 的推理功能。
  2. 对象声明

    • SSCMA Infer:创建 SSCMA 类的实例以进行推理。
  3. stop_rotate 函数

    • 通过发送特定的脉宽停止舵机的旋转。
  4. servo_rotate 函数

    • 控制舵机按指定的时间和方向旋转。
    • rtime:以 30 毫秒为单位确定旋转时间。
    • revers:指定旋转方向(true 为反向,false 为正向)。
  5. setup 函数

    • 初始化 Grove Vision AI V2、串行通信,并将舵机引脚(D0)配置为输出。
  6. loop 函数

    • 持续调用推理过程。
    • 如果检测到对象:
      • 如果对象的 x 坐标小于 80,舵机短时间反向旋转。
      • 如果对象的 x 坐标大于 140,舵机短时间正向旋转。
    • 将检测到的对象的 x 和 y 坐标打印到串行监视器。

要修改代码并自定义对象追踪系统,您可以:

  1. 调整 loop 函数中的阈值(80 和 140),以改变舵机保持静止的范围。

  2. 修改 servo_rotate 函数以调整舵机的旋转时间和速度。

  3. 根据对象的位置自定义系统行为。例如,您可以根据检测到的对象的 x 和 y 坐标添加额外的条件或动作。

  4. 扩展代码以控制额外的舵机或根据对象的位置执行其他操作。

项目二:自动锁定/解锁电脑

通过使用 Grove Vision AI V2 和 XIAO ESP32,增强您的电脑安全性和便利性。本项目通过自动屏幕锁定/解锁功能,确保当您离开时屏幕自动锁定,而当您返回时快速解锁,为您提供无缝且安全的用户体验。

第一步:将人脸识别模型上传到 Grove Vision AI V2

在本项目中,我们将根据电脑前是否有人来锁定或解锁屏幕,因此我们需要为 Grove Vision AI V2 使用人脸识别模型。您可以使用 SenseCraft AI 上传此模型,并在预览窗口中查看检测效果。

第二步:XIAO 连接到电脑并上传程序到 XIAO

以下是本项目的完整程序,请编译并上传到 XIAO ESP32 系列。

#include "USB.h"
#include <USBHIDKeyboard.h>
#include <Seeed_Arduino_SSCMA.h>

#define KEY_DEBOUNCE 100
#define KEY_WAIT 500
// 设置无人时屏幕暂停时间,单位:毫秒
#define SCREEN_TIME 10000

SSCMA Infer;
USBHIDKeyboard Keyboard;

extern char password[] = "YOUR_COMPUTER_PASSWORD";
extern uint pass_size = 6;
unsigned long times;

bool locked = false;

void lockPC() {
Keyboard.press(KEY_LEFT_CTRL);
Keyboard.press(KEY_LEFT_ALT);
Keyboard.press(KEY_DELETE);
delay(KEY_DEBOUNCE);
Keyboard.releaseAll();
delay(KEY_WAIT);

Keyboard.press(KEY_RETURN);
delay(KEY_DEBOUNCE);
Keyboard.releaseAll();
locked = true;
}

void unlockPC (){
Keyboard.press(KEY_RETURN);
delay(KEY_DEBOUNCE);
Keyboard.releaseAll();
delay(KEY_WAIT);
for(int i = 0; i < pass_size; i++){
Keyboard.press(password[i]);
delay(KEY_DEBOUNCE);
Keyboard.releaseAll();
}
delay(KEY_WAIT);
Keyboard.press(KEY_RETURN);
delay(KEY_DEBOUNCE);
Keyboard.releaseAll();
locked = false;
}

void setup() {
// 在此处放置初始化代码,仅运行一次:
Serial.begin(115200);
Serial.println("Scanning...");

// 启动 HID
Keyboard.begin();
USB.begin();
Infer.begin();

times = millis();
}

void loop() {
// 在此处放置主代码,循环运行:
if (!Infer.invoke()) {
if (Infer.boxes().size() > 0) {
if (locked) {
unlockPC();
Serial.println("Unlock");
}
times = millis();
} else {
if ((millis() - times) > SCREEN_TIME && !locked) {
lockPC();
Serial.println("Lock");
}
}
} else {
if ((millis() - times) > SCREEN_TIME && !locked) {
lockPC();
Serial.println("Lock");
}
}
}

如果程序运行顺利,您应该看到如下效果。

:::提示

  1. 此程序仅适用于 Windows 电脑,如果您的电脑使用其他系统,您可能需要更改屏幕关闭的命令。

  2. 如果您的 Windows 电脑设置了指纹解锁或其他非密码解锁方式,解锁代码可能无法正常工作。 :::

程序注释

代码结构如下:

  1. 引入必要的库:

    • USB.h:处理 USB 通信。
    • USBHIDKeyboard.h:启用 USB HID 键盘功能。
    • Seeed_Arduino_SSCMA.h:提供人员检测的推理能力。
  2. 定义常量:

    • KEY_DEBOUNCE:键盘输入的去抖时间。
    • KEY_WAIT:键盘输入之间的等待时间。
    • SCREEN_TIME:无人时屏幕锁定的时间间隔。
  3. 创建 SSCMA (Infer) 和 USBHIDKeyboard (Keyboard) 类的实例。

  4. 声明变量:

    • password[]:存储用于解锁电脑的密码。
    • pass_size:存储密码的长度。
    • times:存储最后一次检测到人员的时间戳。
    • locked:跟踪电脑当前的锁定状态。
  5. lockPC 函数:

    • 模拟键盘快捷键 (Win+L) 来锁定电脑。
    • 等待 KEY_DEBOUNCEKEY_WAIT 时间。
    • 按下回车键确认锁定操作。
    • 更新 locked 变量以指示锁定状态。
  6. unlockPC 函数:

    • 按下回车键启动解锁过程。
    • 等待 KEY_DEBOUNCEKEY_WAIT 时间。
    • 模拟逐字符输入密码。
    • 按下回车键确认密码输入。
    • 更新 locked 变量以指示解锁状态。
  7. setup 函数:

    • 初始化串口通信。
    • 启动 USB 键盘 (Keyboard) 和推理引擎 (Infer)。
    • 设置初始人员检测时间戳。
  8. loop 函数:

    • 调用推理引擎 (Infer)。
    • 如果检测到人员:
      • 如果电脑处于锁定状态,调用 unlockPC 函数解锁。
      • 更新最后一次检测到人员的时间戳。
    • 如果未检测到人员:
      • 如果距离最后一次检测到人员的时间超过 SCREEN_TIME 且电脑未锁定,调用 lockPC 函数锁定。
    • 如果推理失败:
      • 如果距离最后一次检测到人员的时间超过 SCREEN_TIME 且电脑未锁定,调用 lockPC 函数锁定。

您可以根据需求自定义代码,以下是可修改的部分:

  1. 更新密码:

    • YOUR_COMPUTER_PASSWORD 替换为您的实际电脑密码。
    • 修改 pass_size 以匹配密码的长度。
  2. 调整常量:

    • 修改 KEY_DEBOUNCEKEY_WAIT 以更改键盘输入的时间。
    • 修改 SCREEN_TIME 以更改无人时屏幕锁定的时间间隔。
  3. 自定义锁定和解锁过程:

    • lockPCunlockPC 函数中,您可以修改键盘快捷键或输入序列以匹配您的操作系统或安全设置。
  4. 集成额外功能:

    • 您可以扩展代码以在计算机锁定或解锁时执行额外的操作或通知。
    • 例如,您可以发送电子邮件、触发警报或记录事件。

项目 III:手势控制鼠标

通过这个突破性的手势控制鼠标项目,使用 Grove Vision AI V2 和 XIAO ESP32,改变您的人机交互体验。告别传统的鼠标输入,拥抱更直观、更自然的计算机导航方式。

Grove Vision AI V2 是该项目的核心,它利用其先进的计算机视觉能力检测并跟踪用户的手势。通过采用复杂的算法,它可以识别特定的手部动作并将其转换为相应的鼠标操作。

第一步:将手势识别模型上传到 Grove Vision AI V2

在这个项目中,我们将基于手势操作鼠标,因此我们需要为 Grove Vision AI V2 使用手势识别模型。您可以使用 SenseCraft AI 上传此模型,并在预览窗口中观看检测效果。

第二步:XIAO 连接到计算机并上传程序到 XIAO

以下是该项目的完整程序,请编译并上传此程序到 XIAO ESP32 系列。

#include <Seeed_Arduino_SSCMA.h>
#include "USBHIDMouse.h"
#include "USB.h"

#define KEY_DEBOUNCE 100
#define KEY_WAIT 500
#define RESET_NUM 3
#define LEFT_CLICK_TARGET 0
#define MOVE_TARGET 1
#define RIGHT_CLICK_TARGET 2

SSCMA Infer;
USBHIDMouse Mouse;

int X = 0, Y = 0;
int8_t mx, my;
bool clicked = false;
int reset_mouse = RESET_NUM;

void setup() {
// 在此处放置您的初始化代码,仅运行一次:
Serial.begin(115200);
Infer.begin();

// 初始化鼠标控制:
Mouse.begin();
USB.begin();
}

void move_mouse(int mx, int my) {
Mouse.move(mx, my);
}

void loop() {
if (!Infer.invoke()) {
Serial.println("调用成功:");
if (Infer.boxes().size() == 0) {
if (reset_mouse <= 0) {
X = 0;
Y = 0;
} else {
reset_mouse -= 1;
}
}

for (int i = 0; i < Infer.boxes().size() && i < 1; i++) {
reset_mouse = RESET_NUM;
if (Infer.boxes()[i].target == MOVE_TARGET) {
// Mouse.press(MOUSE_RIGHT);
if (X == 0 && Y == 0) {
X = Infer.boxes()[i].x;
Y = Infer.boxes()[i].y;
} else {
mx = Infer.boxes()[i].x - X;
my = Infer.boxes()[i].y - Y;
X = Infer.boxes()[i].x;
Y = Infer.boxes()[i].y;
move_mouse(-mx * 2, my * 2);
clicked = false;
}
} else if (Infer.boxes()[i].target == LEFT_CLICK_TARGET && !clicked) {
Mouse.press(MOUSE_LEFT);
delay(KEY_DEBOUNCE);
Mouse.release(MOUSE_LEFT);
delay(KEY_WAIT);
clicked = true;
} else if (Infer.boxes()[i].target == RIGHT_CLICK_TARGET && !clicked) {
Mouse.press(MOUSE_RIGHT);
delay(KEY_DEBOUNCE);
Mouse.release(MOUSE_RIGHT);
delay(KEY_WAIT);
clicked = false;
}
}

} else {
Serial.println("调用失败!");
}
}

如果程序运行顺利,您应该看到如下效果。

程序注释

代码结构如下:

  1. 引入必要的库:

    • Seeed_Arduino_SSCMA.h:提供目标检测的推理功能。
    • USBHIDMouse.h:启用 USB HID 鼠标功能。
    • USB.h:处理 USB 通信。
  2. 定义常量:

    • KEY_DEBOUNCE:鼠标点击的去抖时间。
    • KEY_WAIT:鼠标点击之间的等待时间。
    • RESET_NUM:在未检测到目标的帧数后重置鼠标位置的计数。
    • LEFT_CLICK_TARGETMOVE_TARGETRIGHT_CLICK_TARGET:不同操作的目标 ID。
  3. 创建 SSCMA (Infer) 和 USBHIDMouse (Mouse) 类的实例。

  4. 声明变量:

    • XY:存储当前鼠标位置。
    • mxmy:存储鼠标移动的增量。
    • clicked:跟踪点击状态。
    • reset_mouse:用于重置鼠标位置的计数器。
  5. setup 函数:

    • 初始化串行通信。
    • 启动推理引擎 (Infer) 和 USB 鼠标 (Mouse)。
  6. move_mouse 函数:

    • 根据指定的增量 (mxmy) 移动鼠标。
  7. loop 函数:

    • 调用推理引擎 (Infer)。
    • 如果推理成功且未检测到目标,在 RESET_NUM 帧后重置鼠标位置。
    • 遍历检测到的目标(此代码限制为 1 个目标):
      • 如果目标是 MOVE_TARGET
        • 根据目标的坐标更新鼠标位置。
        • 计算鼠标移动的增量 (mxmy)。
        • 相应地移动鼠标。
      • 如果目标是 LEFT_CLICK_TARGET 且尚未点击:
        • 执行左键单击。
        • 等待 KEY_DEBOUNCEKEY_WAIT 的时间。
      • 如果目标是 RIGHT_CLICK_TARGET 且尚未点击:
        • 执行右键单击。
        • 等待 KEY_DEBOUNCEKEY_WAIT 的时间。
    • 如果推理失败,打印错误信息。

要根据您的需求自定义代码,可以进行以下更改:

  1. 调整常量:

    • 修改 KEY_DEBOUNCEKEY_WAIT 以更改鼠标点击的时间。
    • 修改 RESET_NUM 以更改未检测到目标的帧数后重置鼠标位置的计数。
    • 更新 LEFT_CLICK_TARGETMOVE_TARGETRIGHT_CLICK_TARGET 以匹配您的特定目标 ID。
  2. 修改目标处理逻辑:

    • loop 函数中,您可以根据检测到的目标添加、删除或修改条件和操作。
    • 例如,您可以添加额外的鼠标按钮、实现双击或根据特定目标 ID 触发不同的操作。
  3. 自定义鼠标移动:

    • move_mouse 函数中,您可以通过调整乘法因子(如 -mx * 2my * 2)或添加额外的逻辑来修改鼠标移动行为。
  4. 集成其他功能:

    • 您可以通过使用适当的库和函数扩展代码,以包含键盘控制、媒体控制或任何其他所需的功能。

技术支持与产品讨论

感谢您选择我们的产品!我们致力于为您提供多种支持,以确保您使用我们的产品时获得尽可能顺畅的体验。我们提供多种沟通渠道,以满足不同的偏好和需求。

Loading Comments...