MediaPipe Hands 手部关键点追踪:5 分钟跑通 21 点手势识别的完整教程
【免费下载链接】mediapipeCross-platform, customizable ML solutions for live and streaming media.项目地址: https://gitcode.com/GitHub_Trending/med/mediapipe
画面里的手刚转个角度、被指尖自己挡一下,追踪就丢了?MediaPipe Hands 用「手掌检测 + 关键点回归」两级模型,单帧就能实时算出每只手 21 个 3D 关键点,Python、JS、Android、桌面 C++ 都能接。读完这篇,你能在 5 分钟里装好 Python 版、看懂 21 个点的分组含义,再换到 JS 与 Android 上接起来,文末还有一张高频翻车自查表。
能力速览:这套 API 到底给什么
这一步先帮你确认能拿到什么、有哪些可调旋钮,免得写代码时一脸懵。
核心能力:
- 21 个 3D 关键点:单帧即可回归出手腕与四指的完整骨骼结构,无需历史帧。
- 左右手判断:每只手附带
Left/Right标签和置信度score。 - 世界坐标:除了归一化坐标,还能拿到以手几何中心为原点的米制 3D 坐标。
- 多手追踪:默认一次追踪 2 只手,双手交叉时也能各自维持身份。
- 跨平台同一套模型:palm 检测与 hand landmark 模型在 Python/JS/Android 间复用。
一张速查表先记重点(具体取值在后面「读懂输出」再讲):
| 能力 | 关键参数 | 默认值 |
|---|---|---|
| 关键点数量 | 固定 21 点 | — |
| 最大手数 | max_num_hands | 2 |
| 模型复杂度 | model_complexity(取 0 或 1) | 1 |
| 检测置信度 | min_detection_confidence | 0.5 |
| 追踪置信度 | min_tracking_confidence | 0.5 |
| 图像/视频模式 | static_image_mode | false |
五分钟跑通第一个 Demo
这一步解决「装好就能看效果」的问题。用官方 Python 包,模型已随包内置,不用单独下文件。
最快安装命令:
python3 -m venv mp_env && source mp_env/bin/activate pip install mediapipe最小可运行代码(详见 Python 安装文档):
import cv2 import mediapipe as mp hands = mp.solutions.hands.Hands( model_complexity=0, min_detection_confidence=0.5) draw = mp.solutions.drawing_utils cam = cv2.VideoCapture(0) while cam.isOpened(): ok, frame = cam.read() if not ok: break res = hands.process(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)) for hand in res.multi_hand_landmarks or []: draw.draw_landmarks(frame, hand, mp.solutions.hands.HAND_CONNECTIONS) cv2.imshow("hands", cv2.flip(frame, 1)) if cv2.waitKey(1) == 27: break cam.release()预期看到:摄像头画面被镜像显示,手上叠加 21 个关键点与连接线,移动手指时连线实时跟着走;按 ESC 退出。
读懂输出:21 个点怎么分组、参数怎么调
这一步解决「跑通了但不知道每个数代表什么」。
process返回三组结果,最常用的multi_hand_landmarks里,每只手是 21 个点,按下表分组:
| 编号 | 部位 |
|---|---|
| 0 | 手腕(wrist) |
| 1–4 | 拇指(4 为拇指指尖) |
| 5–8 | 食指(8 为食指指尖) |
| 9–12 | 中指 |
| 13–16 | 无名指 |
| 17–20 | 小指 |
坐标含义:x、y已按图宽高归一化到[0,1];z以手腕为原点,值越小表示越靠近相机。multi_hand_world_landmarks则是真实米制坐标,原点在手的几何中心。multi_handedness的score恒 ≥ 0.5,且左右手判定假定输入是自拍镜像图,显示时记得cv2.flip(frame,1),否则标签会反。
流水线内部只有两步,理解它你就不会瞎调参:
最常用参数取值建议:实时视频用static_image_mode=False,静态图批量处理才开True;求低延迟把model_complexity=0,要精度设1;min_detection_confidence与min_tracking_confidence都从 0.5 起步,别一上来调到 0.9 把能追上的手判丢了。模型源码见 hand_landmark 模块。
换平台接入:JS 与 Android 最小代码
这一步解决「Web 和 Android 上怎么接」,细节不再重复 Python 已讲的参数。
前端用 npm 包@mediapipe/hands,把模型文件放到本地assets目录即可:
const hands = new Hands({ locateFile: f => `./assets/${f}` }); hands.setOptions({ maxNumHands: 2, modelComplexity: 1, minDetectionConfidence: 0.5 }); hands.onResults(res => console.log(res.multiHandLandmarks));Android 在build.gradle加依赖,再用CameraInput喂帧(参考 android solutions 示例):
implementation 'com.google.mediapipe:solution-core:latest.release' implementation 'com.google.mediapipe:hands:latest.release'var opts = HandsOptions.builder() .setStaticImageMode(false).setMaxNumHands(2) .setRunOnGpu(true).build(); Hands hands = new Hands(this, opts); CameraInput cam = new CameraInput(this); cam.setNewFrameListener(f -> hands.send(f));高频翻车点自查表
这一步把最常见的坑压成一张表,照着对就行。
| 现象 | 常见原因 | 修复办法 |
|---|---|---|
| 手转个角度就丢 | 追踪置信度太低,频繁重新检测 | min_tracking_confidence=0.5 |
| 左右手标签反了 | 输入是自拍镜像,handedness 假定已镜像 | 显示前cv2.flip(frame, 1) |
| 帧率掉、内存涨 | 每帧都复制/可写 | image.flags.writeable = False |
| 远处小手检测不到 | 分辨率过高、手掌占比过小 | 摄像头降到约 640×480 |
| 静态图被当成视频重复检测 | static_image_mode设错 | 静态图设static_image_mode=True |
| 手指遮挡时抖动 | 模型复杂度低 | model_complexity=1 |
| 安卓 GPU 报错 | 设备不支持 GPU 管线 | setRunOnGpu(false)走 CPU |
性能与部署要点 ⚡
这一步给出上线前的清单与分档配置,帮你按设备定参数。
- 实时场景用
static_image_mode=False,静态图才开True - 低配设备把
model_complexity设为 0 - 两个置信度从 0.5 起步,逐步调高再观察
- 显示前镜像,保证左右手标签正确
- 高分辨率输入先降到约 640×480 再送进模型
官方文档提到该流水线在手机上可实时运行,且手掌检测平均精度达 95.7%。按设备分档的推荐配置如下(均为建议值,实际以你的设备实测为准):
| 设备档位 | model_complexity | 输入分辨率建议 | 置信度起步 |
|---|---|---|---|
| 低配 / 老手机 | 0 | 640×480 | 0.5 / 0.5 |
| 中端手机 | 0 或 1 | 640×480 | 0.5 / 0.5 |
| 桌面 / 旗舰 | 1 | 摄像头原生 | 0.5 / 0.5 |
桌面端可用 Bazel 构建现成目标,例如hand_tracking_tflite,见 桌面手部追踪构建。
继续深入 📌
想再往前走,这三条线值得看:
- 手势识别:在 gesture_recognizer 任务 上接分类器,把 21 个点直接变成握拳、张开、竖拇指等手势标签。
- 自定义手势训练:用仓库自带的 Model Maker 脚本,把自己的手势数据训成 TFLite 分类模型。
- 桌面 C++ 图:从 手部追踪图 入手,理解检测与追踪子图如何串成一张可自定义的 MediaPipe 计算图。
收尾
从单帧 21 点到跨平台落地,MediaPipe Hands 已经把手势交互最难的基础部分替你扛好了。现在就把它拉下来,跑通上面那段 17 行的 Python:
git clone https://gitcode.com/GitHub_Trending/med/mediapipe【免费下载链接】mediapipeCross-platform, customizable ML solutions for live and streaming media.项目地址: https://gitcode.com/GitHub_Trending/med/mediapipe
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考