拓冰建站拓冰建站
首页 / 资讯中心 / 正文

MediaPipe 手部追踪升级翻车实录:Hand Landmarker 迁移必改的 3 处代码 + 1 个隐藏默认值

MediaPipe 手部追踪升级翻车实录Hand Landmarker 迁移必改的 3 处代码 1 个隐藏默认值【免费下载链接】mediapipeCross-platform, customizable ML solutions for live and streaming media.项目地址: https://gitcode.com/GitHub_Trending/med/mediapipe把项目里的 MediaPipe 手部追踪升到新版后日志第一行就是ValueError: missing the model——旧的mp.solutions.hands.Hands之前一行没改都能跑换成新一代的 Hand Landmarker手部关键点检测任务后连创建都过不去。本文完整走一遍 MediaPipe 手部追踪从旧 Hands 接口迁到 Hand Landmarker 任务的路差异到底在哪、代码哪几行必须动、跑不动时怎么排查。旧接口在包里仍然共存、可以双轨并行所以迁移前完全可以拿一张图先做新旧对照。底层到底改了什么变化本质不是参数改名而是打包方式变了。旧 Hands 是个封闭盒子图、模型、参数一起编译成一个 binarypb 图文件随安装包分发构造时塞几个标量参数就行。新的 Hand Landmarker 是任务级接口内部图被拆成单只手关键点检测与手掌检测追踪循环等可组合子图见手部关键点子图定义模型被剥离成外部显式指定的资产包Python、Java、C 各平台则是对同一份 C 实现的封装——Java 端包名变成com.google.mediapipe.tasks.vision.handlandmarker命名变化是架构变化的直接体现。所以显式给模型、显式给模式不再是可选项而是接口契约。不改就跑不起来的地方旧 Hands 接口新 Hand Landmarker模型来源内置于 wheel自动加载必须显式传model_asset_path且要带元数据的.task资产包入口类mp.solutions.hands.Handsmediapipe.tasks.python.vision.HandLandmarker运行模式static_image_mode布尔开关running_modeIMAGE / VIDEO / LIVE_STREAM 三选一最大手数max_num_hands默认 2num_hands默认 1 ⚠️结果字段results.multi_hand_landmarksresult.hand_landmarks输入图片还是普通的照片新老接口的差别全在调用方式上而不是输入长什么样最小改动跑通新版先升级 SDK再注意模型文件的获取方式# 旧 solutions 接口与 tasks 接口并存升级后两边都能导入 pip install mediapipe --upgrade # 官方预训练的 hand_landmarker.taskfull 精度需从 MediaPipe 官方渠道 # 下载后放到脚本同目录仓库内 hand_landmark 模块只声明了 .tflite 文件名 # 权重并未入库裸 .tflite 也带不上 Tasks 接口需要的元数据下面用一张静态图做新旧对照。旧代码Handsimport cv2 import mediapipe as mp hands mp.solutions.hands.Hands( static_image_modeTrue, max_num_hands2, min_detection_confidence0.5) image cv2.imread(gesture.jpg) results hands.process(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)) for hand in results.multi_hand_landmarks or []: for p in hand.landmark: x int(p.x * image.shape[1]) y int(p.y * image.shape[0]) cv2.circle(image, (x, y), 4, (0, 255, 0), -1) cv2.imwrite(out_old.jpg, image)新代码Hand Landmarkerimport cv2 import mediapipe as mp from mediapipe.tasks import python from mediapipe.tasks.python import vision # 改动1模型必须显式给出且需是带 metadata 的 .task 资产包 options vision.HandLandmarkerOptions( base_optionspython.BaseOptions( model_asset_pathhand_landmarker.task), running_modevision.RunningMode.IMAGE, # 改动2布尔开关变三态模式 num_hands2, # 改动3新接口默认 1不传就只剩一只手 min_hand_detection_confidence0.5) image cv2.imread(gesture.jpg) with vision.HandLandmarker.create_from_options(options) as lm: # 改动4输入统一为 mp.Image且必须是 RGB mp_image mp.Image(image_formatmp.ImageFormat.SRGB, datacv2.cvtColor(image, cv2.COLOR_BGR2RGB)) result lm.detect(mp_image) for hand in result.hand_landmarks: # 改动5字段少了 multi_ 前缀 for p in hand: x int(p.x * image.shape[1]) y int(p.y * image.shape[0]) cv2.circle(image, (x, y), 4, (0, 255, 0), -1) cv2.imwrite(out_new.jpg, image)说白了必改的就上面这 5 行。改动 4 值得多说一句旧的process()直接吃 RGB 的 numpy 数组新接口把输入统一成mp.ImageBGR2RGB 转换得自己做——逻辑没变只是位置换了。还有一个隐性变化旧的model_complexity参数消失了它的作用被选哪个模型文件接管不再出现在代码里。跑不动时的 3 种典型症状1. 创建时报 missing the model模型路径或格式不对现象create_from_options直接抛ValueError报错信息指向模型。根因新任务默认不携带任何模型且只认带元数据的模型资产包.task裸.tflite缺少这份元数据hand_landmark 模块 里声明的模型文件名只是子图资源引用权重并不在仓库里。修复import os from mediapipe.tasks import python from mediapipe.tasks.python import vision model_path hand_landmarker.task # 官方渠道下载后放到脚本同目录 assert os.path.exists(model_path), f模型文件不存在: {model_path} options vision.HandLandmarkerOptions( base_optionspython.BaseOptions(model_asset_pathmodel_path)) with vision.HandLandmarker.create_from_options(options) as lm: print(创建成功模型元数据解析正常)2. 视频第二帧就报时间戳错误时间戳没有严格递增现象detect_for_video第一帧正常第二帧开始抛ValueError提示时间戳问题。根因新接口要求相邻两次调用的timestamp_ms严格单调递增而你传的值在多路摄像头切换、视频拖动 seek 或丢帧场景下发生了重置或重复。修复用帧序号换算毫秒时间戳从构造上保证单调fps 30.0 for idx, frame in enumerate(video_frames): # idx 从 0 严格递增 ts_ms int(idx * 1000 / fps) rgb cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) mp_image mp.Image(image_formatmp.ImageFormat.SRGB, datargb) lm.detect_for_video(mp_image, ts_ms)3. LIVE_STREAM 模式一个结果都收不到回调是必填项现象摄像头一直有帧进来回调函数却始终不触发甚至 create 阶段就已经报错。根因LIVE_STREAM 模式下result_callback是必填参数create_from_options里的 running mode 校验会直接拒绝缺回调的配置另外detect_async为压低延迟会在高负载时主动丢帧并非每帧都有输出属于设计内行为。修复import cv2 import mediapipe as mp from mediapipe.tasks import python from mediapipe.tasks.python import vision def on_result(result, mp_image, ts_ms): print(f{ts_ms}ms: 检测到 {len(result.hand_landmarks)} 只手) options vision.HandLandmarkerOptions( base_optionspython.BaseOptions( model_asset_pathhand_landmarker.task), running_modevision.RunningMode.LIVE_STREAM, result_callbackon_result) # LIVE_STREAM 必填缺了它结果无处可去 cap cv2.VideoCapture(0) ts_ms 0 with vision.HandLandmarker.create_from_options(options) as lm: while True: ok, frame cap.read() if not ok: break rgb cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) lm.detect_async(mp.Image(image_formatmp.ImageFormat.SRGB, datargb), ts_ms) ts_ms 33 # 模拟约 30fps保证严格递增 cap.release()参数怎么选 性能怎么压三个参数值得先钉死num_hands旧 Hands 默认 2新接口默认 1——这就是标题里那个隐藏默认值。双手场景忘了显式传现象是升级后手少了一半排查半天最后才发现是配置问题。min_hand_detection_confidence控制手掌检测器置信度对应旧min_detection_confidence。复杂背景和实时流取 0.5 起步出现幽灵手误检时逐级提到 0.7不建议直接拉到 0.9光线偏暗时会整手漏检。min_hand_presence_confidence新参数控制手部存在分数。实时场景 0.5 即可关键点在手出画或被遮挡时来回跳动的提到 0.7。min_tracking_confidence含义与旧参数一致直接沿用原值即可。模型与模式按场景选静态图单张 / 离线批处理RunningMode.IMAGEdetect()选 full 精度模型追求上限。解码后的视频流RunningMode.VIDEOdetect_for_video()传严格递增的毫秒时间戳。实时摄像头RunningMode.LIVE_STREAMdetect_async() 回调端到端延迟紧张时换 lite 模型并把输入缩到 640×480 再喂进去。换个角度看性能压降的主杠杆也变了旧版是model_complexity这个参数新版变成选哪个模型文件 输入分辨率调参空间外移到了部署层。迁移完成后想深入从 Hand Landmarker 的 Python 封装 入手最顺三个 detect 方法的行为差异在方法注释里写得最清楚旧接口参数细节可对照 docs/solutions/hands.md。下一步要训练自己的手势识别模型直接看mediapipe/model_maker/python/vision/gesture_recognizer/下的训练链路。【免费下载链接】mediapipeCross-platform, customizable ML solutions for live and streaming media.项目地址: https://gitcode.com/GitHub_Trending/med/mediapipe创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门