尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

COCO数据集人体关键点转YOLO格式实战指南

COCO数据集人体关键点转YOLO格式实战指南 1. 项目概述COCO数据集人体关键点识别与YOLO格式转换在计算机视觉领域人体姿态识别一直是个热门研究方向。最近我在处理COCO数据集时遇到了一个实际需求将COCO格式的人体关键点标注数据转换为YOLO可用的.txt格式。这个转换过程看似简单但实际操作中会遇到各种细节问题比如关键点坐标系的转换、可见性标记的处理、以及不同版本YOLO对关键点格式的要求差异等。COCO数据集全称Common Objects in Context是微软发布的大规模目标检测、分割和姿态识别数据集。其中2017版包含超过20万张图像和25万个人体实例每个实例标注了17个关键点鼻子、眼睛、耳朵、肩膀、肘部、手腕、臀部、膝盖和脚踝。这些关键点数据以JSON格式存储包含每个点的(x,y)坐标和可见性标志0未标注1标注但不可见2标注且可见。YOLOYou Only Look Once作为当前最流行的实时目标检测框架从v5版本开始支持关键点检测任务。但YOLO使用的关键点格式与COCO不同需要将COCO的绝对坐标转换为相对于边界框宽高的相对坐标。这个转换过程直接影响模型训练效果必须精确处理。2. COCO数据集关键点标注解析2.1 COCO关键点数据结构COCO数据集的标注信息存储在annotations文件夹下的person_keypoints_train2017.json和person_keypoints_val2017.json文件中。每个关键点标注包含以下核心字段{ keypoints: [x1,y1,v1,...,x17,y17,v17], num_keypoints: int, bbox: [x,y,width,height], category_id: 1, id: int, image_id: int, iscrowd: 0 }其中keypoints数组按固定顺序存储17个关键点每组三个值分别表示x坐标、y坐标和可见性状态。关键点顺序固定为鼻子左眼右眼左耳右耳左肩右肩左肘右肘左腕右腕左髋右髋左膝右膝左踝右踝2.2 关键点可见性处理可见性标记v有三种状态v0关键点未标注实际不存在或标注员未标注v1关键点标注但不可见被遮挡或超出图像边界v2关键点标注且可见在转换到YOLO格式时需要特别注意v1的情况。YOLO的关键点格式没有单独的可见性标记通常有两种处理方式保留所有标注点v1或2但训练时对v1的点使用不同的损失权重只保留v2的点其余视为无效根据我的实测经验第一种方式效果更好因为被遮挡的关键点位置虽然不确定但至少知道它的大致区域比如被衣服遮挡的手腕应该在袖子末端。3. YOLO关键点格式详解3.1 YOLO格式规范YOLOv5/v8的关键点检测使用以下.txt文件格式每行一个对象object-class x_center y_center width height px1 py1 p1_visible ... pxN pyN pN_visible其中object-class类别索引COCO中person0x_center, y_center, width, height边界框中心坐标和宽高相对值0-1范围pxi, pyi第i个关键点的x,y坐标相对边界框的偏移0-1范围pi_visible关键点可见性通常0不可见1可见与COCO格式的主要区别坐标系统YOLO使用相对坐标相对于图像尺寸或边界框尺寸可见性标记YOLO通常只用0/1两种状态数据存储YOLO使用空格分隔的纯文本而非JSON3.2 坐标转换算法将COCO格式转换为YOLO格式需要以下计算步骤边界框转换# COCO bbox格式[x,y,width,height]绝对像素值 x_min bbox[0] y_min bbox[1] width bbox[2] height bbox[3] # 转换为YOLO格式相对图像尺寸 x_center (x_min width/2) / image_width y_center (y_min height/2) / image_height box_width width / image_width box_height height / image_height关键点转换for i in range(17): # COCO关键点坐标绝对像素值 x_abs keypoints[3*i] y_abs keypoints[3*i1] v keypoints[3*i2] # 转换为相对于边界框的坐标 x_rel (x_abs - x_min) / width if v 0 else 0 y_rel (y_abs - y_min) / height if v 0 else 0 # YOLO可见性标记简化处理 visible 1 if v 2 else 0注意当关键点位于边界框外时可能由于标注误差或特殊姿势需要做截断处理x_rel max(0, min(1, x_rel)) y_rel max(0, min(1, y_rel))4. 完整转换代码实现4.1 Python转换脚本以下是完整的COCO到YOLO关键点格式转换脚本import json import os def coco2yolo_keypoints(coco_json_path, output_dir, image_dir): # 加载COCO标注文件 with open(coco_json_path) as f: coco_data json.load(f) # 创建图像ID到文件名的映射 images {img[id]: img for img in coco_data[images]} # 按图像ID分组标注 annotations {} for ann in coco_data[annotations]: if ann[category_id] ! 1: # 只处理person类别 continue img_id ann[image_id] if img_id not in annotations: annotations[img_id] [] annotations[img_id].append(ann) # 处理每张图像 for img_id, anns in annotations.items(): img_info images[img_id] img_width img_info[width] img_height img_info[height] file_name img_info[file_name].replace(.jpg, .txt) yolo_lines [] for ann in anns: # 解析COCO格式 keypoints ann[keypoints] bbox ann[bbox] x_min, y_min, width, height bbox # 跳过无效边界框 if width 0 or height 0: continue # 转换为YOLO边界框格式 x_center (x_min width/2) / img_width y_center (y_min height/2) / img_height box_width width / img_width box_height height / img_height # 处理关键点 kps_line [0, x_center, y_center, box_width, box_height] # class0(person) for i in range(17): x_abs keypoints[3*i] y_abs keypoints[3*i1] v keypoints[3*i2] # 关键点相对坐标 x_rel (x_abs - x_min) / width if v 0 else 0 y_rel (y_abs - y_min) / height if v 0 else 0 # 边界截断 x_rel max(0, min(1, x_rel)) y_rel max(0, min(1, y_rel)) # YOLO可见性标记 visible 1 if v 2 else 0 kps_line.extend([x_rel, y_rel, visible]) yolo_lines.append( .join(map(str, kps_line))) # 写入YOLO格式文件 output_path os.path.join(output_dir, file_name) with open(output_path, w) as f: f.write(\n.join(yolo_lines)) # 使用示例 coco2yolo_keypoints( coco_json_pathperson_keypoints_train2017.json, output_dirlabels/train2017, image_dirimages/train2017 )4.2 关键优化技巧批处理加速对于大规模数据集可以使用多进程处理from multiprocessing import Pool def process_image(args): img_id, anns, images args # 处理单张图像同上 ... if __name__ __main__: with Pool(processes8) as pool: args_list [(img_id, anns, images) for img_id, anns in annotations.items()] pool.map(process_image, args_list)可视化验证转换后建议绘制关键点验证准确性import cv2 import numpy as np def plot_keypoints(image_path, label_path): img cv2.imread(image_path) h, w img.shape[:2] with open(label_path) as f: lines f.readlines() for line in lines: parts list(map(float, line.strip().split())) if len(parts) 6: # 无关键点 continue # 解析边界框 x_center, y_center, box_w, box_h parts[1:5] x_min int((x_center - box_w/2) * w) y_min int((y_center - box_h/2) * h) box_w int(box_w * w) box_h int(box_h * h) cv2.rectangle(img, (x_min, y_min), (x_minbox_w, y_minbox_h), (0,255,0), 2) # 解析关键点 kps parts[5:] for i in range(0, len(kps), 3): x_rel, y_rel, visible kps[i:i3] if visible 0: x int(x_min x_rel * box_w) y int(y_min y_rel * box_h) cv2.circle(img, (x,y), 3, (0,0,255), -1) cv2.imshow(Keypoints, img) cv2.waitKey(0)5. 训练YOLO模型的关键点检测5.1 数据集配置转换完成后需要创建YOLO格式的数据集配置文件data.yaml# COCO人体关键点数据集配置 train: ../images/train2017 val: ../images/val2017 # 关键点信息 kpt_shape: [17, 3] # 17个关键点每个点3个值(x,y,visible) flip_idx: [1,2, 3,4, 5,6, 7,8, 9,10, 11,12, 13,14, 15,16] # 左右对称点对 # 类别信息 names: 0: person5.2 模型训练命令使用YOLOv8训练关键点检测模型yolo train modelyolov8n-pose.pt datadata.yaml epochs100 imgsz640 batch32关键参数说明modelyolov8n-pose.pt使用预训练的姿态估计模型kpt_shape必须与数据格式匹配flip_idx指定左右对称的关键点索引对用于数据增强5.3 训练技巧学习率调整关键点检测需要更精细的学习率控制yolo train ... lr00.01 lrf0.1 warmup_epochs3数据增强配置适当增加旋转和缩放增强# data.yaml中添加 augment: rotation: 30 # 旋转角度范围 scale: 0.5 # 缩放范围 shear: 10 # 剪切范围损失权重调整关键点损失与检测损失的平衡yolo train ... kobj1.0 kpt5.0 # 增大关键点损失权重6. 常见问题与解决方案6.1 关键点坐标异常问题转换后的关键点坐标超出[0,1]范围原因COCO标注的边界框可能没有完全包含所有关键点解决在转换代码中添加截断处理见4.1节6.2 YOLO训练时报错维度不匹配问题ValueError: kpt_shape does not match label data原因data.yaml中kpt_shape设置与实际数据不一致检查确认标注文件中每行有517356个值1类4框17关键点3确认yaml文件中kpt_shape: [17,3]6.3 关键点预测位置偏差大问题模型预测的关键点位置不准确可能原因坐标转换时未正确处理可见性标记边界框质量差导致关键点相对坐标失真优化方案清理训练数据剔除边界框过小或标注质量差的样本在损失函数中降低低可见性关键点的权重6.4 处理非COCO标准关键点需求使用自定义关键点如面部特征点修改步骤调整kpt_shape为关键点数量更新flip_idx对应新的对称关系在转换脚本中修改关键点索引映射7. 性能优化与部署建议7.1 模型选型参考模型参数量GPU延迟(ms)精度(AP)适用场景yolov8n-pose3.2M2.150.2移动端/嵌入式yolov8s-pose11.4M3.456.8边缘计算yolov8m-pose26.3M6.561.2服务端yolov8l-pose44.4M9.263.5高性能服务器7.2 TensorRT加速部署将训练好的YOLOv8-pose模型导出为TensorRT引擎yolo export modelyolov8n-pose.pt formatengine device0优化技巧使用FP16精度减少显存占用yolo export ... halfTrue动态批次处理支持yolo export ... batch1,4,8 # 支持1/4/8三种批次大小7.3 关键点后处理优化原始输出包含所有17个关键点的置信度可以通过以下方式优化基于规则过滤# 只保留置信度0.5的关键点 valid_kpts [kpt for kpt in keypoints if kpt[2] 0.5]姿态合理性校验def validate_pose(keypoints): # 检查左右对称点距离 shoulder_dist distance(keypoints[5], keypoints[6]) hip_dist distance(keypoints[11], keypoints[12]) # 肩宽与髋宽应保持合理比例 return 0.7 shoulder_dist/hip_dist 1.5在实际项目中我发现正确处理COCO到YOLO的关键点格式转换是保证模型精度的基础。特别是边界框与关键点的相对位置关系直接影响模型学习关键点位置的能力。建议转换完成后至少抽样检查5%的图像标注确保没有明显的坐标转换错误。
返回列表