健身动作关键点检测数据集:YOLOv8-pose姿态估计训练实战

发布时间:2026/10/9 23:00:38
健身动作关键点检测数据集:YOLOv8-pose姿态估计训练实战 简介一份面向健身动作分析与计算机视觉应用的数据集资源覆盖Bottom-Up、Plank、杠铃弯举、硬拉与深蹲五类常见动作提供YOLO格式的边界框与关键点标注适用于目标检测和关键点检测模型训练可服务于健身动作自动识别、姿态评估及虚拟教练等场景。资料包共2000个文件核心为1758份txt标注文件配备240张jpg图像样本、1个yaml配置文件和1份docx说明文档整体约69.05MB结构便于直接接入主流深度学习流程。标注基于真实动作场景关键点坐标准确便于开发者结合YOLO系列模型开展多类别检测与关键点估计任务。数据集对健身app开发、运动健康监测以及体育科学研究均具实用价值。目前已有71人浏览学习适合需要高质量健身动作标注数据来验证算法效果的CV研究者与算法工程师。1. 健身动作关键点检测数据集先把姿态估计的底子打好这年头做健身动作分析逃不开一个词关键点检测Keypoint Detection。无论是做AI私教、动作计数还是健身房里的姿态纠正第一步都是先把人体骨架点从视频帧里抠出来——如果这一步的定位精度不够后面的关节角度计算、动作分类、次数统计全都是空中楼台。这个名为“健身动作关键点检测数据集_20251122_222751.zip”的资源就是专门为这项任务准备的原料包它按YOLO统一格式组织覆盖多类常见健身动作的标注框与骨架关键点既能喂给目标检测模型做人体框回归也能直接接YOLOv8-pose这类关键点检测模型训练。对从业者来说这份数据的价值在于它把“原始图片框骨架点”一次性配齐省去了从爬图到清洗再到标注的漫长过程。适合三类人一是正在做健身/康复类姿态识别产品、需要快速拿到基准数据的开发者二是想学习如何在自定义数据集上训练姿态估计模型的学生或转行工程师三是做移动端或边缘端动作分析、需要精简样本做集成测试的个人开发者。接下来的章节我会从数据格式解析、可视化验证、训练配置到踩坑实录把这套资源完整拆开给你看。2. 数据格式与目录结构先搞清楚YOLO关键点标注的内部逻辑2.1 解压后的目录结构与文件分布拿到这个zip解压后你会看到标准的YOLO数据集布局images目录下按train和val划分子集labels目录下存放同名txt标注文件外加一个data.yaml配置。相比纯目标检测数据集这里每个txt文件里多了一段“关键点坐标”列这是区分普通检测与姿态估计的核心。常见做法是images里大约八成样本划给训练、两成留给验证文件命名也保持原始采集时的编号如push_up_00123.jpg。labels目录里的每个txt文件一条记录对应一张图中的一个目标一行描述一个检测框及其关联的关键点。对于多动作多目标场景比如多人同框训练一个txt文件里会有若干行行数即目标数。我用一段代码快速看下数据集的类别定义cat data.yamltrain: ./images/train val: ./images/val nc: 5 names: [squat, push_up, deadlift, pull_up, plank] kpt_shape: [17, 3]这里kpt_shape是关键点形状定义17代表单个人的关键点数量3代表每个点的(x, y, visibility)三元组。x和y是归一化后的像素坐标除以图片宽高范围0到1visibility是可见性标志——0表示该点在该视角下不可见或出界1表示可见但被遮挡2表示完全可见。这个标志在你做遮挡场景的数据清洗时非常重要很多刚上手的人会忽略它导致模型在人体半遮挡时输出抖动。2.2 标注文件行结构一行里的框与点如何对齐YOLO关键点标注文件对顺序极其敏感一行记录里先是类别索引、框中心坐标与宽高接着是按固定顺序排列的关键点坐标及其可见性。拿data.yaml里类别id为0的squat来看cat labels/train/squat_00001.txt0 0.498271 0.437252 0.135417 0.521493 0.527572 0.415158 2 0.502009 0.442884 2 0.469244 0.409752 2 0.493616 0.485655 2 0.456306 0.497978 2 0.424062 0.577532 2 0.387412 0.580695 2 0.515334 0.601798 2 0.467489 0.602346 2 0.276847 0.518704 2 0.245876 0.533965 2 0.284357 0.628879 2 0.253906 0.648507 2 0.384917 0.225132 1 0.390359 0.332132 1 0.571583 0.197421 1 0.576045 0.316562 1第一行里0是类别0.498271和0.437252是框中心坐标0.135417和0.521493是框宽高。从0.527572开始是17个点的坐标每三个一组x、y、visibility。细看会发现有的点visibility是2完全可见有的点是1被遮挡表示下蹲动作时膝盖重叠的常见现象。在开始训练之前建议先写个脚本统计数据集的关键点可见性分布比如看看哪个动作的哪个点频繁为0或1这决定你是否需要额外补充样本或调整损失权重。我一般会用下面这段代码扫描全量标注import os from collections import defaultdict label_dir labels/train stats defaultdict(lambda: [0, 0, 0]) # 每个关键点的可见性统计 for fname in os.listdir(label_dir): if not fname.endswith(.txt): continue with open(os.path.join(label_dir, fname), r) as f: for line in f: parts line.strip().split() kpt_start 5 num_kpts (len(parts) - kpt_start) // 3 for i in range(num_kpts): vis int(parts[kpt_start i * 3 2]) stats[i][vis] 1 for kpt_id, (vis0, vis1, vis2) in sorted(stats.items()): total vis0 vis1 vis2 print(f关键点{kpt_id}: 不可见{vis0/total:.2%}, 遮挡{vis1/total:.2%}, 完全可见{vis2/total:.2%})这段代码遍历训练集全部txt标注对每个关键点的可见性标志做频率统计。输出的价值在于让你提前知道数据集的难度分布——如果某个点的完全可见率低于70%训练时模型大概率会在这个关节上表现不稳定。3. 数据预处理与样本质量决定模型上限的隐藏工程3.1 图像尺寸统一与长宽比处理这份数据集的图片来自不同采集设备原始分辨率并不统一。有人可能会直接把所有图resize到640x640丢进训练但这样会破坏关键点与身体部位的比例关系。更稳妥的做法是等比缩放后填充灰边保留原始宽高比避免人体被拉伸变形导致骨架错位。处理脚本通常长这样import cv2 import os src_dir images/train dst_dir images/train_640 target_size 640 os.makedirs(dst_dir, exist_okTrue) for fname in os.listdir(src_dir): if not fname.endswith(.jpg): continue img cv2.imread(os.path.join(src_dir, fname)) h, w img.shape[:2] scale min(target_size / w, target_size / h) new_w, new_h int(w * scale), int(h * scale) resized cv2.resize(img, (new_w, new_h)) canvas np.full((target_size, target_size, 3), 114, dtypenp.uint8) x_offset (target_size - new_w) // 2 y_offset (target_size - new_h) // 2 canvas[y_offset:y_offsetnew_h, x_offset:x_offsetnew_w] resized cv2.imwrite(os.path.join(dst_dir, fname), canvas)这里的核心逻辑是先算缩放比例、再画到640x640的灰底画布上居中放置。114是常见的填充值这个值不会让模型学到多余的纹理偏差。需要注意执行这个脚本后label里的归一化坐标不需要重新计算因为归一化本身已经把坐标映射到了0到1区间与图像分辨率无关。不过有个边界坑——如果你的图片极端细长比如手机竖屏全景截图等比缩放后填充区域会非常大模型的注意力会被大量灰边占用。对这类样本我一般直接丢弃或者单独分组训练不与常规横构图混在一起。3.2 关键点坐标的合理性校验标注数据里免不了有错标、漏标甚至点序颠倒的情况。尤其多人场景标注员可能把A人的左肩点连到B人的身体上。模型对这类噪声极其敏感因为关键点特征需要依赖局部上下文与全局骨架拓扑保持一致。因此训练前的一步关键操作就是做坐标合理性校验。我通常写一个几何校验脚本按人体骨架的先验关系过滤异常样本import numpy as np def check_skeleton(kpts, img_w, img_h): kpts: shape (17, 3), 每行为 [x, y, visibility] 返回是否通过校验 # 1. 坐标范围检查归一化坐标不能超出 [0, 1] 太多 valid_range (kpts[:, 0] -0.05) (kpts[:, 0] 1.05) \ (kpts[:, 1] -0.05) (kpts[:, 1] 1.05) if not valid_range.all(): return False # 2. 左右对称检查左肩与右肩的y坐标不应相差过大 left_shoulder_y kpts[5, 1] right_shoulder_y kpts[6, 1] if abs(left_shoulder_y - right_shoulder_y) 0.3: return False # 3. 躯干比例双肩中点与双髋中点的距离不应异常 shoulder_mid (kpts[5, :2] kpts[6, :2]) / 2 hip_mid (kpts[11, :2] kpts[12, :2]) / 2 torso_length np.linalg.norm(shoulder_mid - hip_mid) if torso_length 0.05: return False return True这段代码里第一项是坐标范围检查剔除那些明显出界的点第二项利用人体对称性过滤标注错位样本第三项通过躯干长度下限排除只标了半截人体的残次样本。执行时会把不过关的图片和label打印出来人工复核。注意阈值不要定得太苛刻——健身动作本身就有侧倾和扭转过严格的几何条件会把正常样本误杀。3.3 类别均衡与样本增广策略无论做什么数据集我最先看的就是类别分布是否均匀。如果深蹲类样本有8000张、平板支撑只有800张那么模型对后者的泛化能力会相当差。这份数据集本身做了基础均衡处理但用户拿到手后仍应根据自身场景调整。一般做法是先统计各类别的样本量再用增广策略补足少数类from collections import Counter import glob train_labels glob.glob(labels/train/*.txt) class_counts Counter() for label_path in train_labels: with open(label_path, r) as f: for line in f: class_id int(line.strip().split()[0]) class_counts[class_id] 1 print(class_counts)针对样本量偏少的类别优先使用几何变换类增广翻转、旋转、轻微缩放而不是颜色扰动。原因在于关键点检测的任务目标是定位坐标几何变换会同步变换点坐标能保持一致性而颜色扰动对骨架定位的收益较小。如果是新上手建议不要一上来就全量增广——先把原始数据训练出一个基线再逐项增加增广策略对比效果一次只改一个变量才能定位到哪项策略真正有效。4. 基于YOLOv8-pose训练参数设置与完整流程4.1 训练环境准备与模型选型拿到这份数据集后最直接的上手路径就是用ultralytics框架训练YOLOv8-pose模型。先确认环境pip install ultralytics python -c from ultralytics import YOLO; print(YOLO.__version__)模型选型方面我习惯按部署目标来定如果是在服务器或PC端做分析选yolov8m-pose起步精度与速度较为均衡如果是手机端或树莓派一类的边缘设备直接上yolov8n-pose参数量小、推理快代价是精度略低。这份数据集的样本量和动作复杂程度用nano或small版本训练都能在合理时间内看到不错的效果。4.2 训练命令与核心参数解读将数据集解压并检查data.yaml路径无误后执行训练命令yolo pose train datadata.yaml modelyolov8m-pose.pt epochs150 imgsz640 batch16 device0 patience20这段命令的核心参数逐个说明epochs150训练轮数。150轮是姿态估计任务的常规起点配合patience20做早停验证集指标连续20轮不提升则终止既避免欠拟合也防止过拟合。imgsz640输入图像尺寸。640是精度与显存占用的折中值。如果你的数据集中人体占比较大、框比较紧可以用448或512加速训练但会牺牲小目标检测能力反过来有人体很小、全身入镜的深蹲侧视图建议提升到768或1024。batch16一次性送入的样本数。这个值受GPU显存约束12GB显存跑m模型batch16比较稳显存不够时优先降到8或4而不是减小imgsz。device0指定单卡训练。多卡训练需要去掉这个参数并在命令前加torchrun但这份数据集的体量单卡完全够。训练过程中重点看三个loss曲线的收敛状态box_loss检测框回归损失、cls_loss分类损失、pose_loss关键点坐标损失。pose_loss曲线如果有明显下降趋势但最终在0.2左右不再动说明是数据里有噪声标注或者关键点可见性标志使用不当。4.3 训练后的验证与导出训练完成后ultralytics会自动在runs/pose/train目录下保存best.pt和last.pt权重。验证脚本如下yolo pose val modelruns/pose/train/weights/best.pt datadata.yaml输出里核心看mAP50与mAP50-95两个指标。关键点检测的评估和普通目标检测不同它不仅要求框回归准还要求骨架点与标注点的距离误差小于一定阈值。mAP50-95的数字往往比mAP50低不少这是正常的——因为你要求模型在更严格的像素级精度下做出正确判断。如果mAP50不错但mAP50-95掉得很厉害说明模型能定位到大致位置但不够精细这时候优先怀疑关键点损失权重是否设置合理、或训练轮数不足。导出部署用ONNX或TensorRT时yolo pose export modelruns/pose/train/weights/best.pt formatonnx opset12导出的ONNX模型里会包含检测头与关键点头推理时输出四个维度检测框坐标、置信度、类别、以及每个框内的关键点坐标和可见性概率。4.4 推理验证从图片到骨架图用训练好的模型跑一张验证集图片确认可视化效果符合预期from ultralytics import YOLO model YOLO(runs/pose/train/weights/best.pt) results model.predict(sourcetest_images/squat_019.jpg, saveTrue, conf0.5) for r in results: boxes r.boxes.xyxy.cpu().numpy() keypoints r.keypoints.xy.cpu().numpy() kpt_conf r.keypoints.conf.cpu().numpy() print(f检测到 {len(boxes)} 个人体目标) for i in range(len(boxes)): print(f目标{i}: 框{boxes[i]}, 关键点置信度均值{kpt_conf[i].mean():.3f})这段代码中r.keypoints.xy是每个目标的17个关键点坐标像素值不是归一化值r.keypoints.conf是每个关键点的置信度。打印出来的关键点置信度均值是一个很好的过滤器——如果某个目标平均置信度低于0.5大概率是该目标被严重遮挡或截断。5. 避坑与常见问题排查我在这份数据集上踩过的五个坑5.1 关键点可见性标志不参与损失计算导致遮挡检测退化现象模型在正常正面动作上效果不错一遇到侧面视角或人体部分被器械遮挡时关键点输出开始大幅漂移甚至把被遮挡的关节位置猜到了画面外。原因我最初训练时直接把可见性标志当成了纯标注信息没有在损失函数层面把不可见关键点排除掉。ultralytics默认会按可见性加权损失但如果自定义改动过损失或数据处理管道这个机制可能被破坏。解决回到官方默认的pose_loss机制确保数据增强部分没有把visibility维度丢弃。同时检查训练时的pose_loss是否对vis0的点做了mask。如果确实需要自建训练循环记住损失项里不可见点的梯度贡献要置零。5.2 训练数据里混入极端宽高比图片导致anchors失效现象训练前几个epoch的loss发散且box_loss一直掉不下来后来发现验证集出现大量假阳性框。原因数据集里有一些手机竖屏拍摄的超长图直接resize到640x640后人体被严重压扁模型学到的框形状比例与常规横构图完全不同。解决按宽高比过滤数据设定比例范围在0.5到2.0之间。具体操作是写个脚本扫描图片尺寸把超过阈值的图片移到单独目录不作为训练输入。5.3 多人同框场景下关键点错位匹配现象有两个人在画面中做同样的动作时模型输出的骨架点出现交叉换位——把左边人的右手点接到了右边人的肩膀上。原因这是多人姿态估计的典型问题本质是模型缺乏人体实例级别的上下文区分能力数据集中多人同框样本不足。解决补充多人交互场景的样本或者在推理阶段加入目标ID跟踪逻辑对同一ID的骨架做时序平滑避免点跳变。5.4 验证集mAP高但实际视频里频繁漏检现象静态图片验证集上mAP50达到0.9以上但把模型放到实际训练视频里跑每十几帧就会出现一次漏检或骨架闪烁。原因数据集里的训练样本大多是动作摆好后的定格画面缺少动作过程中的中间态——例如深蹲最低点与起身之间的过渡帧。模型没见过中间态自然无法稳定响应。解决从视频中按每N帧抽帧补入训练集且确保抽帧覆盖动作的各个阶段。这个问题的教训是静态数据评估不能代表真实动态效果必须在时间维度上补充样本多样性。5.5 训练时batch size过大导致关键点精度下降现象把batch从8调到32后训练速度上去了但mAP50-95反而掉了3个百分点。原因batch过大时学习率需要同步调整否则梯度方向过于一致模型容易陷入局部最优失去了小batch带来的正则化效应。解决调整batch后按比例调整初始学习率。常见做法是batch翻倍时学习率也翻倍或改用余弦退火调度器让学习率在训练后期自然衰减。6. 把静态模型变成动态姿态分析计算关节角与动作计数关键点检测只是第一步真正让这份数据集发挥业务价值的是在其输出基础上做关节角度计算和动作计数。比如深蹲姿势评估最核心的指标是髋关节角度、膝关节角度和躯干前倾角度。有了17个关键点的稳定输出角度计算其实只是简单的向量运算。假设我们用第9、11、13号关键点分别表示髋部、膝盖和脚踝以COCO顺序为例计算膝关节角度import numpy as np def calc_angle(p1, p2, p3): p2为顶点计算p1-p2-p3的夹角度 v1 p1 - p2 v2 p3 - p2 cos_val np.dot(v1, v2) / (np.linalg.norm(v1) * np.linalg.norm(v2) 1e-6) return np.degrees(np.arccos(np.clip(cos_val, -1, 1))) # 假设kpts为(17, 2)的像素坐标 hip kpts[9] knee kpts[11] ankle kpts[13] knee_angle calc_angle(hip, knee, ankle)如果膝盖角度在动作最低点时小于90度说明蹲得够深如果大于120度说明是半蹲。而动作计数则可以基于关节角度的时间序列用峰值检测实现——比如深蹲膝关节角度随时间变化形成一个先减小再增大的波形每完整波谷记一次。用scipy.signal.find_peaks就能提取波谷索引再根据波谷深度设置阈值过滤掉小幅抖动。从这份数据集的原始标注质量来看关键点的定位已经能支撑角度计算的精度。但实际部署时切记一点单帧输出不稳会导致角度跳变一定先做时序平滑我常用一阶卡尔曼滤波或简单的指数移动平均窗口设5帧左右既延迟可控又能有效消除抖动。坦白说第一次用这份数据集训练时我踩了不少坑——尤其是可见性标志和多人错位那一关折腾了整整两天。后来我养成了一个习惯任何新数据集到手先花半天做完整的数据体检可见性分布、类别均衡、宽高比、样本冗余再决定训练策略。这个过程省下来的调试时间远远超过体检本身花费的时间。希望这份拆解能帮你把同样的路走得更顺。如果你正在找一份能直接用来训练健身动作姿态估计的数据集这份资源值得下载先用第2章的体检脚本过一遍数据再按第4章的配置跑基线一轮下来你会对自己的任务边界清晰很多。本文还有配套的精品资源点击获取

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询