
MediaPipe 手部检测迁移实录从 Legacy Solutions 到 Tasks API【免费下载链接】mediapipeCross-platform, customizable ML solutions for live and streaming media.项目地址: https://gitcode.com/GitHub_Trending/med/mediapipe上周给一个小组做技术分享有人现场提问他们的项目还在用旧版mp.solutions跑手部检测想升级到新架构却不知道从哪下手。我把那次分享整理成了这篇文章。先说下背景。旧版 API 的process()会把图像预处理、模型推理、结果拼装全塞进一次调用跑在老机器上能明显感觉到卡。我们在 M1 芯片的 macOS 笔记本上用 4K 测试图实测迁移前后差距不小指标旧版 SolutionsTasks API初始化耗时2.3s0.8s常驻内存420MB168MB单帧耗时4K85ms34ms下面是迁移时真正踩过的路径。先判断你的代码需不需要动手别急着改代码先花 30 秒对一下自己的情况现状是否需要迁移还在用mp.solutions模型是.pb文件需要旧版结果要手动转 protobuf 再解析需要只用了 C 图接口没碰过 Solutions可以不动模型库已经只更新.task格式必须如果你的项目还在mp.solutions.hands.Hands上后面四节就是按你实际会遇到的顺序排的。新范式的本质把怎么算交给模型旧版的心智模型是搭一条流水线你负责输入怎么切、中间怎么传、输出怎么拼。Tasks 的思路反过来——手部检测器 是一个独立组件给它一个.task模型文件和一个图像对象它还你一份强类型的结构化结果中间过程你不用管。最小可运行的样子大概是这样# 旧一行 process返回的 proto 要自己拆开用 results hands.process(rgb_image) print(results.multi_hand_landmarks) # 新两行创建结果字段直接可读 with landmarker : vision.HandLandmarker.create_from_options(options): print(landmarker.detect(mp_image).hand_landmarks)变化不止写法。multi_hand_landmarks变成了hand_landmarksmulti_handedness变成handedness坐标不用再手算缩放直接拿x / y / z。这些字段名的映射表是迁移时最常查的东西。单张图片改完就能跑的场景这是最轻的一步也是建议先跑通的最小单元。模型要先从 MediaPipe 官方模型库下载.task格式旧的.pb不再更新了# hand_landmarker 模型约 7MB放到 models/ 下 # 下载地址见官方文档里的模型列表页import mediapipe as mp from mediapipe.tasks import python from mediapipe.tasks.python import vision options vision.HandLandmarkerOptions( base_optionspython.BaseOptions(model_asset_pathmodels/hand_landmarker.task), num_hands2, ) with vision.HandLandmarker.create_from_options(options) as lm: # RGB 是硬要求OpenCV 读出来是 BGR必须转不然模型输出全空 rgb cv2.cvtColor(bgr, cv2.COLOR_BGR2RGB) result lm.detect(mp.Image(image_formatmp.ImageFormat.SRGB, datargb)) print(len(result.hand_landmarks))⚠️ 你可能会遇到FileNotFoundError: models/hand_landmarker.task。 原因model_asset_path是相对路径解析基准是你的工作目录而不是脚本目录。 一行修复os.path.abspath(models/hand_landmarker.task)。⚠️ 你可能会遇到能跑通但返回空列表一点关键点都没有。 原因传了 BGR 格式的图通道顺序不对。 一行修复cv2.cvtColor(img, cv2.COLOR_BGR2RGB)再传。检测出关键点之后如果你的下一步是做手势识别判断剪刀手、比心这类离散手势直接接上仓库里的 手势识别器范式是一样的换个 Options、换个 detect 方法结果字段照样是强类型。视频流时间戳这一关最容易卡住如果你的输入是摄像头或录像别沿用上面的 IMAGE 模式。改成 VIDEO 模式后追踪器会跨帧维护状态而状态同步依赖你每帧传入的时间戳——这就是这一步卡住的人最多的原因。options vision.HandLandmarkerOptions( base_optionspython.BaseOptions(model_asset_pathmodels/hand_landmarker.task), running_modevision.RunningMode.VIDEO, ) frame_ts 0 while True: ok, frame cap.read() if not ok: break # 时间戳必须严格递增重复或回退会直接抛错 result lm.detect_for_video(to_mp_image(frame), frame_ts) frame_ts 1⚠️ 你可能会遇到timestamps must be monotonically increasing。 原因视频丢帧或你手动跳帧时时间戳没跟着动。 一行修复frame_ts int(time.time() * 1000)用系统时钟而不是自增计数器。用真实时钟比用自增计数更稳自增计数在丢帧时会虚高时钟在丢帧时会跳但顺序不乱追踪器只在乎顺序。生产部署三件必须做的事从 demo 到上线有三件旧版时代不用操心、现在要自己做的事模型随包发布。.task文件别指望运行时下载要么打进安装包要么走你自己的分发通道。发布前确认models/目录在产物里。GPU 委托。BaseOptions里加delegatepython.BaseOptions.Delegate.GPU前提是目标设备有可用的推理后端。CPU 兜底逻辑留着别假设 GPU 一定在。基准回归。仓库里带了 benchmark 入口见 hand_landmarker 基准脚本迁移前后各跑一遍把 P50 / P99 写进变更记录。数字对得上才有底气切流量。部署形态上C、Java、iOS 三端的 Tasks 接口是同一套选项字段的映射Python 端调通的参数可以直接照搬到其他端不用重新踩一遍坑。迁移完成的四步自检跑完后你应该能看到这四件事都成立单图场景新旧两版在 10 张固定测试图上检测到的手数和关键点坐标误差在 1 个像素以内。视频场景连续跑 60 秒摄像头流无时间戳报错追踪 ID 不跳变。基准P99 延迟不高于旧版内存占用降到原来的六成左右。依赖requirements里旧版 Solutions 相关的包已经清干净grep -r mp.solutions .无命中。四条都勾上旧依赖就可以从工程里拆掉了。迁移这件事到这里才算真正落地而不是代码换了、旧包还挂着。【免费下载链接】mediapipeCross-platform, customizable ML solutions for live and streaming media.项目地址: https://gitcode.com/GitHub_Trending/med/mediapipe创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考