讲师中心 微信公众号
AI工具推荐 视频效率加速

2D人体姿态关键点数据处理:JSON格式解析与模型适配策略

千瑶吖_3508

千瑶吖_3508

发布时间:2025-11-19 14:59:36

|

701人浏览过

|

来源于php中文网

原创

2d人体姿态关键点数据处理:json格式解析与模型适配策略

本文探讨了在2D人体姿态估计中,如何处理和适配特定JSON格式的关键点数据。针对用户自定义的`[x, y, confidence]`扁平化列表格式,文章指出直接寻找原生输出此格式的模型存在挑战。核心策略是理解现有数据结构,并根据目标姿态估计模型的输入要求进行数据重格式化。教程将提供JSON解析示例,并讨论关键点顺序、坐标归一化等重格式化要点,旨在帮助开发者高效地将自定义数据应用于主流姿态估计框架。

在2D人体姿态估计任务中,获取图像中人物的关键点坐标是核心目标。开发者常会遇到现有关键点数据(无论是标注数据还是其他模型输出)采用特定JSON格式,而主流姿态估计模型(如YOLOv8-pose、OpenPose、MediaPipe等)通常有其预定义的输入或输出格式。本文将针对类似以下示例的JSON格式数据,探讨如何进行解析、理解,并提出将其适配到主流姿态估计模型的方法。

理解自定义关键点JSON格式

我们首先分析提供的JSON数据结构。该格式将人体关键点表示为一个扁平化的列表,其中每个关键点由三个浮点数组成:[x坐标, y坐标, 置信度]。

{
  "version": 1.0,
  "people": [
    {
      "face_keypoints": [],
      "pose_keypoints": [
        104.81, 34.44, 0.91, // Keypoint 1 (x, y, confidence)
        83.90, 80.05, 0.72, // Keypoint 2
        // ... more keypoints ...
        0, 0, 0,            // Missing or undetected keypoint
        93.98, 28.16, 0.93  // Last keypoint
      ],
      "hand_right_keypoints": [],
      "hand_left_keypoints": []
    }
  ]
}

在这个结构中:

  • version: 版本信息。
  • people: 一个列表,每个元素代表检测到的一个人。
  • pose_keypoints: 包含人体姿态关键点的列表。这是一个扁平化的数组,每三个元素构成一个关键点 (x, y, confidence)。如果某个关键点未被检测到,其坐标和置信度可能为 0, 0, 0。
  • face_keypoints, hand_right_keypoints, hand_left_keypoints: 同样用于存储面部和手部关键点,在本例中为空。

这种扁平化列表的格式在某些场景下(例如OpenPose的早期输出或自定义数据集)较为常见,但其关键点的具体语义(例如第一个三元组代表鼻子,第二个代表左眼等)需要额外的映射表来定义。

直接寻找原生输出模型的挑战

开发者常常希望找到一个模型能够直接输出与其现有数据完全匹配的JSON格式。然而,这在实践中往往是困难的。

  1. 标准化差异: 不同的姿态估计模型和数据集(如COCO、MPII)定义了不同的关键点集合和顺序。例如,COCO数据集定义了17个关键点,而OpenPose可能定义了25个。
  2. 输出结构多样性: 模型的输出格式多种多样,可能是原始的张量、特定API对象、或者不同结构的JSON/CSV文件。直接匹配到 [x, y, confidence] 的扁平化列表并非通用标准。
  3. 后处理: 大多数模型在推理后都会进行后处理,将原始模型输出转换为更易读或标准化的格式。即使模型内部生成了类似的数据,最终暴露给用户的API输出也可能不同。

因此,与其寻找一个原生输出完全匹配的模型,更实际的方法是采用数据重格式化策略。

策略:数据重格式化以适配模型

核心思想是:将现有自定义格式的关键点数据,转换为目标姿态估计模型所要求的输入格式,或者在模型输出后,将其结果转换为期望的自定义格式。

Python Testing
Python Testing

Python 测试速查:运行 pytest、使用 mock/patch、参数化、fixtures、异步、覆盖率测试。

下载

1. 解析自定义JSON数据

首先,我们需要编写Python代码来解析上述自定义JSON格式,将其转换为更易于处理的结构,例如一个包含 (x, y, confidence) 元组的列表。

import json

def parse_custom_keypoints_json(json_data_str):
    """
    解析自定义JSON字符串,提取人体姿态关键点。
    """
    data = json.loads(json_data_str)
    people_keypoints_list = []

    for person_data in data.get("people", []):
        pose_keypoints_flat = person_data.get("pose_keypoints", [])

        # 将扁平化列表转换为 (x, y, confidence) 元组列表
        keypoints = []
        for i in range(0, len(pose_keypoints_flat), 3):
            if i + 2 < len(pose_keypoints_flat):
                x = pose_keypoints_flat[i]
                y = pose_keypoints_flat[i+1]
                confidence = pose_keypoints_flat[i+2]
                keypoints.append((x, y, confidence))
        people_keypoints_list.append(keypoints)

    return people_keypoints_list

# 示例JSON数据(来自问题内容)
example_json_str = """
{"version": 1.0, "people": [{"face_keypoints": [], "pose_keypoints": [104.818897637795, 34.4436363636364, 0.915185123682022, 83.9055118110236, 80.0581818181818, 0.723944239318371, 42.5826771653543, 79.8254545454545, 0.618412546813488, 34.7716535433071, 142.661818181818, 0.757904663681984, 31.244094488189, 204.8, 0.52992781996727, 122.456692913386, 81.2218181818182, 0.589333228766918, 125.48031496063, 145.92, 0.702833116054535, 131.527559055118, 192, 0.366538248956203, 58.7086614173228, 193.861818181818, 0.298667620576452, 0, 0, 0, 0, 0, 0, 107.842519685039, 196.421818181818, 0.324830377765466, 0, 0, 0, 0, 0, 0, 93.9842519685039, 28.16, 0.932040095329285, 107.086614173228, 26.9963636363636, 0.939965099096298, 71.3070866141732, 32.5818181818182, 0.885046675801277, 0, 0, 0], "hand_right_keypoints": [], "hand_left_keypoints": []}]} 
"""

parsed_keypoints = parse_custom_keypoints_json(example_json_str)
# print(parsed_keypoints) # 输出解析后的关键点列表

这段代码将原始的扁平化列表转换为更结构化的关键点列表,每个关键点是一个 (x, y, confidence) 元组。

2. 目标模型的数据格式要求

以Ultralytics YOLOv8-pose为例,其姿态估计任务的标注格式通常是文本文件(.txt),每行代表一张图片中的一个目标,格式如下: class_id bbox_x_center bbox_y_center bbox_width bbox_height keypoint1_x keypoint1_y keypoint1_visibility keypoint2_x keypoint2_y keypoint2_visibility ...

其中:

  • 所有坐标(bbox和keypoint)都必须是相对于图像宽度和高度的归一化值(0到1之间)。
  • visibility(可见性)通常是0(未标注)、1(遮挡但可见)、2(可见)。在推理场景下,这通常被替换为置信度或直接省略。
  • 关键点的顺序必须与模型训练时使用的顺序一致(例如COCO关键点顺序)。

这意味着,如果您想使用现有数据训练YOLOv8-pose,或者将YOLOv8-pose的输出转换为您的格式,您需要进行以下转换:

  • 关键点顺序映射: 将您的自定义关键点顺序映射到目标模型(如COCO)的关键点顺序。这通常需要一个预定义的映射表。
  • 坐标归一化: 将绝对像素坐标 (x, y) 转换为相对于图像尺寸的归一化坐标 (x_norm, y_norm)。 x_norm = x / image_widthy_norm = y / image_height
  • 边界框信息: 如果目标模型需要,您可能需要从关键点估算或从其他来源获取每个人的边界框 (bbox_x_center, bbox_y_center, bbox_width, bbox_height)。
  • 置信度/可见性: 根据目标模型的具体要求处理关键点的置信度。

3. 示例:将解析数据适配到YOLOv8-pose(概念性)

假设我们已经解析了自定义JSON数据,并获得了 keypoints = [(x1, y1, c1), (x2, y2, c2), ...]。现在我们将其转换为YOLOv8-pose所需的格式。

def reformat_for_yolov8_pose(parsed_keypoints_list, image_width, image_height, coco_keypoint_map):
    """
    将解析后的关键点数据转换为YOLOv8-pose兼容的格式。
    此函数仅为概念性示例,需要根据实际情况进行完善。

    Args:
        parsed_keypoints_list: parse_custom_keypoints_json 的输出。
        image_width: 原始图像宽度。
        image_height: 原始图像高度。
        coco_keypoint_map: 一个字典,将自定义关键点索引映射到COCO关键点索引。
                           例如:{custom_idx: coco_idx, ...}
    Returns:
        一个列表,包含每个人的YOLOv8-pose格式字符串。
    """
    yolov8_labels = []

    for person_keypoints in parsed_keypoints_list:
        # 1. 估算边界框 (这里简化处理,实际可能需要更精确的算法)
        # 排除 (0,0,0) 的关键点来估算边界框
        valid_keypoints = [(x, y) for x, y, c in person_keypoints if c > 0]
        if not valid_keypoints:
            continue # 没有有效关键点,跳过此人

        min_x = min(kp[0] for kp in valid_keypoints)
        max_x = max(kp[0] for kp in valid_keypoints)
        min_y = min(kp[1] for kp in valid_keypoints)
        max_y = max(kp[1] for kp in valid_keypoints)

        bbox_width = (max_x - min_x) / image_width
        bbox_height = (max_y - min_y) / image_height
        bbox_x_center = ((min_x + max_x) / 2) / image_width
        bbox_y_center = ((min_y + max_y) / 2) / image_height

        # 2. 准备关键点列表并进行归一化和排序
        # 假设我们有25个关键点,且已知道它们的COCO映射
        # 这里需要一个更复杂的映射逻辑,将原始关键点与COCO 17个关键点对应
        # 简化为直接使用原始关键点,并假设其顺序与某个标准匹配

        # 填充COCO 17个关键点,如果原始数据有更多,需要选择性映射
        # 如果原始数据有25个关键点,需要根据COCO的17个关键点进行筛选和排序
        # 示例中假设 person_keypoints 的顺序与COCO关键点大致对应或可映射

        # 为了演示,我们假设自定义数据的前17个关键点与COCO顺序一致
        # 实际应用中,需要根据具体的关键点定义进行精确映射

        keypoints_formatted = []
        for i in range(17): # 假设目标是COCO 17个关键点
            if i < len(person_keypoints):
                x, y, c = person_keypoints[i]
                x_norm = x / image_width
                y_norm = y / image_height
                # YOLOv8-pose通常使用0/1/2表示可见性,这里简化为0或1
                visibility = 1 if c > 0 else 0 
                keypoints_formatted.extend([x_norm, y_norm, visibility])
            else:
                # 如果自定义数据关键点不足17个,则填充0
                keypoints_formatted.extend([0.0, 0.0, 0])

        # 3. 组合成YOLOv8-pose的标签行
        # class_id 0 通常代表 "person"
        label_line = f"0 {bbox_x_center:.6f} {bbox_y_center:.6f} {bbox_width:.6f} {bbox_height:.6f}"
        label_line += " " + " ".join([f"{val:.6f}" for val in keypoints_formatted])
        yolov8_labels.append(label_line)

    return yolov8_labels

# 假设图像尺寸和COCO关键点映射(需要根据实际情况定义)
# 这是一个简化的映射示例,实际需要根据您的自定义关键点和COCO关键点对应关系来构建
# 例如:{0: 0, 1: 1, ... 16: 16} 假设前17个关键点直接对应COCO
coco_keypoint_mapping_example = {i: i for i in range(17)} 
image_w, image_h = 640, 480 # 假设图像尺寸

# 转换数据
yolov8_formatted_labels = reformat_for_yolov8_pose(parsed_keypoints, image_w, image_h, coco_keypoint_mapping_example)
# for label in yolov8_formatted_labels:
#     print(label)

注意事项:

  • 关键点语义和顺序: 最关键的一步是理解您的自定义JSON中每个 (x, y, confidence) 三元组代表哪个身体部位,并将其与目标模型(如COCO)所定义的关键点进行精确映射。如果关键点数量不一致,需要进行增删和排序。
  • 坐标归一化: 几乎所有现代深度学习模型都要求输入坐标是归一化的。
  • 边界框: 许多姿态估计模型(特别是基于检测的模型,如YOLOv8-pose)需要边界框信息。如果您的原始数据中没有,您需要从关键点中估算。
  • 可见性/置信度: 目标模型可能对关键点的可见性或置信度有特定的编码要求。

选择和适配姿态估计模型

在完成数据重格式化后,您可以选择适合您需求的姿态估计模型:

  1. YOLOv8-pose: Ultralytics YOLOv8系列提供了姿态估计功能。它易于使用,性能良好,并且有详细的文档说明如何准备数据集。
  2. OpenPose:

热门AI工具

更多
UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

AionClaw
AionClaw Hot

AionClaw是一款面向办公、创作和编程任务的AI桌面智能体。

蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

1995

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

2782

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

956

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

3139

2025.09.10

treenode的用法
treenode的用法

​在计算机编程领域,TreeNode是一种常见的数据结构,通常用于构建树形结构。在不同的编程语言中,TreeNode可能有不同的实现方式和用法,通常用于表示树的节点信息。更多关于treenode相关问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2241

2023.12.01

C++ 高效算法与数据结构
C++ 高效算法与数据结构

本专题讲解 C++ 中常用算法与数据结构的实现与优化,涵盖排序算法(快速排序、归并排序)、查找算法、图算法、动态规划、贪心算法等,并结合实际案例分析如何选择最优算法来提高程序效率。通过深入理解数据结构(链表、树、堆、哈希表等),帮助开发者提升 在复杂应用中的算法设计与性能优化能力。

316

2025.12.22

深入理解算法:高效算法与数据结构专题
深入理解算法:高效算法与数据结构专题

本专题专注于算法与数据结构的核心概念,适合想深入理解并提升编程能力的开发者。专题内容包括常见数据结构的实现与应用,如数组、链表、栈、队列、哈希表、树、图等;以及高效的排序算法、搜索算法、动态规划等经典算法。通过详细的讲解与复杂度分析,帮助开发者不仅能熟练运用这些基础知识,还能在实际编程中优化性能,提高代码的执行效率。本专题适合准备面试的开发者,也适合希望提高算法思维的编程爱好者。

357

2026.01.06

C++ 数据结构与算法实现教程合集
C++ 数据结构与算法实现教程合集

以 C++ 为实现语言,系统讲解核心数据结构与算法,涵盖链表(单链表/双链表/环检测)、栈与队列(单调栈/优先队列)、二叉树(遍历/BST/AVL/红黑树)、哈希表(开地址法/链地址法)、图(邻接表/BFS/DFS/Dijkstra/拓扑排序)、常见排序算法(快排/归并/堆排/计数排序)的实现与复杂度分析,同时分享 LeetCode 刷题技巧、竞赛编程常用模板(二分/前缀和/滑动窗口/动态规划),帮助开发者夯实算法基础。

412

2026.05.09

LLVM自定义Pass怎么写
LLVM自定义Pass怎么写

本专题聚焦LLVM自定义Pass开发,整理Pass类结构、run()方法、PreservedAnalyses、CMake构建、插件注册、-load-pass-plugin加载和测试用例编写流程。

0

2026.09.30

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn