首页 / 资讯中心 / 文章详情

YOLOv8姿态估计实战:八段锦动作评分系统从训练到部署

YOLOv8姿态估计实战:八段锦动作评分系统从训练到部署 ★ FEATURED ARTICLE
简介这是一套基于YOLOv8的八段锦动作识别与练习指导系统面向计算机视觉、人工智能方向的高校学生及毕业设计开发者可完成目标检测、动作分类与可视化交互演示。资源共含97个文件以Python源码70个py为核心配套预训练模型权重pt、配置文件xml、说明文档txt及演示视频mp4整体压缩包约24.21MB结构覆盖模型训练、检测服务、可视化页面与部署指南。数据显示已有296人学习使用。内容不仅包含可运行的完整项目还提供可视化界面设计、核心指标曲线、混淆矩阵、F1曲线等评估工具便于答辩展示部署说明与README指引清晰简单配置即可运行适合毕业设计、课程设计或初期项目立项演示也适合新手学习YOLOv8实战流程。1. 用 YOLOv8 给八段锦动作打分这套毕设资源能省掉哪些事YOLOv8 做目标检测不稀奇但把它拆出 pose 分支做八段锦动作评估还能在答辩现场直接跑起来就是另一回事了。这个资源包我拆过一遍里面不是孤零零的训练代码而是从完整数据集、训练脚本、可视化界面到部署教程的一整套属于那种解压后照着文档走就能真实跑起来的关键点检测与动作指导系统。它解决的痛点是体育类或计算机类毕设想做 AI 方向又怕算法太偏被答辩老师问倒——基于人体姿态估计的动作规范性判断既能讲出深度学习的原理又能现场演示界面实时识别算是个很稳的选题。适合做毕设、课设以及想快速上手 YOLOv8-pose 的初学者。2. 方案选型与资源拆解为什么是 YOLOv8-pose包里到底有什么2.1 先对比一轮姿态估计方案里为什么最后选了 YOLOv8做动作评估第一步是把人体关键点提取出来。常见的方案不止一个我平时在项目里选型会先列一张对比表把精度、速度、工程集成难度都摆出来再拍板。方案关键点数量部署难度工程集成友好度选型倾向OpenPose18 / 25 / 135高依赖 Caffe 和复杂后处理一般输出格式重推理速度偏慢不选MediaPipe33 点低开箱即用生态闭环关键点格式和训练流程不好接进自己的卷积管线不选MoveNet17 点低轻量速度快但相同分辨率下精度一般没有统一训练接口不选YOLOv8-pose17 点低Ultralytics 一条命令训练能复用检测的训练、验证、导出链路UI 集成也成熟选用OpenPose 精度不错但依赖链太长了在毕设这种时间预算下光配环境就能耗掉一周MediaPipe 拿来做个 demo 很爽可真要训练自己的动作数据集、调整关键点权重就不那么顺手了。YOLOv8-pose 最大的优势是生态统一同一个框架里做检测和关键点训练时用yolo pose train推理时直接读权重后面接可视化界面也省事。所以这套资源选择它作为整个系统的主模型符合这种项目的实际诉求——不是追求某个指标登顶而是保证在“数据、训练、界面”这条完整链路里都跑得顺。2.2 资源包目录拆解源码、数据、界面各管哪一段解压后建议先顺着目录走一遍别急着跑命令。我拆完这个包之后整理的目录结构大概是这样的BajingYOLOv8/ ├── weights/ │ ├── yolov8n-pose.pt # 官方 COCO 预训练权重做迁移学习起点 │ └── best.pt # 基于八段锦数据训练后的权重 ├── datasets/ │ └── pose/ │ ├── images/ │ │ ├── train/ │ │ └── val/ │ ├── labels/ │ │ ├── train/ │ │ └── val/ │ └── pose.yaml # 数据集配置文件 ├── deployment/ │ └── 部署教程.md # 环境配置、训练、界面运行的完整说明 ├── ui/ │ ├── main_window.py # 可视化界面主程序 │ └── pose_utils.py # 关键点后处理、画骨骼线、动作判分工具 ├── tools/ │ ├── preprocess.py # 标注整理与数据集划分 │ └── draw_curve.py # 画损失曲线和指标曲线 └── requirements.txtweights里放了两份权重yolov8n-pose.pt是 COCO 预训练模型只做通用关键点识别best.pt是这个数据集训练出来的产物界面默认加载的应该是它。deployment/部署教程.md建议最先读里面写清楚了从创建环境到启动界面的顺序我后文讲的步骤和它基本一致但会补充一些它没写透的参数细节。tools/preprocess.py是容易被忽略的一环。YOLOv8 的 pose 标注不是常见的 JSON 或 XML而是每个 txt 文件一行对应一个目标类别、框的四个值再加上 17 个关键点的坐标和可见性。这个脚本做的事情就是把原始标注转成这种格式并按比例切分训练集和验证集。如果你拿到的数据集已经是 YOLO 格式这步可以跳过但建议还是跑一遍确认数据划分是随机的、没有混入顺序性偏差。2.3 先跑通最简推理确认权重和关键点输出是对的在碰界面之前我习惯先用一段最朴素的脚本验证模型能不能推理这样能把“模型问题”和“界面问题”隔离开。下面这段代码是包的常见用法直接基于 Ultralytics 的 Python API 写from ultralytics import YOLO model YOLO(weights/best.pt) results model.predict( sourcedatasets/pose/images/val/0001.jpg, # 换成你手上的任意图片或视频 conf0.5, # 关键点置信度阈值低于它的点视为不可信 device0, # 0 是 GPUCPU 环境改成 cpu saveTrue # 把标注结果保存到 runs/pose/predict ) keypoints results[0].keypoints.data # (B, 17, 3) 形状 print(keypoints)results[0].keypoints.data的形状是(B, 17, 3)B 是检测到的人数17 是关键点数量3 对应(x, y, visible)。visible 值为 2 表示标注可见、1 表示遮挡、0 表示该点在画面中不存在界面判分时要先筛掉 low visible 的点不然算角度会把动作判断带偏。跑通这段之后就可以确定权重文件、推理环境和关键点输出都没问题接下来所有操作都建立在“模型可用”这个前提上。3. 环境与数据准备按部署教程跑起来之前的三个前提3.1 conda 环境与 torch 版本匹配YOLOv8 的环境配置热搜里常年有人问原因在于 torch 装不对后面全白搭。我建议按下面顺序来每一行都值得看清楚再执行conda create -n bajing python3.9 -y conda activate bajing pip install torch torchvision --index-url https://download.pytorch.org/whl/cu121 pip install ultralytics先装 torch 再装 ultralytics这个顺序是有讲究的。Ultralytics 在上层它对 torch 版本有要求如果先把 ultralytics 装好再补 torchpip 可能会因为依赖冲突把 torch 重新装一遍白等半天。cu121对应 CUDA 12.1如果你的显卡驱动版本较老可以换成cu118具体以nvidia-smi里看到的驱动支持为准——这一块经常被形容为玄学但本质是驱动、CUDA、torch 三者要匹配不是随机问题。CPU 环境也能跑torch那行用默认源安装就行但不建议用 CPU 训练速度慢到怀疑人生。如果是 GTX 1660 Ti 这类 6G 显存的卡训练时设batch8、imgsz640是跑得动的后面训练一章会细说。装完环境记得验证一下import torch; torch.cuda.is_available()是否为 True这一步 10 秒钟能避免后面所有 CUDA 相关的报错。3.2 数据集目录与 pose.yaml 的正确写法数据集目录结构在 2.2 已经列过这里重点说pose.yaml。YOLOv8 训练时靠这个文件定位数据路径写错是最常见的翻车点而且报错信息不太直接常以AssertionError: train dataset not found这类形式出现。path: datasets/pose # 数据集根目录相对当前工作目录 train: images/train # 训练图片目录 val: images/val # 验证图片目录 kpt_shape: [17, 3] # 17 个关键点每个点保存 (x, y, visibility) names: 0: bajinji # 本数据集只有一个类别path用相对路径还是绝对路径如果报路径找不到直接改成/你的绝对路径/datasets/pose大部分项目用绝对路径能少生一肚子气。kpt_shape这里要特别留意[17, 3]表示 17 个点、每个点 3 个值。如果你用的是自定义关键点格式改动这里的同时界面端读关键点的代码也得同步改否则会出现第 5 章要讲的“数量不匹配”问题。对应的 labels 文件是纯文本每行表示一个人体目标class_id x_center y_center width height开头后面跟 17 个关键点的(x, y, visible)也就是一行一共 1 4 17×3 56 个数。坐标全部归一化到 0~1写的时候要注意别把像素坐标直接丢进去那是检测和关键点训练失败的高频原因。3.3 训练前的预处理把原始标注转成 YOLO 格式这个包里的tools/preprocess.py就是干这件事的。原始标注可能是从标注工具导出的 JSON也可能是别人打包好的 XML脚本负责统一转成 YOLO pose 的 txt并完成训练集/验证集的随机划分。python tools/preprocess.py \ --src-dir datasets/raw \ --out-dir datasets/pose \ --val-ratio 0.2--src-dir填原始数据所在目录--val-ratio 0.2表示留 20% 做验证集。执行后脚本会生成 n 个 txt 标注文件同时打印出每个类别的目标数量。这里要核对一个数类别数量必须是 1也就是只有bajinji。如果打印出来显示有噪音类别说明原始标注里有空标注或错误标签需要先清理不然训练一个多类别模型出来界面按单类别去画骨骼线就会错乱。跑完预处理再打开pose.yaml确认 train/val 路径和生成的images、labels目录能对上然后就可以进入训练环节了。4. 训练自己的关键点模型命令、参数与损失曲线判断4.1 训练命令与关键参数说明训练是整套资源里最耗时的环节也是值得反复调整的环节。命令本身不复杂复杂的是参数怎么配合你的硬件和数据量。yolo pose train \ datadatasets/pose/pose.yaml \ modelyolov8n-pose.pt \ epochs120 \ imgsz640 \ batch8 \ patience20 \ device0逐个说参数怎么理解。modelyolov8n-pose.pt是从 COCO 预训练权重开始微调比从头训练收敛快得多如果显存只有 4G可以换yolov8n-pose.yaml且配imgsz480精度会掉一些但训练时显存占用小很多。epochs120在 pose 任务里够用了前提是patience20生效——它表示连续 20 个 epoch 验证损失没改善就提前停止。这个机制是防过拟合的不要随手关掉。batch8在 6G 显存卡上是个安全值。如果报 CUDA out of memory优先降到 4而不是去换更小的模型因为显存不够影响的只是 batch-size强行调小 imgsz 反而会让关键点定位精度下降。device0指定第一张 GPU建议启动前用nvidia-smi看一眼是不是已经有进程占了显存。4.2 看损失曲线判断训练状态什么时候该停训练跑起来之后别干等着Ultralytics 会在runs/pose/train/下生成results.csv里面记录了每个 epoch 的 box loss、pose loss、cls loss 和验证集指标。用这个包自带的tools/draw_curve.py或者直接自己画我一般这样写import pandas as pd import matplotlib.pyplot as plt df pd.read_csv(runs/pose/train/results.csv) # 注意列名自带空格取列时按实际 CSV 为准 for col in [train/box_loss, train/pose_loss, val/pose_loss]: plt.plot(df[col], labelcol.strip()) plt.xlabel(epoch) plt.ylabel(loss) plt.legend() plt.savefig(loss_curve.png, dpi200)重点看val/pose_loss也就是验证集上的关键点损失。曲线在前几十个 epoch 快速下降然后趋平这是正常节奏。如果验证损失出现明显回升而训练损失还在降就是过拟合信号patience20应该已经触发早停没触发的话说明曲线在抖可以再等几个 epoch也可以直接停掉用当前验证指标最好的权重。这里顺带回应一下“yolov8 画损失函数曲线图”的常见困惑很多人开了训练就干等跑完了也不看曲线直接拿last.pt用。关键点任务里最低验证损失对应的不一定是最 后一个 epoch所以best.pt和last.pt要分清——界面默认加载的是best.pt你用last.pt替换训练出来的新权重时得先确认这一点。4.3 验证指标与权重选择训练结束后跑一次显式验证看看权重在验证集上的真实表现yolo pose val \ modelweights/best.pt \ datadatasets/pose/pose.yaml输出里会给出mAP50-95、pose AP等指标。对小规模数据集mAP50-95在 0.8 以上就可以接受关键点定位误差需要结合可视化的骨骼叠加来判断——打开runs/pose/val/下保存的预测图片看骨骼线和原图人体对齐程度这比单看一个数字更有说服力。如果发现多数图片里脚跟、膝盖位置偏差明显优先去检查 labels 的标注质量而不是堆 epoch。5. 避坑记录界面与推理部署时最容易翻车的五个点5.1 训练或推理时报 CUDA out of memory现象命令跑起来没几秒就报torch.cuda.OutOfMemoryError进程直接退出。原因imgsz 或 batch 超出显存容量也可能是别的程序占了显存。解决先降 batch 到 4 或 2再考虑降低 imgsz 到 480。顺序不能反过来因为关键点任务对输入分辨率更敏感。如果还不行检查nvidia-smi看显存占用是否被其他进程吃掉了训练前通过CUDA_VISIBLE_DEVICES0锁定单卡能避免多卡环境下的显存冲突。5.2 界面运行时摄像头画面黑屏或卡死现象界面能打开但视频区域一直黑或者几秒才刷一帧点了关闭也没反应。原因最常见的是界面主线程里直接循环调用cap.read()和model.predict()推理耗时把 UI 事件循环堵死了。摄像头被占用时还会读到空帧但不会报错。解决把视频读取和模型推理移到单独线程主线程只负责显示。读帧前必须先做cap.isOpened()检查读出来是空帧就跳过这一轮摄像头索引不对时测试cv2.VideoCapture(1)而不是盯着 0 不放。这个坑在运行界面代码时出现频率最高部署教程里如果没提多线程你大概率会撞上。5.3 界面文字显示成方块或乱码现象窗口标题、动作名称显示为“□□□□”。原因OpenCV 的cv2.putText不支持中文默认渲染不出汉字这在界面里显示“左右开弓似射雕”这类动作名时尤其明显。解决两个办法。一是在界面里全部用英文标签开发成本最低二是在画面上用 Pillow 把中文先画到透明图层再叠加到帧上效果自然但需要额外引入 PIL 并处理字体文件路径。毕设答辩时画面上的文字要能看清方块字非常减分。5.4 关键点索引与模型输出不对齐现象界面能跑画出来的骨骼线位置错乱比如肘关节连到了肩膀。原因模型输出是 17 点但界面代码里写死了自己的一套关键点顺序和 COCO 约定的顺序鼻子、双眼、双耳、双肩…不同。你训练的时候改了类别数或关键点数量界面端没跟着改就会出现这种静默错误。解决训练后先打印model.model.yaml里的kpt_shape确认和界面读取代码一致同时对照 COCO 关键点索引表把界面里每个关节的连线顺序对一遍。这个错不报异常全靠肉眼排查是最耗人的一类坑。5.5 模型推理结果正常但界面一直没输出提示现象摄像头上人体的骨骼线画出来了但没有动作判分文字或者分数恒为 0。原因判分逻辑依赖的关键点可见性visible筛选把大部分点都过滤掉了或者界面代码读的是 0.5 版本之前的关键点坐标格式没适配新的可见性值。解决先输出原始关键点数据手动检查 visible 分布合理阈值一般设在 0.5。别把visible 2才视为有效那样遮挡帧就会全部判为无效分数当然恒为 0。判分函数里加一条日志输出当前参与计算的关键点数量比盯着分数猜要快得多。6. 可视化界面的判分套路从关键点到动作规范分数6.1 用余弦定理算关节角判分的关键一步八段锦动作规范与否落到代码层面其实就是几个关键角度是否落在合理区间。界面里pose_utils.py的核心函数本质是用三点算夹角以肘关节角度为例传入肩膀、肘部、手腕三个点的坐标取肘部为夹角顶点import math def calc_angle(a, b, c): # a: 肩, b: 肘, c: 腕b 是夹角顶点 ab (a[0] - b[0], a[1] - b[1]) cb (c[0] - b[0], c[1] - b[1]) dot ab[0] * cb[0] ab[1] * cb[1] dist_ab math.hypot(ab[0], ab[1]) dist_cb math.hypot(cb[0], cb[1]) if dist_ab 0 or dist_cb 0: return 0.0 cos_val max(-1.0, min(1.0, dot / (dist_ab * dist_cb))) return math.degrees(math.acos(cos_val))拿到角度后界面里会跟一组预设阈值比对输出“偏低/到位/偏高”的提示。阈值通常在代码顶部以字典形式集中定义换个动作式样只改字典值不用动判分逻辑。这是整个系统最值得讲给答辩老师听的部分——把姿态问题转化成可量化的角度判定。6.2 一个可持续运行的实时主循环界面主程序的视频处理部分哪怕引用了线程核心循环也是同样的结构读帧、推理、算角度、写提示。简化后就长这样while cap.isOpened(): ret, frame cap.read() if not ret: continue results model.predict(frame, verboseFalse)[0] kpts results.keypoints.data.cpu().numpy() # 对每个目标筛可见点 - 算关节角 - 比对阈值 - 拼提示文字 frame draw_pose(frame, kpts, thresholds) cv2.imshow(Bajing Judge, frame) if cv2.waitKey(1) 0xFF ord(q): break注意verboseFalse不然推理信息会刷屏界面性能也会被日志拖慢。从那以后我每次拿到一套带界面的 YOLO 工程包都会先跑一遍不带界面的推理脚本确认模型输出形状和关键点顺序没问题再去碰 UI 代码——这个顺序帮我省掉了大量无意义的排错时间希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?
咨询建站