news 2026/9/17 16:46:05

MMPose 3D 手部姿态估计 Demo 实战指南:从 top-down 脚本到 Inferencer 统一推理接口

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
MMPose 3D 手部姿态估计 Demo 实战指南:从 top-down 脚本到 Inferencer 统一推理接口

MMPose 3D 手部姿态估计 Demo 实战指南:从 top-down 脚本到 Inferencer 统一推理接口

【免费下载链接】mmposeOpenMMLab Pose Estimation Toolbox and Benchmark.项目地址: https://gitcode.com/GitHub_Trending/mm/mmpose

导读

本文是 MMPose 仓库中 demo/docs/en/3d_hand_demo.md 文档的完整实战化展开,围绕"如何在 MMPose 中运行 3D 手部姿态估计 Demo"这一主题,覆盖两条使用路径:基于hand3d_internet_demo.py的 top-down 单图/视频推理,以及基于inferencer_demo.py的统一推理接口。读完本文,你将掌握 3D 手部姿态估计 Demo 的全部命令行参数与运行方式,理解其背后的模型初始化、结果后处理(rebase 高度、左右手深度补偿、关键点旋转)与可视化流程,并能结合仓库源码定位每一步的实现细节。

背景:MMPose 中的 3D 手部姿态估计

MMPose 是 OpenMMLab 出品的姿态估计工具箱,其中hand_3d_keypoint系列任务专注于从单张 RGB 图像回归手部关节的三维坐标。本文关联文档涉及的推理模型是 InterNet(InterHand2.6M 数据集配套基线,论文出处见 configs/hand_3d_keypoint/internet/interhand3d/internet_interhand3d.md 中的 ECCV'2020 引用),其 ResNet-50 版本在 InterHand2.6M test 集上的指标(MPJPE-single 9.47mm、MPJPE-all 11.59mm、MRRPE 29.28mm、APh 0.99)记录在 configs/hand_3d_keypoint/internet/README.md。

3D 手部估计与 2D 姿态估计的关键差异在于:输出不仅是 42 个关键点(左右手各 21 个)的平面坐标,还包含深度(z 轴)、双手相对根节点深度(rel_root_depth)以及左右手分类(hand_type)。这些额外输出直接决定了 Demo 脚本中后处理与可视化逻辑的复杂度,也解释了为什么 3D 手部 Demo 需要专门的推理脚本与专门的 Inferencer。

方式一:使用hand3d_internet_demo.py进行 top-down 推理

脚本入口与基本用法

仓库提供了 demo/hand3d_internet_demo.py 这一 top-down 风格脚本:先由外部检测器(或直接给定 GT 检测框)提供手部包围框,再对每个手部区域裁剪、缩放后送入姿态模型回归 3D 关键点。文档给出的完整命令为:

python demo/hand3d_internet_demo.py \ ${MMPOSE_CONFIG_FILE} ${MMPOSE_CHECKPOINT_FILE} \ --input ${INPUT_FILE} \ --output-root ${OUTPUT_ROOT} \ [--save-predictions] \ [--gt-joints-file ${GT_JOINTS_FILE}]\ [--disable-rebase-keypoint] \ [--show] \ [--device ${GPU_ID or CPU}] \ [--kpt-thr ${KPT_THR}] \ [--show-kpt-idx] \ [--show-interval] \ [--radius ${RADIUS}] \ [--thickness ${THICKNESS}]

其中--gt-joints-file用于在给定 GT json 文件的前提下进行单图测试;--input支持图片、视频甚至webcam(摄像头)输入,脚本内部通过mimetypes.guess_type判断输入类型,见 demo/hand3d_internet_demo.py。

全部命令行参数详解

以下参数均以 demo/hand3d_internet_demo.py 中parse_args()的实现为准,包含默认值与作用:

参数默认值说明
config必填模型配置文件路径(位置参数)
checkpoint必填模型权重文件路径(位置参数)
--input''图片/视频/摄像头(webcam)输入路径,为空时脚本会直接assert报错
--output-root''可视化结果输出根目录;为空时默认不保存可视化图,且main()中会assert args.show or (args.output_root != '')
--save-predictionsFalse是否将预测结果以 JSON 形式保存到${output_root}/results_${输入名}.json(见 demo/hand3d_internet_demo.py)
--disable-rebase-keypointFalse是否禁用关键点高度"回正"(rebase)。默认开启 rebase,即将预测 3D 姿态的最低点的高度置为 0,使其"落地",便于可视化
--showFalse是否在弹窗中实时显示结果
--devicecpu推理设备,可传 GPU id(如0)或cpu
--kpt-thr0.3关键点可视化分数阈值,低于该分数的关键点不绘制
--show-kpt-idxFalse是否在可视化图中标注关键点的索引号
--show-interval0视频/摄像头逐帧显示时的间隔秒数
--radius3可视化时关键点圆点半径(会写入model.cfg.visualizer.radius
--thickness1可视化时骨骼连线粗细(会写入model.cfg.visualizer.line_width

完整示例:使用预训练 InterNet 模型推理单张图片

文档给出了一个可直接复制的示例命令,使用 InterNet ResNet-50 模型与测试样例图tests/data/interhand2.6m/image69148.jpg

python demo/hand3d_internet_demo.py \ configs/hand_3d_keypoint/internet/interhand3d/internet_res50_4xb16-20e_interhand3d-256x256.py \ https://download.openmmlab.com/mmpose/hand3d/internet/res50_intehand3dv1.0_all_256x256-42b7f2ac_20210702.pth \ --input tests/data/interhand2.6m/image69148.jpg \ --save-predictions \ --output-root vis_results

对应的模型配置文件为 configs/hand_3d_keypoint/internet/interhand3d/internet_res50_4xb16-20e_interhand3d-256x256.py,其核心结构如下:

  • codec:使用Hand3DHeatmap,输入尺寸 256×256,热图尺寸 64×64×64(深度方向 64 层),根节点热图尺寸 64,sigma=2.5max_bound=255
  • 模型TopdownPoseEstimator+ ResNet-50 backbone +InternetHeadInternetHead由三个子头构成(见配置中的keypoint_head_cfgroot_head_cfghand_type_head_cfg),分别预测 42 关键点的 3D 热图、根节点深度热图与左右手类型;
  • 优化与调度:Adam(lr=2e-4)、MultiStepLR(milestones=[15, 17],gamma=0.1),20 个 epoch;
  • 数据与评测:InterHand3D 数据集、训练时使用 GT 根节点深度(use_gt_root_depth=True),评测指标为InterHandMetric的 MPJPE / MRRPE / HandednessAcc。

运行成功后,可视化图会保存在vis_results目录,且因为传入了--save-predictions,预测结果 JSON 会被保存到vis_results/results_image69148.json。脚本完成时会通过print_log输出保存路径(见 demo/hand3d_internet_demo.py)。

3D 手部后处理逻辑:rebase、深度补偿与坐标旋转

hand3d_internet_demo.pyprocess_one_image()(demo/hand3d_internet_demo.py)集中体现了 3D 手部特有的后处理,理解它才能真正读懂输出结果:

  1. 相对根深度补偿keypoints[:, 21:, 2] += rel_root_depth,把模型预测的左右手相对根节点深度叠加到右手(索引 21 之后)关节的 z 坐标上,从而将两只手对齐到同一深度坐标系;
  2. 按手型缩放分数scores[:, :21] *= hand_type[:, [0]]scores[:, 21:] *= hand_type[:, [1]],用模型预测的左右手类型置信度门控两侧关键点的得分;若分数最大值超过 1,再统一除以 255 归一化;
  3. 坐标轴旋转:乘以旋转矩阵vis_R = [[1,0,0],[0,0,-1],[0,1,0]],把 z 轴对齐到"高度"方向,以便在 3D 视图(Pose3dLocalVisualizeraxis_azimuth=-115axis_limit=200axis_elev=15)中自然显示;
  4. rebase 高度回正:默认将 z 坐标整体平移,使置信度大于 0 的关键点中最低点的 z 值为 0("落地")。由于模型预测的是相对深度而非全局位置,这一步骤对可视化至关重要;若模型输出本身包含全局位置,可通过--disable-rebase-keypoint关闭。

值得说明的是,同样的后处理逻辑在 Inferencer 的Hand3DInferencer.forward()中几乎逐行复现(mmpose/apis/inferencers/hand3d_inferencer.py),因此两种方式产出的结果语义完全一致。

视频与摄像头输入

--input为视频路径或webcam时,脚本进入视频分支(demo/hand3d_internet_demo.py):

  • 逐帧调用process_one_image推理并可视化;
  • 若指定了--output-root,会以mp4v编码、25 FPS 创建cv2.VideoWriter输出视频(摄像头输入时输出文件自动加.mp4后缀);
  • 若指定--save-predictions,每帧的预测结果会以frame_id + instances的形式追加到列表,最终统一写入 JSON;
  • --show模式下按 ESC 键退出,并通过time.sleep(args.show_interval)控制播放节奏。

方式二:使用 Inferencer 统一推理接口

为什么用 Inferencer

相比手写脚本,MMPoseInferencer提供了统一推理界面:无需显式指定配置文件路径与权重路径,直接用模型别名(model alias)即可;输入格式更丰富(图片路径、视频路径、图片文件夹、摄像头);同时封装了预处理、前向、可视化、后处理四个阶段的关键字参数。其底层分发逻辑在 mmpose/apis/inferencers/mmpose_inferencer.py:当pose3d参数包含'hand3d'时,自动实例化Hand3DInferencer,否则实例化Pose3DInferencer

一条命令完成 3D 手部推理

文档给出的示例:

python demo/inferencer_demo.py tests/data/interhand2.6m/image29590.jpg --pose3d hand3d --vis-out-dir vis_results/hand3d

该命令的作用:

  • tests/data/interhand2.6m/image29590.jpg为输入图片;
  • --pose3d hand3d选择模型别名hand3d,权重会从 model metafile 自动加载;
  • --vis-out-dir vis_results/hand3d指定可视化结果输出目录。

更多可用参数(均定义在 demo/inferencer_demo.py):

参数默认值说明
--pose3d-weightsNone自定义 3D 模型权重路径,不指定时从 metafile 加载
--pose2d/--pose2d-weightsNone2D 姿态模型(非 hand3d 的 3D 推理链需要)
--det-model/--det-weights/--det-cat-idsNone/None/0手部检测器配置/权重/类别 id
--deviceNone推理设备,不指定时自动选择可用设备
--show-progressFalse推理时显示进度条
--showFalse弹窗显示结果
--draw-bboxFalse是否绘制包围框
--bbox-thr0.3检测框分数阈值
--nms-thr0.3检测框 NMS 的 IoU 阈值
--kpt-thr0.3关键点可视化阈值
--disable-rebase-keypointFalse同前文,禁用高度回正
--num-instances1每帧可视化的 3D 姿态数量,小于 0 时取第一帧检测到的实例数
--radius3关键点半径
--thickness1连线粗细
--vis-out-dir''可视化结果保存目录
--pred-out-dir''预测结果保存目录
--show-aliasFalse打印所有可用模型别名

在 Python 代码中调用 Inferencer

除了命令行,MMPoseInferencer也可以在 Python 中直接使用,例如:

from mmpose.apis.inferencers import MMPoseInferencer inferencer = MMPoseInferencer(pose3d='hand3d') for result in inferencer( 'tests/data/interhand2.6m/image29590.jpg', vis_out_dir='vis_results/hand3d', return_datasamples=True): # result 中同时包含 'visualization' 与 'predictions' 两个键 print(result['predictions'])

这一调用路径对应的实现细节:

  • MMPoseInferencer.__call__(mmpose/apis/inferencers/mmpose_inferencer.py)会先把vis_out_dir/pred_out_dir之外的 kwargs 按preprocess_kwargsforward_kwargsvisualize_kwargspostprocess_kwargs四类分发到对应阶段;
  • 输入为webcam时自动打开摄像头并将show置为True;输入为目录/视频时会切换为逐帧批处理;
  • Hand3DInferencer.preprocess_single(mmpose/apis/inferencers/hand3d_inferencer.py)在有检测器时对检测框执行分数过滤(bbox_thr)与 NMS(nms_thr),无检测框时退化为以整张图像为框;
  • 预测结果的保存由postprocess_kwargs['pred_out_dir']控制,支持return_datasample=True时返回PoseDataSample对象。

模型别名与权重加载

Hand3DInferencer的构造函数(mmpose/apis/inferencers/hand3d_inferencer.py)说明:model可以是模型别名(如'hand3d')、metafile 中的配置名或配置路径;weights不指定时从 metafile 自动加载。此外初始化时会执行revert_sync_batchnorm,并把数据集的dataset_meta写入 visualizer。运行python demo/inferencer_demo.py --show-alias可查看当前 scope 下所有可用别名。

两种方式的对比与选型建议

维度hand3d_internet_demo.pyinferencer_demo.py --pose3d hand3d
配置/权重指定必须显式给出 config 与 checkpoint 路径使用模型别名,自动从 metafile 加载
输入类型图片 / 视频 / webcam图片 / 视频 / 图片目录 / webcam,且支持 numpy 数组
检测框来源依赖 GT json 或外部检测结果可选内置检测器(--det-model)或整图回退
结果导出--save-predictions导出 JSON--pred-out-dir导出 JSON,支持return_datasample
可视化控制--radius/--thickness/--kpt-thr/--show-kpt-idx同名参数,另有--num-instances--skeleton-style
适用场景复现文档示例、深度调试单条推理链日常推理、批量处理、二次开发集成

两条路径共享同一套 3D 后处理(rebase、深度补偿、坐标旋转)与同一套Pose3dLocalVisualizer可视化参数(axis_azimuth=-115axis_limit=200axis_elev=15)。若只是快速验证效果或接入业务,推荐 Inferencer;若要细粒度控制每个阶段或配合 GT 框评测,推荐hand3d_internet_demo.py

测试验证:Inferencer 路径的行为保障

仓库测试 tests/test_apis/test_inferencers/test_hand3d_inferencer.py 从四个维度验证了 3D 手部 Inferencer 的行为:

  • 初始化Hand3DInferencer(model='hand3d')能正确加载出torch.nn.Module模型实例;
  • 单图调用:输入图片路径或 numpy 数组结果一致,predictions中包含keypoints,且每只手输出 42 个关键点(左右手各 21);
  • 目录批处理:输入目录时对目录下所有图片推理,可分别只保存可视化(vis_out_dir)或同时保存可视化与预测(out_dir,输出到visualizations/predictions/两个子目录);
  • 数据格式return_datasample=True时返回PoseDataSample

同时,tests/test_apis/test_inferencers/test_mmpose_inferencer.py 中的test_hand3d_call验证了MMPoseInferencer(pose3d='hand3d')这条完整链路的可用性。这些测试所使用的样例图片tests/data/interhand2.6m/image29590.jpg也正是本文 Inferencer 示例的输入,读者可以直接复现测试环境下的推理行为。

小结

本文完整展开了 demo/docs/en/3d_hand_demo.md 的两条 3D 手部推理路径:hand3d_internet_demo.py适合需要显式控制 config/checkpoint、配合 GT 框做单图验证的场合;inferencer_demo.py --pose3d hand3d则以模型别名 + 自动权重加载的方式,覆盖图片、目录、视频、摄像头等多种输入,适合快速验证与工程集成。无论走哪条路径,输出都经过同样的 3D 后处理(相对根深度补偿、手型分数门控、坐标旋转、高度 rebase),因此可视化与预测结果语义一致。建议读者结合 demo/hand3d_internet_demo.py、mmpose/apis/inferencers/hand3d_inferencer.py 与对应模型配置 configs/hand_3d_keypoint/internet/interhand3d/internet_res50_4xb16-20e_interhand3d-256x256.py 逐层阅读,以掌握从输入到可视化完整链路的底层原理。

【免费下载链接】mmposeOpenMMLab Pose Estimation Toolbox and Benchmark.项目地址: https://gitcode.com/GitHub_Trending/mm/mmpose

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

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

Open WebUI 连 AI 数据中心多模型,TaoToken 放在网关层

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/17 16:44:37

Copilot替代方案选型指南:免费与高性价比工具深度对比

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/17 16:44:37

需求调研报告模板编写指南:结构解析与python-docx自动化处理

简介:软件项目需求调研报告是软件开发前期的重要交付物,直接决定需求理解与项目规划的准确度。这份Word模板专为项目经理、需求分析师、开发与测试人员设计,可帮助团队快速建立规范化调研文档框架,避免遗漏关键信息。压缩包内含1个…

作者头像 李华
网站建设 2026/9/17 16:44:35

Vue.js keep-alive组件原理与性能优化实践

1. keep-alive 组件概述在 Vue.js 生态中,keep-alive 是一个极具实用价值的内置组件。作为一名长期使用 Vue 进行项目开发的前端工程师,我发现这个组件在实际业务场景中能显著提升应用性能。它的核心功能是缓存不活跃的组件实例,避免重复渲染…

作者头像 李华
网站建设 2026/9/17 16:44:00

OKR模板选型与落地:从O写法到信心指数的完整拆解

简介:二十种OKR(目标与关键结果)模板案例大全是一份面向企业管理者、人力资源及团队负责人的实操参考文档,聚焦目标与关键结果法的落地应用,帮助读者解决目标制定空泛、关键结果拆解不清等问题。文档仅含一个便携式PDF…

作者头像 李华