news 2026/9/4 8:03:05

MediaPipe手势识别:21点3D手部追踪怎么跑通

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
MediaPipe手势识别:21点3D手部追踪怎么跑通

MediaPipe手势识别:21点3D手部追踪怎么跑通

【免费下载链接】mediapipeCross-platform, customizable ML solutions for live and streaming media.项目地址: https://gitcode.com/GitHub_Trending/med/mediapipe

MediaPipe 是 Google 开源的端侧机器学习框架,支持 Android、iOS、桌面、Web 和边缘设备。它的手部追踪能力可以从单帧图像推断出 21 个 3D 手部关键点,在手机上就能实时运行。这篇文章讲清楚两件事:怎么用几行 Python 代码跑通摄像头实时追踪,以及 5 个配置参数各自的含义。

🖐️ 先搞懂管线:两个模型各管一段

手部追踪由两级模型串成。先说明为什么拆两段:单手检测很困难,手的尺寸跨度能到约 20 倍,又没有脸那样的高对比特征。所以第一段用手掌检测模型(palm detector)在全图上找一个带朝向的方框,只框住手掌这个刚性区域;第二段用关键点模型在裁剪出的小图块上直接回归 21 个 3D 坐标。

拆开的好处有两个。裁剪后输入是标准化的小图,训练时基本不需要旋转、平移、缩放这类数据增强,网络容量可以全部用来提升坐标精度。跟踪时优先用上一帧的关键点位置直接裁剪,只有关键点模型失效了才重新调用检测模型定位,大部分帧省掉了最贵的检测环节,这是延迟低的关键。

关键点布局固定为 21 个:0 是腕部,1-4 拇指,5-8 食指,9-12 中指,13-16 无名指,17-20 小指,每个指节的关节和指尖依次排列。

环境准备:装包与克隆仓库

Python 3.8 以上即可,装一个包就能用:

pip install mediapipe

想编译桌面 C++ 示例或看 Model Maker 的训练代码,再克隆仓库:

git clone https://gitcode.com/GitHub_Trending/med/mediapipe

仓库版本见 version.bzl,当前是 1.0.1。注意两点:mp.solutions.hands属于 Legacy Solutions(旧版 API),代码仓库按原样维护、不再新增功能;新方案是 MediaPipe Tasks 的 Hand Landmarker,本文示例以 Legacy API 为准,它仍是 Python 端最省事的入口。

三步跑通摄像头实时追踪

下面这段代码打开摄像头、追踪双手、画出手部骨架,Esc 键退出:

import cv2 import mediapipe as mp mp_drawing = mp.solutions.drawing_utils # 官方绘制工具 mp_drawing_styles = mp.solutions.drawing_styles cap = cv2.VideoCapture(0) with mp.solutions.hands.Hands( model_complexity=0, min_detection_confidence=0.5, min_tracking_confidence=0.5) as hands: while cap.isOpened(): ok, frame = cap.read() if not ok: continue frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) # 模型吃RGB result = hands.process(frame) if result.multi_hand_landmarks: for lm in result.multi_hand_landmarks: mp_drawing.draw_landmarks(frame, lm, mp.solutions.hands.HAND_CONNECTIONS) cv2.imshow('hands', cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)) if cv2.waitKey(5) & 0xFF == 27: break cap.release()

跑起来后能拿到的三组输出:

  • multi_hand_landmarks:x、y 已按图像宽高归一化到 [0,1],z 是深度,以手腕为原点,值越小离镜头越近,量级和 x 接近。
  • multi_hand_world_landmarks:真实世界 3D 坐标,单位是米,原点在手掌的几何中心附近。要量手指长短就用这组。
  • multi_handedness:左右手标签加置信分,分数不小于 0.5。

想要食指指尖的像素坐标,取 8 号点乘宽高即可:

tip = lm.landmark[mp.solutions.hands.HandLandmark.INDEX_FINGER_TIP] px, py = tip.x * frame_width, tip.y * frame_height

处理一批静态照片时加static_image_mode=True,并对每张图先cv2.flip(image, 1)水平翻转再送入,左右手标签才正确。

参数怎么调:5 个配置项逐个看

这 5 个参数就是全部配置,默认值都偏保守,按场景微调即可。

static_image_mode:默认false,按视频流处理,只在首帧和跟踪失败时跑检测。处理静态图片时设为true,每帧都跑检测。

max_num_hands:默认 2。要追踪第三只手,改这里;跑 C++ 桌面示例时,改的是图文件里ConstantSidePacketCalculator的选项。

model_complexity0是轻量模型,1是默认的高精度模型。准确率和延迟都随复杂度上升。摄像头实时场景从0开始,处理照片或视频文件时用1

min_detection_confidence:检测模型的阈值,默认 0.5。调低后更容易检出手,误检也会变多;手在画面里很小的时候尤其要调低。

min_tracking_confidence:跟踪模型的阈值,默认 0.5。低于它,下一帧自动触发重新检测。调高更稳、更费时间;静态图模式下无效。

Android 端对应HandsOptions,多了setRunOnGpu开关,示例代码在 mediapipe/examples/android/solutions/hands。iOS 端类似,看 mediapipe/examples/ios。桌面端用 Bazel 编译,离线视频示例:

bazel build -c opt --define MEDIAPIPE_DISABLE_GPU=1 \ //mediapipe/examples/desktop/hand_tracking:hand_tracking_tflite bazel-bin/mediapipe/examples/desktop/hand_tracking/hand_tracking_tflite \ --calculator_graph_config_file=mediapipe/graphs/hand_tracking/hand_tracking_desktop.pbtxt \ --input_side_packets=input_video_path=in.mp4,output_video_path=out.mp4

常见现象速查:手丢了、闪烁、左右反了

现象、原因、处理放在一张表里:

现象原因处理
手检测不到检测阈值过高,或手在画面里太小min_detection_confidence降到 0.3 左右,或提高输入分辨率
关键点闪烁、频繁重定位跟踪置信度要求高,频繁回退到检测调低min_tracking_confidence
左右手标签反了handedness 按镜像(前摄自拍)图判定送入前水平翻转图像,或在后摄场景手动交换标签
帧率不够模型复杂度或输入分辨率偏高model_complexity=0,摄像头分辨率降到 640x480 量级
z 值看着没物理意义z 是以手腕为原点的相对深度需要物理尺寸改用multi_hand_world_landmarks

官方文档里的一个数据供参考:手掌检测模型的平均精度为 95.7%(论文评估集口径),换用普通交叉熵损失训练只有 86.22%,可见 focal loss 对大尺度差异场景的作用。你自己的设备上能跑多少帧,以实测为准。

进阶:用 Model Maker 训练自己的手势分类器

关键点模型只输出 21 个坐标,"握拳"还是"剪刀手"这种业务分类要自己训一个。仓库里自带训练代码 gesture_recognizer 和示例数据 raw_data。数据按类别分文件夹存放,训练脚本会自动拆分数据集:

from mediapipe.model_maker.python.vision import gesture_recognizer data = gesture_recognizer.Dataset.from_folder(dirname='my_data') train_data, rest = data.split(0.8) val_data, test_data = rest.split(0.5) model = gesture_recognizer.GestureRecognizer.create( train_data=train_data, validation_data=val_data, options=gesture_recognizer.GestureRecognizerOptions( model_options=gesture_recognizer.GestureRecognizerModelOptions( dropout_rate=0.05, layer_widths=[300, 300]), hparams=gesture_recognizer.HParams(export_dir='./out'))) print(model.evaluate(test_data, batch_size=2)) model.export_model() # 导出 tflite,供推理端加载

layer_widths定义隐藏层宽度,每层之间接 BatchNorm、Dropout 和 ReLU,默认是不加隐藏层。导出的 tflite 拿到推理端,配合 Hand Landmarker 输出的关键点坐标做输入即可闭环。

下一步做什么

  • 把示例里的model_complexity从 0 改成 1,对比同一摄像头下的帧率差异,感受两档模型的取舍。
  • 用 raw_data 里现成的三类样本跑一遍上面的训练脚本,导出你的第一个手势分类模型。

【免费下载链接】mediapipeCross-platform, customizable ML solutions for live and streaming media.项目地址: https://gitcode.com/GitHub_Trending/med/mediapipe

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/4 8:35:42

STM32火灾报警系统全流程实战:从硬件设计到多传感器融合算法

简介:本资源是一套完整的基于STM32的火灾报警系统毕业设计/课程设计实战资料包,面向嵌入式初学者、电子信息类本科生及毕设开发者,解决从硬件选型、PCB设计到嵌入式软件开发与答辩全流程落地难题。压缩包含1445个文件,总大小56.55…

作者头像 李华
网站建设 2026/9/3 14:33:55

Android SDK Platform手动管理指南:从构建失败到离线安装实战

简介:本资源是Android 13(API级别36)官方平台SDK核心组件压缩包,面向Android应用开发者、移动开发学习者及需要适配最新系统特性的工程团队,用于构建、编译、调试和测试兼容Android 13的应用程序。压缩包共2000个文件&…

作者头像 李华
网站建设 2026/9/3 21:38:42

Vue 3与Spring Boot 3构建医院HR系统:架构设计与核心模块实现

简介:这是一套面向Java与前端开发者、高校计算机专业师生及医疗信息化项目实践者的医院人力资源管理系统完整源码,聚焦解决医院人事部门在招聘、考勤、薪酬、绩效、培训与离职等多环节的数字化管理需求。资源采用Vue3SpringBoot3前后端分离架构&#xff…

作者头像 李华
网站建设 2026/9/4 12:40:10

STM32F103驱动HC-SR04超声波测距:从硬件原理到软件滤波的实战优化

简介:本资源是基于STM32F103RCT6微控制器与HC-SR04超声波传感器实现高精度实时测距的完整嵌入式项目,面向嵌入式初学者、课程设计学生及智能硬件开发者,解决非接触式距离检测在机器人避障、智能家居与自动化场景中的基础应用问题。压缩包共77…

作者头像 李华
网站建设 2026/9/4 14:37:22

基于vn.py的量化策略二次开发:机器学习选股与回测实战指南

简介:这是一套面向计算机及相关专业(如人工智能、自动化、电子信息等)在校学生与初学者的量化交易实战项目资源,基于vn.py框架深度二次开发,完整覆盖选股策略设计、多因子回测验证与机器学习模型集成三大核心环节&…

作者头像 李华