资讯详情

资讯详情

健身动作关键点检测数据集全流程:从解压到训练与可视化验证

简介以YOLO格式组织的健身动作关键点检测数据集用于目标检测与关键点检测任务覆盖自下而上、平板支撑、杠铃弯举、硬拉、深蹲五类常见健身动作共包含1758张图片。资源按训练/验证/测试划分训练集1582张、验证集70张、测试集106张标注同时提供边界框与关键点坐标适合直接接入主流深度学习框架面向健身App、虚拟教练、动作评估与体育科研等场景。压缩包共2000个文件主体为1758个txt标注文件与240张jpg图像另含1个yaml配置文件和1个docx说明文档总容量69.05MB结构清晰便于按YOLO流程快速使用。目前已有71人学习对于需要构建健身动作自动识别或关键点分析模型的开发者这份数据可为模型训练、验证与部署提供完整基础减少数据采集与标注成本。1. 健身动作关键点检测数据集不是拿到标注就能直接开训一个带时间戳的健身动作关键点检测数据集压缩包解压之后最常见的情况不是缺数据而是缺一套把标注变成训练信号的完整流程。很多人拿到数据集就直接把图片丢进网络开始训练结果 loss 一路抖动、验证集指标虚高、模型在真实动作上频繁把左右腿搞混。问题不在模型在于没搞清这套数据集的关键点定义、坐标体系和骨骼连接关系。这个标题背后真正要解决的是从一份标注好的关键点数据出发完成数据解析、热力图生成、增强策略、模型配置和结果验证的完整闭环。适合正在做健身姿态纠正、动作计数、教练辅助系统的从业者也适合想用手头人体姿态数据快速跑通检测流程的工程团队。接下来按实际落地的顺序把每一步拆开讲。2. 数据集的目录结构与标注格式先把坐标存在哪里搞清楚2.1 数据目录从 zip 结构开始认识数据这类数据集压缩包解压后目录通常分成三个部分图像帧目录、标注文件目录、还有一份说明关键点定义的类别文件。不要跳过说明文件直接看图片关键点顺序、骨骼连接关系、坐标是否归一化全写在这份说明里。常见布局是images/、annotations/、keypoint_definition.json三块。图像目录下一般按动作类型分子文件夹比如深蹲、俯卧撑、硬拉、开合跳每个子文件夹里是连续视频帧或按文件名排序的图片。这种按动作分类的组织方式决定了训练集和验证集不能随便按帧随机切分得按动作分组切否则同一个动作的连续帧会同时出现在训练和验证两边指标虚高到没有参考价值。unzip 健身动作关键点检测数据集_20251122_222751.zip -d dataset/ tree dataset -L 2解压后先看一眼目录层级确认图片和标注的对应关系。大多数情况下图片文件名与标注中的image_id一一对应文件名里通常带拍摄编号或动作编号后续做数据划分时可以直接复用这个编号。2.2 关键点定义与标注坐标解析关键点检测数据集的标注文件主流是 COCO 风格 JSONimages数组放图像信息annotations数组放单个人体的关键点坐标和可见性categories里放关键点名称列表和骨架连接定义。拿到手的第一步就是解析这三个字段。import json import numpy as np with open(dataset/annotations/train.json, r) as f: ann json.load(f) keypoint_names [kp[name] for kp in ann[categories][0][keypoints]] skeleton ann[categories][0][skeleton] print(关键点数量:, len(keypoint_names)) print(关键点名称:, keypoint_names) print(骨架连接:, skeleton) img_info ann[images][0] ann_info ann[annotations][0] print(图像尺寸:, img_info[width], x, img_info[height]) kps np.array(ann_info[keypoints]).reshape(-1, 3) print(第一个人体关键点坐标 (x, y, 可见性):) print(kps[:5])keypoints是一个扁平数组每三个数构成一个关键点顺序与keypoint_names对应。坐标x, y是像素坐标还是归一化坐标直接决定后续要不要做坐标缩放很多新手在这里翻车。可见性v通常分三档0表示关键点不在画面内1表示标注了但被遮挡2表示可见且已标注。训练时建议只把v1和v2的点纳入监督v0的点直接屏蔽否则网络会拼命去预测一个根本不存在的东西。2.3 骨骼连接关系最容易忽略的结构信息skeleton字段定义了关键点之间的连接关系它不只是给画图用的。推理后处理时如果骨骼关系定义错误画出来的骨架会交叉错乱做动作角度计算时会得到完全错误的角度。比如深蹲的膝盖角是由髋、膝、踝三个关键点构成如果髋和踝的顺序写错了计算出的膝关节角度可能超过 180 度。# 用骨架连接关系计算膝关节角度示例髋、膝、踝 def compute_angle(p1, p2, p3): v1 p1 - p2 v2 p3 - p2 cos_theta np.dot(v1, v2) / (np.linalg.norm(v1) * np.linalg.norm(v2) 1e-6) return np.degrees(np.arccos(np.clip(cos_theta, -1.0, 1.0))) # 假设关键点顺序: 0髋, 1膝, 2踝 hip, knee, ankle kps[0][:2], kps[1][:2], kps[2][:2] print(膝关节角度:, compute_angle(hip, knee, ankle))这段代码演示了骨骼关系在动作分析和计数场景的典型用途。关键点顺序不同时只需要把索引换掉即可逻辑不变。拿到数据集第一件事就是把每个动作的关键点连线图打印出来和实际人体结构对照一遍确认左右对称关系和脊柱点位置这个检查能省掉后面好几天的排查时间。3. 数据预处理与增强把坐标点变成能训练的监督信号3.1 高斯热力图生成标注坐标到监督信号的转换关键点检测的主流方案不是直接回归坐标值而是生成一张高斯热力图让网络学习预测每个关键点在像素空间上的概率分布。原因是坐标回归对遮挡、模糊和标注噪声极度敏感而热力图天然具有空间泛化能力。def gaussian_heatmap(keypoints, img_size256, hm_size64, sigma2): num_kps len(keypoints) hm np.zeros((num_kps, hm_size, hm_size), dtypenp.float32) scale hm_size / img_size for kp_id, (x, y, v) in enumerate(keypoints): if v 1: continue # 不可见点不生成热力图 cx, cy int(x * scale), int(y * scale) if cx 0 or cy 0 or cx hm_size or cy hm_size: continue xx, yy np.meshgrid(np.arange(hm_size), np.arange(hm_size)) hm[kp_id] np.exp(-((xx - cx) ** 2 (yy - cy) ** 2) / (2 * sigma ** 2)) return hmsigma的选取直接决定训练难度。sigma1时目标峰值尖锐网络必须精确定位容易在遮挡场景下抖动sigma2是大多数姿态估计任务的常用值兼顾精度和鲁棒性sigma超过 3 会让邻近关键点的热力图互相重叠尤其在手腕和手指靠近躯干的动作里监督信号变得模糊。图像尺寸和热力图尺寸的比例决定了输出空间的分辨率256x192输入配合64x48热力图是姿势估计里验证过的组合计算量可控且精度够用。3.2 数据增强组合与镜像 swap 规则健身动作数据集的增强策略和自然场景不同健身动作的拍摄背景相对固定、光线差异不大真正需要增强的是人体角度变化、肢体遮挡和尺度变化。随机旋转、随机缩放、水平翻转、部分遮挡这四类是基操其中水平翻转最容易出错。MIRROR_MAP { 0: 5, 1: 4, 2: 3, 3: 2, 4: 1, 5: 0, # 左手腕→右手腕等 6: 11, 7: 10, 8: 9, 9: 8, 10: 7, 11: 6, # 左肘→右肘等 12: 12, 13: 13, 14: 14, 15: 15, 16: 16 # 鼻子、脊柱等自对称点 }水平翻转图片时左右对称的关键点必须交换标签。比如原图里左肩在画布左侧翻折后左肩跑到右侧如果还用原来的索引去监督网络会学到错误的空间关系导致推理时左右手来回抖动。骨盆、脊柱、鼻子这类人体中线上的点保持不变不需要 swap。每份数据集的关键点顺序可能和 COCO 17 点不同但 swap 规则要根据数据集自带的左右对称关系重新定义不能直接套用。增强还有个细节旋转和缩放要作用到坐标上不能只对图片做变换。工程实现时一般把图片变换矩阵和坐标变换矩阵统一用仿射变换处理一张图一个矩阵图片和坐标同时变换避免坐标和像素错位。import cv2 def affine_transform(img, kps, angle30, scale_range(0.7, 1.3)): h, w img.shape[:2] M cv2.getRotationMatrix2D((w // 2, h // 2), angle, np.random.uniform(*scale_range)) img_t cv2.warpAffine(img, M, (w, h)) ones np.ones((len(kps), 1)) kps_homo np.concatenate([kps[:, :2], ones], axis1) kps_t (M kps_homo.T).T return img_t, kps_t这份增强函数把旋转和缩放合并成一次仿射变换关键点坐标通过同一个矩阵变换保证坐标和图像像素严格对齐。注意增强后的关键点可能跑到图像边界外训练时要过滤掉边界外的点否则热力图会在边界处产生被截断的高斯分布干扰训练。3.3 归一化与可疑样本的过滤图像送入网络前通常要归一化到[-1, 1]或按 ImageNet 的均值和方差做标准化这一步每个框架有不同的实现方式PyTorch 里直接用torchvision.transforms.Normalize。坐标方面如果标注是像素坐标生成热力图时会经过缩放如果标注已经是归一化坐标则要乘上热力图尺寸再生成高斯分布。def normalize_annotations(kps, img_w, img_h): # 将像素坐标转换为归一化坐标 kps_norm kps.copy().astype(np.float32) kps_norm[:, 0] / img_w kps_norm[:, 1] / img_h return kps_norm可疑样本的过滤也是一道必须做的工序。健身数据集采集时经常出现人员快速移动导致的运动模糊、身体局部出框、两个人互相遮挡等情况。一个简单有效的过滤策略是计算每张图可见关键点数量低于总关键点数的 30% 直接剔除再算关键点之间的两点距离远大于图像对角线长度时说明坐标解析有问题也剔除。这个步骤虽然看起来粗暴但能有效防止训练集里混入大量残次标签。4. 模型选型与训练配置半小时跑通一个关键点检测基线4.1 不同任务场景下的模型选型关键点检测模型的选型取决于部署场景。如果是实时动作纠错的移动端或嵌入式设备优先考虑轻量级网络比如 MobileNetV3 作为主干配合反卷积头部做热力图预测如果是对精度要求高、算力充足的离线分析场景直接上 HRNet-W32 或 W48多尺度特征融合带来的精度收益非常明显。中间的平衡点是使用 ResNet50 加简单的反卷积头部训练速度快、部署灵活、精度也能接受适合先跑通完整流程。数据集规模也是选型依据。健身动作关键点数据集通常有几万张图在这种量级下ResNet50 的反卷积方案比 HRNet 更容易收敛HRNet 需要更长的训练时间和更精细的调参。第一步先把 ResNet50 的基线跑通验证数据管线没问题再升级到 HRNet 追求精度上限这个思路在工程上最稳妥。4.2 用一份配置启动训练训练配置中输入尺寸、热力图分辨率、batch size、学习率和 loss 函数是五个必须显式设置的参数。推荐一组可以快速开始的配置参数推荐值备注输入尺寸256x192速度和精度均衡热力图尺寸64x48输入尺寸的 1/4优化器Adambetas(0.9, 0.999)初始学习率1e-3配合 warmup预热步数500 步避免早期震荡学习率调度cosine 退火到 1e-5稳定性好batch size32单卡显存 8GB 可跑训练轮数60 epoch基线够用损失函数加权 MSE 或 AdaptiveWingLossMSE 优先起步import torch import torch.nn as nn criterion nn.MSELoss() model ResNet50_Keypoint(num_keypoints17) optimizer torch.optim.Adam(model.parameters(), lr1e-3) scheduler torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max60) for epoch in range(60): model.train() for images, heatmaps, masks in train_loader: images, heatmaps, masks images.cuda(), heatmaps.cuda(), masks.cuda() preds model(images) loss criterion(preds * masks, heatmaps * masks) optimizer.zero_grad() loss.backward() optimizer.step() scheduler.step()这段代码里最容易忽略的是masks。它不是图像掩码而是指示每个关键点是否可见的监督权重形状和热力图一致。把preds * masks和heatmaps * masks同时做乘法loss 只在可见关键点的位置上计算不可见点的梯度归零。没有这个操作前面花半天时间处理可见性标签就白费了。4.3 迁移学习与 loss 细节关键点检测不能从零开始训练除非数据集规模在十万张以上。常见的做法是加载 COCO 人体姿态预训练权重然后在健身动作数据上微调。预训练权重让网络已经具备了人体结构的先验比如手肘不会长到脚踝上微调时只需要适应健身动作的具体姿势变化和场景特征收敛速度和精度都会有明显提升。# 加载预训练权重并跳过最后输出层 pretrained torch.load(coco_pretrained.pth, map_locationcpu) state_dict model.state_dict() ckpt {k: v for k, v in pretrained.items() if k in state_dict and output not in k} state_dict.update(ckpt) model.load_state_dict(state_dict)加载预训练权重时输出层的权重不要加载因为 COCO 是 17 个关键点但健身数据集可能有不同的关键点数量或顺序。其余层的权重可以直接迁移。head 层要从随机初始化开始训练初始学习率可以比主干略大比如主干的lr1e-3、head 的lr2e-3这样新结构能更快适应任务同时保证主干特征不被破坏。loss 层面如果数据集的标注存在噪声MSE 对离群点过于敏感换成 Smooth L1 或 AdaptiveWingLoss 能减少异常标注的干扰。不过 AdaptiveWingLoss 有额外的参数需要调整基线阶段还是建议先用 MSE等精度瓶颈出现后再换。5. 避坑关键点检测数据集最常见的五处翻车现场5.1 坐标体系搞混归一化坐标当像素坐标用拿到一份数据集标注说明里写着坐标是归一化的训练前忘了检查直接乘热力图尺寸去生成高斯分布结果所有关键点的热力图都挤在图像左上角模型训练完全无法收敛。这个问题的诡异之处在于 loss 并不一定很大网络会拼命把输出均值压低来匹配一个错误的监督信号。解决写一个数据检查脚本把每张图的坐标范围和图像宽高对比如果坐标最大值不超过 1说明是归一化坐标如果坐标值和图像宽高量级接近就是像素坐标。两种坐标在热力图生成前统一换算到热力图分辨率空间。5.2 镜像增强时左右关键点没有 swap健身动作对左右手、左右腿的区分非常敏感弓步蹲的时候左腿和右腿的位置完全不一样。增强代码里只做了cv2.flip(img, 1)关键点坐标也做了水平翻转但忘了把左右腿的标签对调导致网络看到的是左腿位置标着右腿标签训练出来的模型在做对称动作时左右摇摆同一段视频里前几帧和后面几帧的左腿预测忽左忽右。解决按数据集定义画一张左右关键点对应表翻图之后先 swap 再变换坐标。用上面给的MIRROR_MAP思路镜像映射表的正确性直接决定了模型对左右肢体的判别能力。5.3 不可见关键点被强行参与训练健身动作里身体自遮挡很常见比如俯身划船时手臂下垂肘关节可能被躯干挡住。如果标注可见性标记了v0但热力图生成时没有跳过训练时就会给网络一个完全没有依据的监督信号模型被迫在遮挡区域找一个并不存在的峰值。解决热力图生成函数里显式检查v 1就跳过该点loss 计算时用遮罩把不可见点的梯度清零。这两个检查要同时做只做前者不遮 loss模型最终还是会学出一个倾向于在画面中央生成模糊峰值的错误模式。5.4 数据划分泄露验证集指标虚高到没参考价值健身动作数据集的图片通常来自连续视频帧相邻帧之间几乎一样。如果随机把 80% 的帧放进训练集、20% 放进验证集验证集里大量图片和训练集高度相似模型等于开卷考试验证集 PCK 轻松上 95%但部署到真实摄像头画面时性能暴跌。解决按视频或按动作分组划分数据保证同一个动作的连续帧全部属于训练集或验证集其中一边。如果数据集没有视频编号至少按文件名前缀分组前缀代表同一次拍摄。验证集要比训练集更苛刻宁可多放一些不同角度、不同遮挡程度的样本进去。5.5 骨架连接关系定义错误导致角度计算全部错误画骨架时发现手腕连到了对侧肩膀或者髋关节和膝关节连线交叉这种情况通常不是标注错了而是解析skeleton时索引偏移了一位。健身动作的评估系统依赖关节角度骨架连接错了深蹲膝盖夹角、硬拉髋关节角度全是错的动作评分系统直接报废。解决用数据集自带的skeleton字段把骨架画到图上和真实人体结构对照。检查顺序是先看中线点鼻子、脊柱、骨盆再看四肢对称性。这步应该在训练前做不在推理后做因为训练前的可视化只需要读标注文件出现了问题马上能改推理后才发现问题的话整个模型都要重新训练。6. 用可视化验证数据与模型一个能顶十次训练的调试技巧6.1 把关键点画回图像检查标注质量训练跑通之后不要只看 loss 曲线把验证集的预测结果可视化回图像肉眼过一遍。一张图画上标注关键点和预测关键点能直观看到模型在哪些动作、哪些角度、哪些遮挡场景下翻车。import cv2 def draw_skeleton(img, kps, skeleton, color(0, 255, 0)): out img.copy() for i, (x, y, v) in enumerate(kps): if v 0: cv2.circle(out, (int(x), int(y)), 3, color, -1) for i, j in skeleton: if kps[i][2] 0 and kps[j][2] 0: cv2.line(out, (int(kps[i][0]), int(kps[i][1])), (int(kps[j][0]), int(kps[j][1])), (0, 0, 255), 2) return out把验证集里预测结果偏差最大的 30 张图打印出来按动作类型分类统计马上能看出模型的薄弱环节。常见的情况是下蹲到最低点时膝盖周边关键点飘忽或者俯卧撑撑起瞬间手腕关键点抖动这类问题靠 loss 指标几乎看不出来只有可视化才会暴露。6.2 用帧序列验证动作连贯性静态图像上的关键点检测质量好不等于动作连贯。健身动作是连续运动过程单帧预测抖动会直接导致动作计数出现毛刺。把连续视频帧的预测结果写成视频逐帧播放关注骨骼点在时间轴上是否平滑移动。一个典型的失败模式是静态精度 90%但视频里某个关键点在一个小范围内高频抖动动作计数时每次抖动都会触发一次额外计数。解决方法是推理时加时序平滑常见做法是对最近 5 帧的坐标做指数移动平均严重抖动的点中值滤波。这个技巧放在训练完成后做不需要重新训练模型但能显著提升动作计数和姿态评估的可用性。我自己接手过一个模拟项目静态指标很好看一到视频推理就反复触发误计数最终用 5 帧滑动平均把毛刺全部抹掉问题才彻底解决。这段经历让我养成了一个习惯任何关键点检测模型训练完先跑一段视频看连贯性再谈精度指标。数据集的下载和格式解析只是开始可视化验证跑完这套方案才算真正能用。希望帮到你。本文还有配套的精品资源点击获取
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →