MediaPipe + ESP32-S3 + P2.5:AI手势控制64×64流体灯板的实现原理
前言
最近我使用USB摄像头、电脑、ESP32-S3和一块64×64的P2.5 HUB75灯板,实现了一个AI视觉流体灯板。
没有检测到手时,ESP32-S3会持续运行自动流体动画;当手出现在摄像头画面中后,张手、握拳、移动和捏合会被转换成不同的流体作用力。
本文重点解释手势识别链路、关键点计算、动作判断、串口数据设计,以及ESP32-S3如何把手势转换成灯板效果。

一、系统结构
整个系统分为电脑视觉端和ESP32-S3显示端。
USB摄像头
↓
MediaPipe Hand Landmarker
↓
21个手部关键点
↓
动作、位置和速度计算
↓ USB串口,230400 baud
ESP32-S3
↓
流体粒子与力场计算
↓
64×64 P2.5 HUB75灯板
电脑负责视觉推理,ESP32-S3负责实时灯效。串口中只传输控制参数,不传输视频帧,也不传输完整的4096像素画面。
二、MediaPipe输出了什么
项目使用MediaPipe Hand Landmarker。每检测到一只手,模型会输出21个关键点:
- 1个手腕点;
- 拇指4个点;
- 食指、中指、无名指、小指各4个点。
每个关键点包含归一化坐标。x=0.5、y=0.5表示该点位于画面中心,因此后续算法不依赖摄像头的具体分辨率。
MediaPipe并没有直接替我们完成全部动作分类。项目会根据这些关键点进一步计算:
- 手掌中心位置;
- 每根手指是否伸展;
- 拇指与食指的相对距离;
- 相邻帧之间的位移和速度;
- 当前动作的稳定状态。
三、四种手势的判断方法
1. 张开手掌
程序比较指尖、指关节和掌心的位置。如果检测到至少4根手指伸展,就判断为张开手掌。
张手对应排斥力,手掌附近的粒子会向外散开。
2. 握拳
当大部分指尖收回掌心附近,伸展手指数量不超过1根时,判断为握拳。
握拳对应吸引力,粒子会向手掌映射到的灯板位置聚拢。
3. 拇指与食指捏合
不能只使用两指之间的像素距离,因为手靠近摄像头时会整体变大。
项目使用归一化比例:
pinch_ratio = 拇指尖到食指尖的距离 / 手掌参考尺度
当pinch_ratio <= 0.42时,判断为捏合。捏合会触发一次粒子爆发,而不是持续施加作用力。
4. 手掌移动
程序记录手掌中心在相邻两帧中的位置:
vx = current_x - previous_x
vy = current_y - previous_y
speed = sqrt(vx² + vy²)
vx和vy决定推动方向,speed决定推动强度。
四、为什么必须做滤波
手部关键点会受到光线、遮挡、运动模糊和模型误差影响。如果直接使用每一帧的结果,灯板会出现抖动,动作也可能在两个状态之间快速切换。
本项目主要采用以下处理:
- 对手掌坐标进行低通平滑;
- 对速度单独平滑,避免单帧定位误差变成强冲击;
- 为手势设置阈值,减少临界状态反复切换;
- 设置丢失超时,避免手离开后保留上一次作用力。
ESP32-S3超过约500ms没有收到有效手势数据时,会清除手势力,但自动流体动画仍然继续运行。
五、串口为什么只发送控制参数
如果发送完整64×64 RGB画面,一帧至少需要:
64 × 64 × 3 = 12288 bytes
以30FPS计算,仅像素数据就接近369KB/s,还没有计算帧头、校验和转义开销。普通串口很难稳定承担这种数据量。
因此电脑只发送类似下面的控制数据:
{
"seq": 1032,
"visible": true,
"gesture": "open",
"x": 0.63,
"y": 0.41,
"vx": 0.08,
"vy": -0.03,
"speed": 0.086
}
这类数据通常只有几十到几百字节。ESP32-S3收到后,将归一化坐标映射到灯板:
int panelX = constrain(static_cast<int>(x * 63.0f), 0, 63);
int panelY = constrain(static_cast<int>(y * 63.0f), 0, 63);
然后根据动作类型选择吸引、排斥、推动或爆发力。
六、流体效果怎样响应手势
视觉端和流体端是两个独立模块。
视觉端只负责输出:
手是否可见
手掌坐标
动作类型
移动方向
移动速度
ESP32-S3端根据这些数据修改粒子速度:
张手:粒子远离手掌中心
握拳:粒子靠近手掌中心
移动:沿手掌移动方向增加速度
捏合:瞬间施加径向冲击力
这样的分层设计便于扩展。视觉端可以换成人体姿态、物体追踪或面部方向,显示端也可以换成火焰、粒子喷泉、光点或小游戏。
七、常见问题
摄像头打开错了
电脑同时存在内置摄像头和USB摄像头时,需要枚举摄像头编号,并在配置中选择正确设备。
串口无法连接
关闭PlatformIO Monitor、Arduino串口监视器等占用串口的软件,再启动视觉程序。
手势识别抖动
增加位置平滑,适当提高动作阈值,并避免强逆光。手掌尽量完整出现在画面中。
灯板闪烁或重启
64×64 P2.5灯板需要独立、稳定的5V电源。ESP32-S3与灯板必须共地,不能依靠开发板USB口给整块灯板供电。
总结
这个项目的核心不是让AI直接生成4096个像素,而是让AI把现实动作翻译成少量、稳定的控制参数。
电脑负责从画面中提取21个关键点,并判断位置、速度和动作;ESP32-S3负责把这些数据转换成灯板上的流体力场。两部分通过轻量串口协议连接,既减少通信压力,也保留了嵌入式端实时生成灯效的能力。
我是阿白,感谢您的观看。
更多推荐


所有评论(0)