news 2026/1/13 6:24:04

AI人体骨骼检测数据输出格式解析:JSON坐标提取实战教程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
AI人体骨骼检测数据输出格式解析:JSON坐标提取实战教程

AI人体骨骼检测数据输出格式解析:JSON坐标提取实战教程

1. 引言:AI 人体骨骼关键点检测的应用价值

随着计算机视觉技术的快速发展,人体姿态估计(Human Pose Estimation)已成为智能健身、动作捕捉、虚拟现实和安防监控等领域的核心技术之一。通过识别图像中人体关键关节的空间位置,系统可以理解人的姿态与行为,进而实现自动化分析。

在众多开源方案中,Google 推出的MediaPipe Pose模型凭借其高精度、低延迟和轻量化特性脱颖而出。它能够在普通 CPU 上实现实时推理,精准定位33 个 3D 骨骼关键点,包括面部轮廓、肩部、手肘、膝盖等重要关节点,并以直观的“火柴人”形式可视化骨架连接。

本文将围绕基于 MediaPipe 的本地化部署镜像,深入解析其输出的JSON 格式骨骼坐标数据结构,并通过实战代码演示如何从检测结果中提取关键点坐标,为后续的动作识别、姿态比对或动画驱动提供结构化数据支持。


2. MediaPipe Pose 模型输出结构详解

2.1 输出数据的本质:结构化 JSON 坐标流

当使用 MediaPipe Pose 进行人体骨骼检测后,系统不仅返回带有骨架绘制的图像,还会生成一个包含所有关节点三维坐标的JSON 数据对象。该数据是后续进行算法处理的核心输入源。

典型的输出 JSON 结构如下:

{ "landmarks": [ { "x": 0.456, "y": 0.321, "z": 0.012, "visibility": 0.98 }, ... ] }

其中: -landmarks是一个长度为 33 的数组,对应 33 个预定义的人体关键点。 - 每个关键点包含四个字段: -x,y:归一化的平面坐标(范围 0~1),相对于图像宽度和高度。 -z:深度信息(相对深度,无单位),用于表示肢体前后关系。 -visibility:可见性置信度(0~1),表示该点被遮挡的可能性。

📌注意x,y是归一化值,若要转换为像素坐标,需乘以图像的实际宽高。

2.2 关键点索引映射表(Landmark Index Map)

MediaPipe 定义了固定的 33 个关键点顺序,掌握这些索引对于提取特定部位(如左肩、右膝)至关重要。以下是部分常用关节点的索引对照:

索引关键点名称描述
0nose鼻子
1left_eye_inner左眼内角
2left_eye左眼球中心
3left_eye_outer左眼外角
4right_eye_inner右眼内角
5right_eye右眼球中心
6right_eye_outer右眼外角
7left_ear左耳
8right_ear右耳
9mouth_left嘴巴左侧
10mouth_right嘴巴右侧
11left_shoulder左肩
12right_shoulder右肩
13left_elbow左手肘
14right_elbow右手肘
15left_wrist左手腕
16right_wrist右手腕
17left_pinky左小指指尖
18right_pinky右小指指尖
19left_index左食指尖
20right_index右食指尖
21left_thumb左拇指尖
22right_thumb右拇指尖
23left_hip左髋关节
24right_hip右髋关节
25left_knee左膝盖
26right_knee右膝盖
27left_ankle左脚踝
28right_ankle右脚踝
29left_heel左脚后跟
30right_heel右脚后跟
31left_foot_index左脚大脚趾
32right_foot_index右脚大脚趾

💡 实践建议:可将此映射封装为 Python 字典,便于按名称访问关键点。


3. 实战:从 JSON 中提取骨骼坐标并可视化

3.1 环境准备与依赖安装

本教程假设你已成功运行基于 MediaPipe 的本地 WebUI 镜像,并可通过 HTTP 接口获取 JSON 输出。以下代码可在任意 Python 环境中执行,用于解析和处理返回的数据。

pip install numpy matplotlib opencv-python

3.2 完整代码示例:解析 JSON 并绘制关键点

import json import numpy as np import matplotlib.pyplot as plt from matplotlib.patches import Circle # 示例:模拟从 WebAPI 获取的 JSON 响应 response_json = ''' { "landmarks": [ {"x": 0.48, "y": 0.32, "z": 0.01, "visibility": 0.99}, {"x": 0.47, "y": 0.31, "z": 0.00, "visibility": 0.95}, {"x": 0.46, "y": 0.30, "z": 0.00, "visibility": 0.97}, {"x": 0.45, "y": 0.30, "z": 0.00, "visibility": 0.96}, {"x": 0.52, "y": 0.31, "z": 0.00, "visibility": 0.95}, {"x": 0.53, "y": 0.30, "z": 0.00, "visibility": 0.98}, {"x": 0.54, "y": 0.30, "z": 0.00, "visibility": 0.97}, {"x": 0.44, "y": 0.33, "z": 0.01, "visibility": 0.96}, {"x": 0.55, "y": 0.33, "z": 0.01, "visibility": 0.95}, {"x": 0.43, "y": 0.40, "z": 0.02, "visibility": 0.94}, {"x": 0.56, "y": 0.40, "z": 0.02, "visibility": 0.93}, {"x": 0.38, "y": 0.42, "z": 0.03, "visibility": 0.99}, {"x": 0.61, "y": 0.42, "z": 0.03, "visibility": 0.99}, {"x": 0.35, "y": 0.58, "z": 0.04, "visibility": 0.98}, {"x": 0.64, "y": 0.58, "z": 0.04, "visibility": 0.98}, {"x": 0.33, "y": 0.72, "z": 0.03, "visibility": 0.97}, {"x": 0.66, "y": 0.72, "z": 0.03, "visibility": 0.97}, {"x": 0.31, "y": 0.75, "z": 0.02, "visibility": 0.92}, {"x": 0.68, "y": 0.75, "z": 0.02, "visibility": 0.91}, {"x": 0.32, "y": 0.74, "z": 0.02, "visibility": 0.93}, {"x": 0.67, "y": 0.74, "z": 0.02, "visibility": 0.92}, {"x": 0.33, "y": 0.76, "z": 0.01, "visibility": 0.90}, {"x": 0.66, "y": 0.76, "z": 0.01, "visibility": 0.89}, {"x": 0.39, "y": 0.70, "z": 0.05, "visibility": 0.99}, {"x": 0.60, "y": 0.70, "z": 0.05, "visibility": 0.99}, {"x": 0.37, "y": 0.85, "z": 0.04, "visibility": 0.98}, {"x": 0.62, "y": 0.85, "z": 0.04, "visibility": 0.98}, {"x": 0.36, "y": 0.95, "z": 0.03, "visibility": 0.97}, {"x": 0.63, "y": 0.95, "z": 0.03, "visibility": 0.97}, {"x": 0.35, "y": 0.98, "z": 0.02, "visibility": 0.90}, {"x": 0.64, "y": 0.98, "z": 0.02, "visibility": 0.89}, {"x": 0.36, "y": 0.97, "z": 0.02, "visibility": 0.91}, {"x": 0.63, "y": 0.97, "z": 0.02, "visibility": 0.90} ] } ''' # 解析 JSON data = json.loads(response_json) landmarks = data['landmarks'] # 定义关键点名称映射(简化版) keypoint_names = { 0: 'nose', 11: 'left_shoulder', 12: 'right_shoulder', 13: 'left_elbow', 14: 'right_elbow', 15: 'left_wrist', 16: 'right_wrist', 23: 'left_hip', 24: 'right_hip', 25: 'left_knee', 26: 'right_knee', 27: 'left_ankle', 28: 'right_ankle' } # 提取指定关键点的 (x, y) 坐标(归一化 → 像素) image_width, image_height = 640, 480 # 假设输入图像尺寸 pixel_coords = {} for idx, point in enumerate(landmarks): if idx in keypoint_names: x_px = int(point['x'] * image_width) y_px = int(point['y'] * image_height) pixel_coords[keypoint_names[idx]] = (x_px, y_px) # 打印提取结果 print("✅ 提取的关键点像素坐标:") for name, coord in pixel_coords.items(): print(f" {name}: {coord}") # 可视化关键点 fig, ax = plt.subplots(figsize=(8, 6)) ax.set_xlim(0, image_width) ax.set_ylim(image_height, 0) # Y轴反向,匹配图像坐标系 ax.set_aspect('equal') ax.axis('off') # 绘制关键点 for name, (x, y) in pixel_coords.items(): circle = Circle((x, y), radius=5, color='red', fill=True) ax.add_patch(circle) ax.text(x + 10, y, name, fontsize=8, color='white', backgroundcolor='black') plt.title("Extracted Keypoints from MediaPipe JSON Output") plt.tight_layout() plt.show()

3.3 代码解析说明

  • 第1–10行:导入必要的库,包括matplotlib用于绘图。
  • 第13–130行:模拟从 WebUI 接口接收到的 JSON 响应数据。
  • 第133–135行:使用json.loads()解析字符串为 Python 字典。
  • 第138–150行:定义常用关键点名称映射,仅提取关注的 12 个核心关节。
  • 第153–160行:遍历landmarks数组,将归一化坐标(x, y)转换为像素坐标。
  • 第163–170行:打印提取结果,便于调试。
  • 第173–188行:使用matplotlib在空白画布上绘制红点和标签,模拟 WebUI 中的“红点+白线”效果。

提示:实际项目中,你可以将此逻辑封装为函数,接收 JSON 和图像尺寸作为参数,返回结构化坐标字典。


4. 实际应用中的优化建议

4.1 处理多人体检测场景

默认情况下,MediaPipe Pose 每次只检测画面中最显著的一人。若需支持多人,应切换至Pose Landmarker with Multi-Pose版本,其输出结构变为:

{ "landmarks": [ [ {"x": 0.45, "y": 0.32, ...}, // 第一个人的33个点 ... ], [ {"x": 0.75, "y": 0.38, ...}, // 第二个人的33个点 ... ] ] }

此时需外层循环遍历每个人,再内层提取关键点。

4.2 添加骨架连线逻辑

除了单独标记关节点,还可根据 MediaPipe 定义的连接规则绘制骨骼线。常见连接对例如下:

connections = [ (11, 13), (13, 15), # 左臂 (12, 14), (14, 16), # 右臂 (11, 23), (12, 24), # 躯干 (23, 25), (25, 27), # 左腿 (24, 26), (26, 28), # 右腿 ]

使用plt.plot()即可绘制线条。

4.3 过滤低置信度关键点

利用visibility字段过滤不可靠的检测结果:

if point['visibility'] < 0.5: continue # 忽略低置信度点

这在动作识别任务中尤为重要,避免误判。


5. 总结

本文系统解析了基于 Google MediaPipe Pose 模型的 AI 人体骨骼检测服务所输出的 JSON 数据格式,并通过完整 Python 实战代码展示了如何从原始响应中提取关键点坐标、转换为像素值并进行可视化。

我们重点掌握了以下内容: 1.JSON 输出结构landmarks数组包含 33 个关键点的归一化 3D 坐标与可见性。 2.坐标转换方法:将[0,1]范围的x/y映射到实际图像像素坐标。 3.关键点索引映射:通过索引快速定位肩、肘、膝等核心关节。 4.实用代码模板:提供了可直接复用的解析与绘图脚本。 5.工程优化建议:涵盖多人检测、骨架连线与置信度过滤等进阶技巧。

这套方法适用于任何基于 MediaPipe 的本地化部署项目,尤其适合需要将姿态数据接入自定义分析系统的开发者。


💡获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

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

ViGEmBus深度解析:从内核驱动到游戏兼容的完整技术指南

ViGEmBus深度解析&#xff1a;从内核驱动到游戏兼容的完整技术指南 【免费下载链接】ViGEmBus 项目地址: https://gitcode.com/gh_mirrors/vig/ViGEmBus ViGEmBus作为Windows内核级虚拟游戏控制器仿真框架&#xff0c;通过100%准确的设备模拟技术&#xff0c;从根本上解…

作者头像 李华
网站建设 2026/1/13 6:23:06

10分钟快速上手:Lucky Draw年会抽奖程序完整使用指南

10分钟快速上手&#xff1a;Lucky Draw年会抽奖程序完整使用指南 【免费下载链接】lucky-draw 年会抽奖程序 项目地址: https://gitcode.com/gh_mirrors/lu/lucky-draw 还在为年会抽奖环节发愁吗&#xff1f;Lucky Draw作为一款基于Vue.js的开源年会抽奖程序&#xff0c…

作者头像 李华
网站建设 2026/1/13 6:22:58

LeaguePrank英雄联盟段位修改工具:轻松定制你的游戏显示数据

LeaguePrank英雄联盟段位修改工具&#xff1a;轻松定制你的游戏显示数据 【免费下载链接】LeaguePrank 项目地址: https://gitcode.com/gh_mirrors/le/LeaguePrank LeaguePrank是一款专业的英雄联盟段位修改工具&#xff0c;通过LCU API接口实现游戏数据的个性化展示。…

作者头像 李华
网站建设 2026/1/13 6:22:54

MediaPipe姿态识别部署案例:智能镜子交互系统开发

MediaPipe姿态识别部署案例&#xff1a;智能镜子交互系统开发 1. 引言 1.1 业务场景描述 随着智能硬件与AI技术的深度融合&#xff0c;智能镜子正逐步从概念走向现实。这类设备广泛应用于健身指导、康复训练、虚拟试衣等场景&#xff0c;其核心能力之一是实时感知用户的身体…

作者头像 李华
网站建设 2026/1/13 6:22:00

新手必看:Scanner类常用方法避坑指南与最佳实践

新手必看&#xff1a;Scanner类常用方法避坑指南与最佳实践在Java学习的早期阶段&#xff0c;几乎每个初学者都会遇到这样一个问题&#xff1a;“为什么我刚输入完数字&#xff0c;名字就直接跳过了&#xff1f;”这个问题背后&#xff0c;藏着一个看似简单却暗藏玄机的工具——…

作者头像 李华
网站建设 2026/1/13 6:21:53

为什么MediaPipe部署总失败?本地化免API调用实战指南

为什么MediaPipe部署总失败&#xff1f;本地化免API调用实战指南 1. 引言&#xff1a;AI人体骨骼关键点检测的落地困境 在计算机视觉领域&#xff0c;人体姿态估计&#xff08;Human Pose Estimation&#xff09;是动作识别、健身指导、虚拟试衣和人机交互等应用的核心技术。…

作者头像 李华