ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

基于YOLOv8的五禽戏动作识别系统:从数据集构建到部署全流程

基于YOLOv8的五禽戏动作识别系统:从数据集构建到部署全流程 简介这是一套面向计算机、人工智能、自动化等专业学生与教师的深度学习实践资源以YOLOv8为核心实现五禽戏动作识别适合作为毕业设计、课程设计或大作业的完整方案也便于初学者进阶学习。资源包共97个文件约24.21MB以70个Python源码文件为主体辅以4个pt模型权重、5个xml配置、12个pyc缓存及txt说明文档等涵盖模型训练、推理检测与可视化界面等模块。项目已完整测试运行包含源码、数据集、可视化页面与部署说明可生成核心指标曲线、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果及标签分布图帮助读者快速理解目标检测流程与评估方法。目前已有71人学习下载下载后打开README.txt即可按说明部署运行也可在现有代码基础上修改扩展实现其他动作识别功能。1. 从一段五禽戏视频说起YOLOv8 动作识别系统到底在做什么健身气功五禽戏一共十式虎、鹿、熊、猿、鸟各两式动作慢、幅度小、姿态相似度高人眼隔着屏幕都容易把「虎举」和「鹿抵」看混。把这件事交给视觉模型难点不在「有没有人」而在「这个人在做哪一式、做得对不对」。这套《基于 YOLOv8 的五禽戏动作识别系统》要解决的正是这个用 YOLOv8 做人体检测与关键姿态定位再叠加动作分类逻辑把一段手机拍的练功视频拆成逐帧的动作标签最后在一个可视化界面里回放、统计、纠错。它适合三类人做毕设或课程设计、需要一套能跑通全流程的完整工程的学生想入门 YOLOv8 训练自己数据集、又不想从零搭框架的开发者以及做体育教学、康复训练辅助工具的产品同学。整套东西包含源码、完整数据集、可视化界面和部署教程目标是简单部署即可运行但「能跑」和「跑得准」之间隔着数据、参数和一堆玄学下面按落地顺序拆开讲。2. 五禽戏数据集怎么建从采集到 YOLOv8 标注格式2.1 为什么动作识别不能只靠目标检测很多人第一反应是YOLOv8 检测「人」不就行了不行。五禽戏十式的差异全在四肢相对位置和躯干角度上检测框只能告诉你「画面里有人」给不出「手举过头顶还是平推向前」。所以这套系统的实际结构是两段式YOLOv8 先出人体框和关键点用 yolov8n-pose 权重再对关键点序列做动作分类。理解这一点后面数据集的标注方式就顺了——你既要标人体框也要保证关键点可见否则分类器拿到的是一堆残缺骨架。常见做法是直接用 COCO 预训练的 pose 权重做人体关键点自己只补动作类别标签。这样标注成本从「每帧画 17 个点」降到「每段视频打一个类别」对毕设体量来说现实得多。我一般会建议先跑通 pose 推理确认关键点在你的拍摄角度下稳定再决定要不要自己重标。2.2 采集与划分别让同一段视频同时进训练和验证五禽戏数据集的坑八成出在划分上。如果你把一段 30 秒视频切成帧随机 8:2 分到训练集和验证集那验证集里的帧和训练集里的帧几乎一模一样准确率能刷到 99%一换人就崩。正确做法是按「人 场次」划分同一个人、同一次拍摄的所有帧只能整体进训练集或验证集。一个可复现的目录结构如下wuxinqinxi/ ├── images/ │ ├── train/ # 训练帧jpg │ └── val/ # 验证帧jpg ├── labels/ │ ├── train/ # 对应 txtYOLO 格式 │ └── val/ └── data.yaml # 数据集描述文件data.yaml是 YOLOv8 训练的入口配置字段含义直接决定训练读什么path: /home/user/wuxinqinxi # 数据集根目录绝对路径最稳 train: images/train # 相对 path 的训练图目录 val: images/val # 相对 path 的验证图目录 nc: 10 # 类别数五禽戏十式 names: # 类别名顺序必须和标注 id 一致 0: hu_ju 1: hu_pu 2: lu_di 3: lu_ben 4: xiong_yun 5: xiong_huang 6: yuan_ti 7: yuan_zhai 8: niao_shen 9: niao_feinc和names的 id 必须和标注文件里的数字严格对应错一位就是全盘皆错而且训练不会报错只会默默学歪——这是最典型的黑匣子式翻车。2.3 用 labelme 标注再转 YOLO转换脚本与四个边界坑如果标题里给的是完整数据集通常已经标好了但你要加自己的动作就得自己标。常见工具是 labelme它输出 JSONYOLOv8 要的是归一化后的class cx cy w h。转换脚本不长但边界情况多import json, os from PIL import Image def labelme_to_yolo(json_path, out_dir, class_map): with open(json_path, r, encodingutf-8) as f: data json.load(f) img_w data[imageWidth] img_h data[imageHeight] lines [] for shape in data[shapes]: label shape[label] if label not in class_map: # 坑1未登记类别直接跳过别硬塞 continue cls_id class_map[label] pts shape[points] xs [p[0] for p in pts] ys [p[1] for p in pts] # 坑2坐标必须裁剪到图像范围内标注越界会算出负宽高 x1, x2 max(0, min(xs)), min(img_w, max(xs)) y1, y2 max(0, min(ys)), min(img_h, max(ys)) w, h x2 - x1, y2 - y1 if w 1 or h 1: # 坑3退化框丢弃否则训练出 NaN continue cx (x1 x2) / 2 / img_w cy (y1 y2) / 2 / img_h lines.append(f{cls_id} {cx:.6f} {cy:.6f} {w/img_w:.6f} {h/img_h:.6f}) name os.path.splitext(os.path.basename(json_path))[0] .txt with open(os.path.join(out_dir, name), w) as f: f.write(\n.join(lines)) class_map {hu_ju: 0, hu_pu: 1, lu_di: 2, lu_ben: 3, xiong_yun: 4, xiong_huang: 5, yuan_ti: 6, yuan_zhai: 7, niao_shen: 8, niao_fei: 9}逻辑说明class_map把中文或英文标签映射到 0 起始的整数必须和data.yaml的names完全一致。四个坑分别是未登记类别、坐标越界、退化框、以及第四个——图像尺寸以 JSON 里的imageWidth/Height为准不要用 PIL 重新读图因为标注时的图和实际图可能被旋转过两者不一致会让所有框整体偏移。参数上cx cy w h全部归一化到 0~1保留 6 位小数足够。3. 用 YOLOv8 训练五禽戏模型环境、命令与必调参数3.1 Ubuntu 20.04 上搭 YOLOv8 环境CPU 版也能跑标题说简单部署即可运行但环境这关该走的还得走。Ubuntu 20.04 是最省心的选择CPU 版适合没有独显的毕设机器GTX 1660Ti 这类卡则能明显提速。先建虚拟环境别往系统 Python 里装conda create -n wuxq python3.10 -y conda activate wuxq pip install ultralytics -i https://pypi.tuna.tsinghua.edu.cn/simple # CPU 版 PyTorch体积小、装得快 pip install torch torchvision --index-url https://download.pytorch.org/whl/cpu如果你有 NVIDIA 卡把最后一行换成对应 CUDA 版本的官方命令即可。装完用一行验证yolo checks它会打印 ultralytics 版本、PyTorch 版本、是否检测到 GPU。CPU 版这里会显示CPU不影响训练只是慢。参数说明python3.10是当前 ultralytics 兼容性最好的版本3.12 偶发依赖冲突国内源能省掉大量等待时间。3.2 训练命令与参数含义把 epochs 和 imgsz 讲透训练入口就一条命令但每个参数都影响结果yolo pose train \ modelyolov8n-pose.pt \ data/home/user/wuxinqinxi/data.yaml \ epochs150 \ imgsz640 \ batch16 \ lr00.01 \ patience30 \ projectruns/wuxq \ nameexp1逐项说明model用yolov8n-pose.pt是因为它自带人体关键点头n 是最小号CPU 也能训epochs150对十类动作通常够收敛太少欠拟合、太多过拟合imgsz640是精度和显存的平衡点五禽戏动作幅度大降到 416 会丢关键点batch16在 8G 显存上安全CPU 训练建议降到 4lr00.01是初始学习率数据量小于 2000 张时调到 0.005 更稳patience30表示 30 轮没提升就早停省时间。训练日志里重点看box_loss和pose_loss两条曲线前者不降说明框没学好后者不降说明关键点有问题。3.3 训练完怎么验证混淆矩阵比 accuracy 更值得看训练结束会在runs/wuxq/exp1/下生成confusion_matrix.png。别只看一个总准确率五禽戏里「虎举 vs 熊运」这种相似动作最容易混。打开混淆矩阵如果这两类的交叉格数值高说明模型分不清解决办法有两个一是补这两类的边界样本二是把imgsz提到 768 让手部细节更清楚。验证命令yolo pose val modelruns/wuxq/exp1/weights/best.pt data/home/user/wuxinqinxi/data.yaml输出里的mAP50和mAP50-95是核心指标前者宽松、后者严格。毕设场景下 mAP50 到 0.85 以上基本能看低于 0.7 就得回头查数据划分和标注。4. 可视化界面与部署把模型变成能点的系统4.1 可视化界面选型Gradio 还是 PyQt标题里的可视化界面落地时无非两条路。Gradio 适合 Web 端几行代码出界面能上传视频、显示结果部署到服务器就能远程访问PyQt 适合本地桌面程序打包成 exe 给答辩老师双击运行不依赖网络。毕设我更推荐 Gradio因为改起来快、截图好看、跨平台。一个最小可用的推理界面import gradio as gr from ultralytics import YOLO model YOLO(runs/wuxq/exp1/weights/best.pt) def predict(video_path): results model.predict(sourcevideo_path, saveTrue, conf0.5) # saveTrue 会把带标注的视频写到 runs/pose/predict 下 return results[0].save_dir /output.mp4 demo gr.Interface( fnpredict, inputsgr.Video(label上传五禽戏视频), outputsgr.Video(label识别结果), title五禽戏动作识别系统 ) demo.launch(server_name0.0.0.0, server_port7860)逻辑说明conf0.5是置信度阈值低于它的检测框不显示调高更干净但会漏检调低更全但误检多五禽戏建议 0.4~0.5。saveTrue自动落盘结果视频省去自己写视频编码。server_name0.0.0.0让局域网内其他设备也能访问答辩时用手机就能演示。4.2 部署到 RK3588 或普通服务器模型转换的注意点如果要把系统搬到 RK3588 这类边缘板YOLOv8 的.pt不能直接用得先转 ONNX 再转 RKNN。转换本身有官方工具链但坑在于pose 模型的输出头结构和检测模型不同转 ONNX 时要确认关键点分支没被裁掉。普通服务器部署就简单得多Docker 一把梭docker run -it --rm -p 7860:7860 \ -v /home/user/wuxinqinxi:/data \ python:3.10 bash # 容器内重复 3.1 的安装步骤再启动 gradio参数说明-p 7860:7860把容器端口映射到宿主机-v挂载数据集和权重避免每次重建容器都重装。CPU 服务器上单帧推理约 100~200ms一段 30 秒视频要等十几秒界面上最好加个进度提示否则用户以为卡死了。5. 避坑与排查五禽戏动作识别最常见的五个翻车现场5.1 训练 loss 正常但验证全错现象训练集 loss 一路下降验证集 mAP 始终 0.1 左右。原因数据划分时同一段视频的帧同时进了训练和验证或者data.yaml的val路径写错实际验证的是空目录。解决按人和场次重新划分打印len(os.listdir(images/val))确认验证集非空再跑一次。5.2 关键点全挤在画面中央现象推理结果里骨架点全部堆在图像中心像一团乱麻。原因训练时用了检测权重yolov8n.pt而不是 pose 权重yolov8n-pose.pt模型没有关键点头输出的是无意义坐标。解决确认model参数带-pose用yolo pose train而不是yolo detect train。5.3 换个人就识别不出来现象自己拍的验证集准确率很高换同学演示就频繁认错。原因数据集里只有一两个人的样本模型学到了「人」而不是「动作」。解决采集至少 5 个人、不同身高体型、不同背景的样本每类动作不少于 200 帧必要时做随机翻转和亮度增强。5.4 视频推理结果没有声音或时长不对现象Gradio 输出的视频比原视频短或者音轨丢失。原因OpenCV 写视频时默认丢音频帧率没对齐。解决推理时保持原帧率音频用 ffmpeg 单独合并ffmpeg -i result.mp4 -i original.mp4 -c copy -map 0:v:0 -map 1:a:0 output.mp4参数说明-map 0:v:0取结果视频的画面-map 1:a:0取原视频的音频-c copy不重新编码速度快。5.5 CPU 训练慢到怀疑人生现象一个 epoch 要跑半小时150 轮根本等不起。原因imgsz和batch设太大CPU 扛不住。解决CPU 训练把imgsz降到 416、batch降到 4epochs减到 80或者直接用预训练权重做迁移学习只训最后几层。实在不行就租一张云 GPU几小时的事。6. 让识别更准的一个技巧用关键点角度特征补分类纯靠 YOLOv8 pose 输出的关键点直接分类遇到「虎举」和「鸟伸」这种手臂都向上的动作还是会混。我后来加了一步从 17 个关键点里算三个角度特征——左右肘夹角、左右膝夹角、躯干倾斜角拼成一个 6 维向量再喂给一个轻量分类器SVM 或两层 MLP。这一步几乎不增加推理耗时但相似动作的区分度明显提升。import numpy as np def angle(a, b, c): # 计算 b 点处的夹角a/b/c 为 (x, y) v1 np.array(a) - np.array(b) v2 np.array(c) - np.array(b) cos np.dot(v1, v2) / (np.linalg.norm(v1) * np.linalg.norm(v2) 1e-6) return np.degrees(np.arccos(np.clip(cos, -1, 1))) def features(kpts): # kpts: 17x2COCO 顺序 l_elbow angle(kpts[5], kpts[7], kpts[9]) # 左肩-左肘-左腕 r_elbow angle(kpts[6], kpts[8], kpts[10]) # 右肩-右肘-右腕 l_knee angle(kpts[11], kpts[13], kpts[15]) r_knee angle(kpts[12], kpts[14], kpts[16]) torso angle(kpts[5], kpts[11], kpts[12]) # 躯干倾斜 return np.array([l_elbow, r_elbow, l_knee, r_knee, torso])逻辑说明angle用向量点积算夹角加1e-6防止除零。features取 COCO 关键点里肩、肘、腕、髋、膝、踝的位置输出 5 维角度。参数上角度对拍摄距离不敏感比原始坐标鲁棒得多。把这 5 维和 YOLOv8 的分类置信度拼接再训一个小分类器验证集上相似动作的混淆能降三成左右。验证方法很简单固定一段没参与训练的测试视频分别跑「纯 pose 分类」和「pose 角度特征」对比混淆矩阵里虎举/鸟伸那一格的数值。我自己的习惯是任何动作识别项目先跑通端到端再回头补特征工程别一上来就堆模型。这套五禽戏系统值不值得做取决于你要的是「能演示」还是「能实用」——前者照第 3、4 章跑通即可后者得在数据和特征上多花功夫。希望帮到你。本文还有配套的精品资源点击获取
返回列表