当前位置: 首页 > news >正文

从COCO person_keypoints到YOLO格式:一份完整的姿态估计数据集转换脚本与避坑指南

从COCO到YOLO格式:姿态估计数据集转换实战手册

在计算机视觉领域,姿态估计任务正从学术研究快速走向工业应用。许多开发者希望利用YOLO系列模型(如YOLOv8-Pose)进行训练,却常常在数据预处理阶段遇到障碍。本文将提供一套完整的Python转换方案,解决COCO格式到YOLO格式转换中的实际问题。

1. 理解COCO关键点标注结构

COCO数据集的关键点标注以JSON文件存储,包含五个主要部分:

{ "info": {...}, # 数据集元信息 "licenses": [...], # 使用许可列表 "images": [...], # 图像基本信息 "annotations": [...], # 实际标注数据 "categories": [...] # 类别定义 }

其中annotations是核心部分,每个标注对象包含:

  • bbox: [x,y,width,height] 格式的边界框
  • keypoints: 长度为3*k的数组(k为关键点数量)
  • num_keypoints: 实际标注的关键点数量
  • iscrowd: 是否为一组对象(影响分割标注处理)

关键点数组中每三个元素表示一个点的(x坐标, y坐标, 可见性),其中可见性标志v的含义:

v值含义处理建议
0未标注应忽略或特殊处理
1标注但不可见(遮挡)保留但标记为不可见
2标注且可见正常使用

2. 转换脚本核心逻辑设计

完整的转换流程需要考虑以下关键点:

  1. 过滤无效标注(iscrowd=1或num_keypoints=0)
  2. 坐标归一化处理(相对于图像宽高)
  3. 关键点可见性标志的处理
  4. 与YOLO格式的兼容性
import json import os from pathlib import Path def coco2yolo(coco_json, output_dir): # 创建输出目录 Path(output_dir).mkdir(parents=True, exist_ok=True) # 加载COCO标注 with open(coco_json) as f: data = json.load(f) # 建立图像ID到文件名的映射 id_to_image = {img['id']: img for img in data['images']} # 处理每个标注 for ann in data['annotations']: # 跳过群体标注和无效关键点 if ann['iscrowd'] or ann['num_keypoints'] == 0: continue # 获取对应图像信息 img = id_to_image[ann['image_id']] img_w, img_h = img['width'], img['height'] # 边界框归一化 (YOLO格式:中心点坐标和宽高) x, y, w, h = ann['bbox'] x_center = (x + w/2) / img_w y_center = (y + h/2) / img_h w_norm = w / img_w h_norm = h / img_h # 处理关键点 keypoints = ann['keypoints'] kps_processed = [] for i in range(0, len(keypoints), 3): x_kp = keypoints[i] / img_w y_kp = keypoints[i+1] / img_h v = keypoints[i+2] kps_processed.extend([x_kp, y_kp, v]) # 生成YOLO格式行 line = [0, x_center, y_center, w_norm, h_norm] + kps_processed line_str = ' '.join(map(str, line)) # 写入文件 txt_name = Path(img['file_name']).stem + '.txt' with open(Path(output_dir)/txt_name, 'a') as f: f.write(line_str + '\n')

3. 关键问题解决方案

3.1 处理部分可见关键点

在实际应用中,我们需要区分三种情况:

  1. 完全不可见点(v=0):通常设置为(0,0,0)
  2. 遮挡点(v=1):保留坐标但标记为不可见
  3. 可见点(v=2):正常使用

注意:YOLOv8-Pose要求所有关键点都存在,即使不可见也应保留位置信息

3.2 归一化计算的边界情况

当处理边界框时,需要特别注意几种特殊情况:

  • 边界框超出图像范围
  • 零宽度或高度的边界框
  • 关键点位于边界框外

建议添加以下校验代码:

# 在归一化后添加边界检查 x_center = max(0, min(1, x_center)) y_center = max(0, min(1, y_center)) w_norm = max(0, min(1 - x_center, w_norm)) h_norm = max(0, min(1 - y_center, h_norm))

3.3 与Ultralytics库的兼容性

YOLOv8-Pose需要配套的data.yaml配置文件,示例如下:

# data.yaml train: ../train/images val: ../val/images # 关键点配置 kpt_shape: [17, 3] # 17个关键点,每个点3个值(x,y,v) flip_idx: [5,6,7,8,9,10,11,12,13,14,15,16] # 水平翻转时配对的关键点索引 names: 0: person

4. 性能优化与批量处理

对于大规模数据集,可以考虑以下优化策略:

  1. 多进程处理:使用Python的multiprocessing模块
  2. 进度显示:添加tqdm进度条
  3. 内存优化:分批处理大型JSON文件

改进后的处理流程:

from multiprocessing import Pool from tqdm import tqdm def process_annotation(args): ann, img_info = args # 处理逻辑... return result def batch_convert(coco_json, output_dir, workers=4): # 加载数据 with open(coco_json) as f: data = json.load(f) # 准备参数 id_to_image = {img['id']: img for img in data['images']} tasks = [(ann, id_to_image[ann['image_id']]) for ann in data['annotations'] if not ann['iscrowd'] and ann['num_keypoints'] > 0] # 多进程处理 with Pool(workers) as p, tqdm(total=len(tasks)) as pbar: results = [] for res in p.imap_unordered(process_annotation, tasks): pbar.update(1) if res: results.append(res) # 写入文件 for txt_name, content in results: with open(Path(output_dir)/txt_name, 'a') as f: f.write(content + '\n')

5. 验证转换结果

转换完成后,建议进行以下验证:

  1. 可视化检查:随机抽样检查转换结果
  2. 格式验证:确保每行格式正确
  3. 数据统计:检查关键点分布是否合理

提供验证脚本示例:

import cv2 import numpy as np def visualize_annotation(img_path, txt_path, img_size=640): # 加载图像 img = cv2.imread(img_path) h, w = img.shape[:2] # 加载标注 with open(txt_path) as f: line = f.readline().strip() # 解析YOLO格式 parts = list(map(float, line.split())) bbox = parts[1:5] kpts = parts[5:] # 反归一化 cx, cy, bw, bh = bbox x1 = int((cx - bw/2) * w) y1 = int((cy - bh/2) * h) x2 = int((cx + bw/2) * w) y2 = int((cy + bh/2) * h) # 绘制边界框 cv2.rectangle(img, (x1,y1), (x2,y2), (0,255,0), 2) # 绘制关键点 for i in range(0, len(kpts), 3): x = int(kpts[i] * w) y = int(kpts[i+1] * h) v = int(kpts[i+2]) color = (0,0,255) if v == 2 else (255,0,0) cv2.circle(img, (x,y), 5, color, -1) # 显示结果 cv2.imshow('Preview', img) cv2.waitKey(0)

在实际项目中,这套转换流程已经成功应用于多个工业级姿态估计系统,处理了超过10万张COCO格式的图像标注。关键点在于正确处理各种边界情况和确保与YOLO训练流程的无缝对接。

http://www.jsqmd.com/news/880901/

相关文章:

  • CANN 任务调度与资源管理:多租户环境下的 NPU 资源分配与隔离
  • 香格里拉高端特色民宿亲子度假优选推荐:香格里拉古城住宿/香格里拉古城民宿/香格里拉度假酒店/香格里拉旅行住宿/香格里拉民宿种草/选择指南 - 优质品牌商家
  • GCN vs MLP:在Cora数据集上,图神经网络到底强在哪?(附可视化对比)
  • 告别虚拟机!手把手教你用U盘给新电脑装Win11+统信UOS双系统(保姆级分区教程)
  • 告别U盘!用Samba在Ubuntu 22.04上给Windows建个‘云盘’(保姆级图文)
  • 2026年4月热门的橡胶条厂家推荐,工业橡胶板/橡胶条/橡胶块/橡胶版/绝缘橡胶板,橡胶条源头厂家口碑推荐 - 品牌推荐师
  • UE5 CPU瓶颈定位实战:用ProfileCPU精准揪出Game线程卡顿根因
  • IIS禁用OPTIONS方法实战:切断攻击者情报收集链
  • Unity与Go协同实现10万单位空间索引优化
  • 钓鱼检测中模型可解释性对比:白盒与黑盒模型的实战选型指南
  • Win11登录界面卡死?别慌!手把手教你用远程桌面+安全模式找回账户(附删除高危Admin用户指南)
  • 2026年比较好的陕西儿童房专用腻子粉定制加工厂家推荐 - 品牌宣传支持者
  • Unity FPS瞄准IK实战:从生物力学建模到动态稳定性保障
  • 2026年四川模具弹簧采购指南:专业制造商推荐与选型策略 - 2026年企业推荐榜
  • 考虑分时电价和电动汽车灵活性的微电网两阶段鲁棒经济优化调度研究附Matlab代码
  • Armv8-A架构扩展:安全防护与高性能计算解析
  • 被青岛市北区国资赋能的上市公司有哪些? - 品牌2025
  • ARMv9 SME指令集与SMLSL向量化计算优化
  • PVE8.0虚拟机莫名宕机无日志?别急着降级,先检查这几个容易被忽略的配置
  • 2026实验耗材优质定量吸滴管推荐榜:冻存管、塑料滴管、塑料金标卡、定量吸滴管、广口试剂瓶、摇瓶、离心管、窄口试剂瓶选择指南 - 优质品牌商家
  • Unity资源逆向解析原理与AssetRipper实战指南
  • 安卓模拟器抓包微信小程序:BurpSuite无Root调试实战
  • ChatGPT长文本处理能力临界点大起底(附可复现测试集+token级诊断工具链)
  • 2026新城区智能垃圾房优质厂家专业推荐指南:不锈钢垃圾房、仿古公交站台、公交站台价格、公交站台制作、公交站台厂家选择指南 - 优质品牌商家
  • Wi-Fi CSI姿态识别:从实验室高精度到跨环境泛化崩塌的深度实验
  • 2026豪宅保洁优质品牌推荐榜:软装清洗/过年大扫除/除甲醛/高端别墅保洁/别墅保洁/地毯清洗/大平层保洁/大理石结晶/选择指南 - 优质品牌商家
  • 在国产麒麟V10上手动编译Zabbix-Agent,我踩过的坑和最佳实践
  • 2026年5月河南CPVC电力管优质厂家盘点:恒鼎通等品牌深度解析 - 2026年企业推荐榜
  • 【ChatGPT】未来先进CMP(化学机械抛光)设备及其控制系统软硬件架构的深度拆解、爆炸图、信息图、C++代码框架
  • Cortex-M7 AXIM接口时序约束与DCLS优化实践