MediaPipe 手势识别踩坑记

21 个关键点听起来很美,真正做出"跟手又稳定"的手势识别是另一回事。记录我在做手势遥控器时踩过的坑:性能、误触发、镜像、低光。

白穆
白穆 站长
手势遥控器作者 · 独立开发者

《手势遥控器》的核心就是一句话:把摄像头里的手,变成一个可靠的遥控器。这句话里最难的是"可靠"两个字。这篇记录我踩过的坑,给同样想玩 MediaPipe 的朋友铺路。

坑一:性能,不是识别准不准,而是省不省电

MediaPipe Hands 在中端机上的识别速度没问题,但持续开启摄像头是另一个命题。做遥控器意味着识别服务可能挂着几十分钟,功耗直接决定这个 App 是否可用。

我的做法:

  • 降采样:给识别的帧直接降到 480P 级别。手部关键点不需要 1080P,分辨率降下来,CPU 和 NPU 的压力断崖式下降,识别精度几乎不受影响。
  • 帧间隔:不必每帧都识别。控制好节拍,隔帧送入,手部动作的连续性靠插值补足,肉眼无感。
  • 空闲降频:连续 N 秒没有检测到手,自动进入低频轮询模式,手一出现立刻恢复。刷视频的场景里,手不是一直举着的,这个优化对续航贡献巨大。

坑二:误触发——90% 的正确率等于不可用

演示的时候一切都好,实际用起来全是灾难,原因通常是误触发。你想切歌的时候它切了,你没想动的时候它也切了。

解决方案是一套组合拳:

  1. 手势确认窗口:一个手势必须连续命中若干帧才算数,瞬间闪过的手势直接丢弃。这个窗口太短会误触,太长会"跟手性差",我最终取在 200ms 上下。
  2. 动作冷却:同一个动作触发后有一段冷却时间,防止"抖动导致的连发"。切歌这种动作冷却 800ms,体感刚刚好。
  3. 关键点平滑:对 21 个关键点做指数滑动平均,滤掉手抖的高频噪声。平滑系数是玄学,调的时候要开着摄像头一帧帧看。

这三条单独看都很朴素,但调参的顺序很重要:先平滑、再窗口、最后冷却,反过来调你会怀疑人生。

坑三:前置摄像头镜像

一个让我笑了很久的 bug:测试"向右滑"手势的时候,识别方向总是反的。

原因很简单:前置摄像头默认是镜像的(自拍预览所见即所得),而 MediaPipe 输出的是画面坐标系里的关键点。你举着右手在画面左侧,镜像之后坐标就到了右边。滑动方向的判定必须先决定"用哪套坐标系",否则所有的方向类手势都是反的。一行 1 - x 解决,但定位到这一行花了一晚上。

坑四:低光环境是重灾区

晚上关灯躺着刷视频,恰恰是目标场景。但摄像头在低光下噪点爆炸,关键点开始漂移,识别率骤降。

  • 曝光策略:识别用的是一个单独的 ImageAnalysis 用例,可以单独调曝光偏好,宁要"亮而糊"不要"暗而清"。
  • 预期管理:我最后没有强行解决暗光识别,而是在 App 里坦诚提示"光线过暗可能影响识别"。识别这件事上,诚实的降级好过虚假的承诺。

坑五:机型差异

同一套参数,在 A 机器上丝般顺滑,在 B 机器上像喝了假酒。原因包括摄像头标定差异、SoC 算力差异、系统对后台服务的限制差异。我的策略是给默认值 + 允许用户调:识别灵敏度、动作冷却都在设置里开放,默认值取大多数机型体验的交集。

总结

MediaPipe 本身很好用,真正的工作量都在它外面:功耗、防抖、镜像、暗光、机型适配。如果说模型是"耳朵",那这些工程细节才是"听懂人话"的部分。

如果只让我留一条建议给要做手势交互的人:先花一周做"手势确认窗口 + 冷却"的框架,再去调模型参数。稳定性是设计出来的,不是调出来的。

← 手势遥控器:从一个想法到 19.9 上架售卖 一码一机:我的离线授权系统设计 →

评论(0)

评论需要先注册账号

注册 / 登录

还没有评论,来抢沙发。

这篇文章对你有帮助?来留言板聊聊 · 回到博客

联系站长