ARTICLE DETAIL

资讯详情

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

基于YOLOv8的游泳动作识别系统:从数据准备到部署的完整实践

基于YOLOv8的游泳动作识别系统:从数据准备到部署的完整实践 简介一套基于YOLOv8的游泳动作识别系统完整工程包面向计算机视觉、人工智能等专业的毕业设计与课程设计场景解决动作识别从模型训练、指标评估到可视化界面展示的全流程需求。压缩包共97个文件以70个Python脚本覆盖检测服务、模型训练、工具函数等核心模块、4个pt模型权重、5个xml配置、txt使用说明及mp4演示视频为主整体仅24.21MB目录结构清晰按UI、模型训练、工具模块等分区组织便于定位修改。所有代码均经测试运行成功目前已有40人学习下载。除了可直接运行的源码和完整数据集外还提供可视化操作界面与部署教程可一键生成混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果和标签分布图等核心评估结果并包含标签分布统计便于答辩展示与效果验证。适合计科、人工智能、自动化、电子信息等相关专业学生快速落地YOLOv8应用也可作为课设、大作业或初期项目演示的参考。1. 先搞清楚YOLOv8在游泳动作识别里到底解决什么问题游泳动作识别和普通人体动作识别最大的不同在于目标尺度变化剧烈、背景水花干扰强、身体各部分互相遮挡。直接用VideoMA系列行为识别模型在那里做时序建模往往把水花和泳池壁也学进去了到了换一个泳姿角度就掉点。实际工程里更稳的做法是先做目标检测把人或者肢体关键区域框出来再基于框的空间位置和类别变化去判断动作。这套毕设资源正是沿着这个思路做的——用YOLOv8作为检测骨架配合五类动作标签把自由泳、蛙泳、仰泳、蝶泳、转身这类动作从视频流里实时识别出来。你拿到手的是一个可以直接跑起来的完整项目不是半成品示例。里面有训练好的best.pt权重、完整数据集、main.py启动入口、five_type_det_service.py推理服务模块还有一套可视化界面。对准备毕设答辩的同学来说最省心的一点是训练过程会产出核心指标曲线图、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果和标签分布图这些图表往PPT里一贴评审老师基本找不到追问点。下面我会从数据集准备、训练配置、服务封装、部署排错四个层面把整个项目拆开每一步都给出可以直接复用的命令和参数。2. 数据集与标注游泳动作识别的样本怎么准备2.1 数据集目录结构与五类动作定义资源里的数据集不是笼统的“图片文件夹”而是严格按YOLOv8训练格式组织的。根目录下能看到gB_9_s5_2019-03-07T16;31;4801;00_rgb_body_005.mp4这样的视频样本说明原始数据来自公开的游泳视频切片每个片段对应连续的动作过程。而labels目录下的txt文件与images目录下的jpg一一对应每个txt文件名与图片前缀相同内容格式是class x_center y_center width height这是YOLO系列通用的归一化坐标格式。五类动作的划分通常是自由泳freestyle、蛙泳breaststroke、仰泳backstroke、蝶泳butterfly、转身或蹬壁turn。如果原数据集没有直接给出类别名你会看到一个classes.txt文件里按顺序列出类别训练时YOLOv8会读取这个文件建立索引映射。我处理过不少类似项目最常见的问题是类别顺序与训练时的data.yaml不一致导致推理结果张冠李戴所以拿到资源后第一件事就是检查data.yaml里的names列表与classes.txt顺序是否完全一致。2.2 标注格式与YOLOv8的适配YOLOv8的标注格式要求每个目标一行五列数值。注意坐标是相对于图片宽高的比例值不是绝对像素。如下所示是一个典型的标注内容2 0.426 0.582 0.154 0.712 0 0.711 0.349 0.102 0.268第一列是类别ID后面分别是归一化后的中心点x、中心点y、框宽、框高。这里类别ID是2对应蝶泳0对应自由泳具体取决于classes.txt中的排列顺序。训练前最好写一个检查脚本确认所有标注值都在0到1之间并且没有空的txt文件——否则训练器会报“unused image”警告影响训练效率。如果你的原始数据是COCO格式或VOC格式需要先转换。这个资源里内置了general.py工具函数里面封装了coco2yolo和voc2yolo的转换逻辑。常见的做法是在utils目录下跑一行命令python general.py --source-dir ./annotations --target-dir ./labels --data-type coco参数说明source-dir指向包含JSON或XML标注的目录target-dir输出YOLO格式的txt文件>mosaic: 1.0 mixup: 0.2 hsv_h: 0.015 hsv_s: 0.7 hsv_v: 0.4 degrees: 10.0 translate: 0.1 scale: 0.5这些参数的意义分别是mosaic拼四张图训练提高小目标检测能力mixup按比例混合两张图及其标签hsv_h/s/v调整色调、饱和度、亮度的幅度degrees旋转范围translate平移比例scale缩放比例。游泳视频中人体一般较大不需要太大的平移和缩放保持translate: 0.1和scale: 0.5足够。如果发现五类动作数量严重不均衡优先收集少数类别的额外帧而不是简单复制已有样本。资源里提供了myutil.py里面有按类别统计样本数的函数count_class_distribution可以快速生成柱状图。我在实际项目里会先跑这个统计若某类低于总数的10%就在视频抽取阶段对该类帧按2倍频率抽样或者对图片做水平翻转、时序插值而不是直接在训练时调整类别权重——后者容易让模型在头部类别上产生误报。3. 模型训练从yolov8n到best.pt的完整流程3.1 预训练权重选择与模型结构资源内同时提供了yolov8n.pt和yolo11n.pt说明作者可能对比过不同版本的轻量模型。对于游泳动作识别我建议优先用yolov8n.pt作为预训练权重因为n版本参数量只有3.2M在CPU上也能跑推理而GPU训练时batch size可以开得比较大收敛更稳。如果你有足够的算力可以换成yolov8s.pt精度通常提升2到3个点但训练时间也相应增加。YOLOv8模型结构最核心的部分是C2f模块它替代了YOLOv5里的C3模块通过更丰富的梯度流让浅层特征和深层特征融合得更好。在游泳动作识别中C2f的设计能让模型同时捕捉到泳帽的局部特征和手臂划水的全局轨迹。best.pt就是经过完整训练后在验证集上mAP最高的权重文件它会自动保存在runs/detect/train目录下。3.2 训练参数配置与命令行训练入口在train_mode.py它封装了YOLOv8的train()方法。常见做法是直接在命令行里指定参数python train_mode.py --weights yolov8n.pt --data data.yaml --epochs 100 --batch-size 16 --imgsz 640 --device 0 --patience 20 --project runs/detect --name swim_train逐项说明weights指定预训练权重data指向数据集配置文件内部要写好train和val路径epochs是最大训练轮数游泳这类动作差异明显的任务100轮足够收敛batch-size根据显存调整8GB显存建议设为816GB以上可以到32imgsz输入分辨率640是精度和速度的平衡点device 0表示使用第一块GPUCPU推理用device cpu。patience是早停参数如果连续20轮mAP没有提升就停止训练避免过拟合浪费时间。训练时每轮结束会把best.pt和last.pt写入权重目录。best.pt是验证集mAP最高的模型last.pt是最后一轮的模型。部署时只用best.pt但如果训练后期出现过拟合last.pt反而在真实场景上更鲁棒这点和很多教程说的正好相反。3.3 训练过程中的指标监控与曲线图生成训练结束后runs/detect/swim_train目录里会生成大量结果文件。资源自动生成的可视化图表包括results.png包含训练损失、验证损失、精确率、召回率、mAP50、mAP50-95六个子图的趋势confusion_matrix.png混淆矩阵F1_curve.pngF1分数随置信度阈值变化的曲线PR_curve.png精确率-召回率曲线val_batch*.jpg验证集预测结果以及labels.jpg标签分布图。这些图表不是装饰品。答辩时评审最爱问的问题是“你怎么证明模型收敛”直接指results.png里训练损失和验证损失都下降且没有发散即可。而confusion_matrix.png能直观看出哪两类动作最容易被混淆——通常仰泳和自由泳因为手臂动作相似混淆严重。如果对角线颜色不够深说明需要在数据层面补样本而不是换模型。如果要重新生成这些曲线可以用工具脚本python detect.py --source ./val/images --weights best.pt --save-txt --save-conf --save-plot--save-txt保存每张图片的检测结果文本--save-conf保存置信度--save-plot保存带标注框的可视化图片。这组命令在验证集上跑一遍输出的predictions.csv可以直接用pandas透视出按类别统计的精确率。4. 可视化界面与推理服务把模型接到实际场景4.1 five_type_det_service.py 的服务封装逻辑这个文件是整个推理服务的核心。它不是简单的detect.py封装而是用类的方式把模型加载、预处理、推理、后处理串起来方便被main.py界面层调用。核心逻辑大致如下class FiveTypeDetService: def __init__(self, weights_path, conf_thres0.25, iou_thres0.45): self.model YOLO(weights_path) self.conf_thres conf_thres self.iou_thres iou_thres def predict_frame(self, frame): results self.model.predict(frame, confself.conf_thres, iouself.iou_thres, verboseFalse) boxes results[0].boxes return boxes.xyxy.cpu().numpy(), boxes.cls.cpu().numpy(), boxes.conf.cpu().numpy()这段代码里YOLO(weights_path)会加载best.ptconf_thres控制置信度下限iou_thres控制NMS的IoU阈值。返回值是每个检测框的左上右下坐标、类别ID和置信度。需要注意results[0].boxes中的坐标是原始像素坐标如果你要画在界面上直接使用如果要做时序统计需要把每帧的类别ID累积到一个队列里。4.2 detect.py 与 Detection_video.py 的调用差异detect.py是支持单张图片、图片文件夹、视频文件、摄像头等多种输入源的命令行推理脚本适合批量验证。Detection_video.py则专门针对视频流做处理增加了帧率统计和结果视频输出。两者最核心的差异在于是否逐帧保持检测框的时序一致性。Detection_video.py里有一个值得复用的技巧——用类别ID的历史投票来平滑单帧误检。比如连续5帧里至少有3帧判定为蛙泳才输出蛙泳结果否则保持上一动作状态。代码如下from collections import deque history deque(maxlen5) def smooth_predict(cls_id, conf): history.append(cls_id) if len(history) 5: return cls_id return max(set(history), keyhistory.count)这个平滑机制能有效抑制水花飞溅造成的单帧跳变。参数maxlen5表示使用5帧做投票帧率越高窗口应越长30fps视频下用5~7帧比较合理因為动作切换本身也需要几百毫秒不会因为平滑滞后太多。4.3 UI界面与实时显示main.py是可视化界面的启动入口通过PyQt5或Tkinter实现。界面通常包含视频源选择、开始/暂停按钮、实时检测结果画布、以及FPS与当前动作类别显示。核心是把five_type_det_service.predict_frame的输出绘制到QLabel上from PyQt5.QtGui import QImage, QPixmap def update_frame(self, frame): boxes, clss, confs self.service.predict_frame(frame) for box, cls, conf in zip(boxes, clss, confs): x1, y1, x2, y2 box.astype(int) cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.putText(frame, f{self.class_names[cls]} {conf:.2f}, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2) rgb cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) h, w, ch rgb.shape qt_img QImage(rgb.data, w, h, ch * w, QImage.Format_RGB888) self.video_label.setPixmap(QPixmap.fromImage(qt_img))这段代码演示了从模型输出到界面刷新的最短路径。class_names来自data.yaml中的names列表注意顺序要和训练时一致。界面程序运行时建议把verboseFalse传给predict否则终端会被每帧的检测日志刷屏影响界面流畅度。5. 部署排错与进阶让系统在毕设答辩和真实场景中站得住脚5.1 从main.py启动到GPU显存不足的排查main.py默认调用detect.py或five_type_det_service.py加载模型。最常见的启动报错是CUDA out of memory这是因为推理时batch_size被设置成了1但输入分辨率太大或显存被其他进程占用。排查时先用nvidia-smi查看显存占用然后强制使用CPU推理验证代码逻辑python main.py --device cpu如果CPU推理正常说明问题在GPU端的模型缓存。此时在服务初始化中限制显存使用量import torch torch.cuda.set_per_process_memory_fraction(0.7)这行代码把当前进程的GPU显存上限限制为总显存的70%避免因系统预留显存不足而报错。如果仍然溢出将imgsz从640降到512或者换用内存占用更低的yolov8n权重。5.2 动作识别准确率的提升技巧改anchor、调置信度YOLOv8默认anchor是通用COCO数据集的尺寸分布游泳动作中人体通常高度远大于宽度比例比较极端。如果你发现检测框漏掉手臂部分可以在train_mode.py中开启autoanchor开关python train_mode.py --autoanchor True --epochs 20 --weights best.ptautoanchor会根据当前数据集的真实标注尺寸重新聚类生成9组anchor再在现有权重上微调20轮能让mAP提升1到3个点。这个操作很安全因为它是基于你自己的数据分布生成anchor不会破坏原有特征提取能力。如果你只做推理不改训练调整conf_thres是最直接的策略。游泳视频中水花反光容易让背景误检为人体默认0.25的置信度阈值在强反光场景下需要提高到0.45。不要怕漏检五类动作识别更看重的是连续几帧的类别一致性漏掉一两帧远比误报一类动作影响小。5.3 把推理结果导出为热力图或统计报告毕设答辩时如果只展示实时检测框说服力有限。资源里myutil.py包含一个绘制动作时间线热力图的函数能在一整段视频下方输出泳姿切换的时间分布。调用方式如下python myutil.py --video ./test.mp4 --weights best.pt --output ./result_heatmap.jpg这个脚本会逐帧推理记录每帧的动作类别然后以时间为横轴、动作类别为纵轴绘制彩色热力图。裁判和评审老师能一眼看出运动员在某个时刻切换了泳姿这比一堆PR曲线更有冲击力。如果要在论文里展示定量结果还可以把每帧的类别输出为CSVpython Detection_video.py --source ./test.mp4 --weights best.pt --save-csv ./per_frame_labels.csv生成的CSV包含frame_index, class_id, class_name, confidence四列用Excel透视就可以统计各动作持续时间和占比。这些数据是毕设最终章对比实验的素材比如对比不同置信度阈值下的动作识别准确率。建议答辩前用这个模式跑完5段完整游泳视频整理出每段视频的动作切换表这样无论评审问到数据分布还是模型鲁棒性你都能拿出实际数字。本文还有配套的精品资源点击获取
返回列表