首页
/ Label Studio 关键点标注数据转换为 YOLO 格式的完整指南

Label Studio 关键点标注数据转换为 YOLO 格式的完整指南

2025-05-10 21:43:57作者:薛曦旖Francesca

前言

在计算机视觉领域,关键点检测是一项重要的任务,广泛应用于姿态估计、目标跟踪等场景。Label Studio 作为一款流行的数据标注工具,提供了灵活的关键点标注功能。本文将详细介绍如何将 Label Studio 中的关键点标注数据转换为 YOLO 格式,以便用于 YOLOv8 等模型的训练。

关键点标注数据格式对比

Label Studio 格式特点

Label Studio 的关键点标注数据通常包含以下特征:

  1. 使用 JSON 格式存储标注信息
  2. 关键点坐标以百分比形式表示(0-100%)
  3. 每个关键点可以关联到特定的边界框(通过 parentID 或 relation)
  4. 支持为关键点定义不同的标签类别

YOLO 关键点格式要求

YOLO 的关键点格式具有以下规范:

  1. 每个图像对应一个文本文件
  2. 每行表示一个对象实例
  3. 格式包含:类别索引、边界框中心坐标、宽高、关键点坐标
  4. 所有坐标值归一化到 0-1 范围

数据转换的核心思路

转换过程主要包含以下几个关键步骤:

  1. 解析原始数据:读取 Label Studio 导出的 JSON 文件
  2. 建立关联关系:将关键点与对应的边界框进行匹配
  3. 坐标转换:将百分比坐标转换为归一化坐标
  4. 格式重组:按照 YOLO 要求的顺序组织数据
  5. 输出结果:生成 YOLO 格式的文本文件

详细转换方案

1. 配置 Label Studio 标注模板

为了获得最佳转换效果,建议使用以下标注模板配置:

<View>
  <Image name="image" value="$image"/>
  
  <RectangleLabels name="bbox" toName="image">
    <Label value="目标类别"/>
  </RectangleLabels>
  
  <KeyPointLabels name="keypoints" toName="image" smart="true">
    <Label value="关键点1"/>
    <Label value="关键点2"/>
    <!-- 其他关键点定义 -->
  </KeyPointLabels>
</View>

这种配置会自动建立关键点与边界框的父子关系,便于后续处理。

2. Python 转换脚本实现

以下是完整的转换脚本,包含详细注释:

import json
import os

def convert_labelstudio_to_yolo(ls_json_path, output_dir, class_map):
    """
    将Label Studio标注数据转换为YOLO关键点格式
    
    参数:
        ls_json_path: Label Studio导出的JSON文件路径
        output_dir: 输出目录
        class_map: 类别名称到索引的映射字典
    """
    # 创建输出目录
    os.makedirs(output_dir, exist_ok=True)
    
    with open(ls_json_path, 'r') as f:
        data = json.load(f)
    
    for task in data:
        # 获取图像基本信息
        image_path = task['data'].get('image') or task['data'].get('img')
        if not image_path:
            continue
            
        image_name = os.path.basename(image_path)
        txt_filename = os.path.splitext(image_name)[0] + '.txt'
        txt_path = os.path.join(output_dir, txt_filename)
        
        # 处理标注结果
        annotations = task.get('annotations', [])
        if not annotations:
            continue
            
        annotation = annotations[0]['result']
        
        # 存储边界框和关键点信息
        bboxes = {}
        keypoints = []
        
        # 首先收集所有边界框
        for item in annotation:
            if item['type'] == 'rectanglelabels':
                bbox_id = item['id']
                label = item['value']['rectanglelabels'][0]
                
                # 获取图像原始尺寸
                width = item['original_width']
                height = item['original_height']
                
                # 转换边界框坐标
                x = item['value']['x'] / 100
                y = item['value']['y'] / 100
                w = item['value']['width'] / 100
                h = item['value']['height'] / 100
                x_center = x + w/2
                y_center = y + h/2
                
                bboxes[bbox_id] = {
                    'class_idx': class_map.get(label, 0),
                    'x_center': x_center,
                    'y_center': y_center,
                    'width': w,
                    'height': h,
                    'keypoints': []
                }
        
        # 然后收集关键点并关联到边界框
        for item in annotation:
            if item['type'] == 'keypointlabels':
                # 通过parentID或relation关联
                parent_id = item.get('parentID')
                if not parent_id:
                    # 如果没有parentID,尝试从relation中获取
                    for rel in annotation:
                        if rel.get('type') == 'relation' and rel['to_id'] == item['id']:
                            parent_id = rel['from_id']
                            break
                
                if parent_id in bboxes:
                    # 转换关键点坐标
                    kp_x = item['value']['x'] / 100
                    kp_y = item['value']['y'] / 100
                    
                    # 添加到对应边界框的关键点列表
                    bboxes[parent_id]['keypoints'].extend([kp_x, kp_y, 2])  # 2表示可见
        
        # 生成YOLO格式内容
        yolo_lines = []
        for bbox in bboxes.values():
            line = [
                bbox['class_idx'],
                bbox['x_center'],
                bbox['y_center'],
                bbox['width'],
                bbox['height']
            ]
            line.extend(bbox['keypoints'])
            yolo_lines.append(' '.join(map(str, line)))
        
        # 写入文件
        with open(txt_path, 'w') as f:
            f.write('\n'.join(yolo_lines))

3. 脚本使用示例

# 定义类别映射
class_map = {
    'person': 0,
    'fish': 1
    # 添加其他类别...
}

# 执行转换
convert_labelstudio_to_yolo(
    ls_json_path='label_studio_export.json',
    output_dir='yolo_labels',
    class_map=class_map
)

常见问题与解决方案

  1. 关键点与边界框关联失败

    • 检查标注时是否正确建立了父子关系
    • 确保在Label Studio中使用了正确的标注模板
    • 可以尝试手动拖动关键点到边界框内
  2. 坐标转换错误

    • 确认原始JSON中包含original_width和original_height
    • 检查坐标值是否在预期范围内(0-100)
  3. 类别映射缺失

    • 确保class_map包含所有出现的类别
    • 可以为未知类别设置默认值
  4. 多对象实例处理

    • 脚本已支持多个边界框及其关联关键点
    • 每个实例会生成独立的行

最佳实践建议

  1. 标注规范统一

    • 为团队制定统一的标注规范
    • 确保关键点命名和顺序一致
  2. 数据验证

    • 转换后可视化检查结果
    • 可以使用OpenCV绘制关键点验证位置准确性
  3. 版本控制

    • 对标注数据和转换脚本进行版本管理
    • 记录转换参数和映射关系
  4. 性能优化

    • 处理大规模数据时考虑分批处理
    • 可以使用多线程加速转换过程

扩展应用

本文介绍的方法不仅适用于人体姿态估计,还可应用于:

  1. 动物行为分析
  2. 工业零件检测
  3. 医学图像标记
  4. 运动捕捉系统

只需调整Label Studio中的标签定义和YOLO模型的输出配置即可适应不同场景。

结语

将Label Studio的关键点标注数据转换为YOLO格式是训练姿态估计模型的重要前置步骤。通过本文介绍的转换方法和脚本,研究人员和开发者可以高效地准备训练数据,加速模型开发流程。实际应用中,建议根据具体需求调整脚本细节,并建立完善的数据质量控制流程。

登录后查看全文
热门项目推荐

项目优选

收起
ohos_react_nativeohos_react_native
React Native鸿蒙化仓库
C++
176
261
RuoYi-Vue3RuoYi-Vue3
🎉 (RuoYi)官方仓库 基于SpringBoot,Spring Security,JWT,Vue3 & Vite、Element Plus 的前后端分离权限管理系统
Vue
858
509
openGauss-serveropenGauss-server
openGauss kernel ~ openGauss is an open source relational database management system
C++
129
182
openHiTLSopenHiTLS
旨在打造算法先进、性能卓越、高效敏捷、安全可靠的密码套件,通过轻量级、可剪裁的软件技术架构满足各行业不同场景的多样化要求,让密码技术应用更简单,同时探索后量子等先进算法创新实践,构建密码前沿技术底座!
C
257
300
ShopXO开源商城ShopXO开源商城
🔥🔥🔥ShopXO企业级免费开源商城系统,可视化DIY拖拽装修、包含PC、H5、多端小程序(微信+支付宝+百度+头条&抖音+QQ+快手)、APP、多仓库、多商户、多门店、IM客服、进销存,遵循MIT开源协议发布、基于ThinkPHP8框架研发
JavaScript
93
15
Cangjie-ExamplesCangjie-Examples
本仓将收集和展示高质量的仓颉示例代码,欢迎大家投稿,让全世界看到您的妙趣设计,也让更多人通过您的编码理解和喜爱仓颉语言。
Cangjie
331
1.08 K
HarmonyOS-ExamplesHarmonyOS-Examples
本仓将收集和展示仓颉鸿蒙应用示例代码,欢迎大家投稿,在仓颉鸿蒙社区展现你的妙趣设计!
Cangjie
397
370
note-gennote-gen
一款跨平台的 Markdown AI 笔记软件,致力于使用 AI 建立记录和写作的桥梁。
TSX
83
4
CangjieCommunityCangjieCommunity
为仓颉编程语言开发者打造活跃、开放、高质量的社区环境
Markdown
1.07 K
0
kernelkernel
deepin linux kernel
C
22
5