MediaPipe 手部追踪 API 迁移完整指南:从 Hands 到 Hand Landmarker 的 4 个关键问题
【免费下载链接】mediapipeCross-platform, customizable ML solutions for live and streaming media.项目地址: https://gitcode.com/GitHub_Trending/med/mediapipe
MediaPipe 从 0.9.0 版本起,把手部追踪能力从旧的mediapipe.solutions.hands方案整体迁到了新架构的 Hand Landmarker 任务上。对还在跑老版代码的人来说,这次升级不像文档里写的那样顺滑:模型不再内置、参数全部改名、运行方式也变了。这篇分享来自一次真实的迁移过程,按动手时踩到的四个问题逐个拆解,每个问题配了可以直接抄的写法。
问题一:模型文件去哪儿了
老版Hands的模型打包在 wheel 里,创建实例就能用。新版 Hand Landmarker 把模型加载的责任交给了开发者,不显式给路径就起不来。这一步的报错信息很直白,本质就一句话:你需要自己准备一个.tflite文件并塞进BaseOptions。
仓库里就有现成模型,位于 mediapipe/modules/hand_landmark/ 目录下,按精度分两档:
hand_landmark_full.tflite:高精度版,桌面端和精度敏感场景用它;hand_landmark_lite.tflite:轻量版,适合手机端这类资源受限环境。
环境准备一段搞定,模型从仓库里取:
pip install mediapipe --upgrade git clone https://gitcode.com/GitHub_Trending/med/mediapipe拿不准路径对不对时,先用os.path.exists断言一下,比对着报错日志猜快得多:
import os model_path = 'mediapipe/modules/hand_landmark/hand_landmark_full.tflite' assert os.path.exists(model_path), f"模型文件不存在: {model_path}"问题二:参数名对不上,逐个对照
第二个卡点是配置方式变了:老版用构造函数直接传参,新版要求先构造一个HandLandmarkerOptions对象。参数也不是简单改名,有几项被拆分或新增,逐个对照如下:
static_image_mode→running_mode。布尔开关升级成了三态枚举IMAGE/VIDEO/LIVE_STREAM,能表达的场景更多(详见下一节);max_num_hands→num_hands。语义不变,就是改个名;min_detection_confidence→min_hand_detection_confidence。这是手部检测器那一级的置信度门槛,拆分后职责更清晰;min_tracking_confidence→min_tracking_confidence。名字没变,含义是跟踪成功所需的最低分数;- 无对应项 →
min_hand_presence_confidence。全新参数,控制手部"存在"判定,默认值在 hand_landmarker.py 的HandLandmarkerOptions里可以查到。
问题三:三种运行模式怎么选
running_mode是新版最容易选错的参数,三种模式对应三种输入节奏:
IMAGE:一次一张静态图,处理完即走。HandLandmarkerOptions的默认值就是它;VIDEO:逐帧喂视频解码帧,必须传时间戳(timestamp_ms),结果同步返回;LIVE_STREAM:对接摄像头等实时流,要求设置result_callback回调异步收结果,创建时不传回调会直接校验失败。
迁移时按输入源对号入座:图片批处理用IMAGE,本地视频文件用VIDEO,在线流用LIVE_STREAM。老代码里的static_image_mode=False大致等价于VIDEO,True则对应IMAGE。
问题四:最小可运行示例长什么样
下面是一组新旧写法对照,老写法用来确认你要替换的对象,新写法是一个能独立跑起来的最小示例。
旧版 Hand Tracking:
import cv2 import mediapipe as mp mp_hands = mp.solutions.hands with mp_hands.Hands( static_image_mode=False, max_num_hands=2, min_detection_confidence=0.5) as hands: results = hands.process(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)) if results.multi_hand_landmarks: for hand_landmarks in results.multi_hand_landmarks: mp.solutions.drawing_utils.draw_landmarks( image, hand_landmarks, mp_hands.HAND_CONNECTIONS)新版 Hand Landmarker:
import cv2 import mediapipe as mp from mediapipe.tasks import python from mediapipe.tasks.python import vision base_options = python.BaseOptions( model_asset_path='mediapipe/modules/hand_landmark/hand_landmark_full.tflite') options = vision.HandLandmarkerOptions( base_options=base_options, running_mode=vision.RunningMode.VIDEO, num_hands=2, min_hand_detection_confidence=0.5) with vision.HandLandmarker.create_from_options(options) as landmarker: mp_image = mp.Image(image_format=mp.ImageFormat.SRGB, data=image) results = landmarker.detect_for_video(mp_image, timestamp_ms=100) for hand_landmarks in results.hand_landmarks: for landmark in hand_landmarks: x = int(landmark.x * image.shape[1]) y = int(landmark.y * image.shape[0]) cv2.circle(image, (x, y), 5, (0, 255, 0), -1)两个细节值得留意:一是新版的坐标是归一化的,画点前要手动乘回像素尺寸;二是实时流场景下把running_mode换成LIVE_STREAM,用detector.detect_async(mp_image, timestamp)替代同步调用,并在HandLandmarkerOptions里挂上result_callback即可。
收尾:迁移完成后的检查清单
改完别急着合代码,过一遍这几项再交付:
- MediaPipe 版本已升到 0.9.0 及以上,
pip show mediapipe确认; - 模型文件路径存在,且
full/lite选对了档位; - 输入是图片、视频帧还是实时流,
running_mode与之匹配; - 老代码里用到的每个阈值(检测、跟踪、存在性)都已在新选项中找到对应项,特别是新增的
min_hand_presence_confidence; - 归一化坐标已按图像宽高还原成像素坐标;
- 用同一段测试视频对比新旧两版的关键点输出,抖动和丢帧情况可接受。
如果后续要继续深入,可以翻一下 docs/solutions/hands.md 里对掌心检测 + 关键点预测这条两级流水线的描述,理解跟踪策略后,调参就不会只靠试错了。
【免费下载链接】mediapipeCross-platform, customizable ML solutions for live and streaming media.项目地址: https://gitcode.com/GitHub_Trending/med/mediapipe
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考