简介:一套基于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;48+01;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显存建议设为8,16GB以上可以到32;imgsz输入分辨率,640是精度和速度的平衡点;device 0表示使用第一块GPU,CPU推理用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.png(F1分数随置信度阈值变化的曲线),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_thres=0.25, iou_thres=0.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, conf=self.conf_thres, iou=self.iou_thres, verbose=False) boxes = results[0].boxes return boxes.xyxy.cpu().numpy(), boxes.cls.cpu().numpy(), boxes.conf.cpu().numpy()这段代码里,YOLO(weights_path)会加载best.pt,conf_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(maxlen=5) def smooth_predict(cls_id, conf): history.append(cls_id) if len(history) < 5: return cls_id return max(set(history), key=history.count)这个平滑机制能有效抑制水花飞溅造成的单帧跳变。参数maxlen=5表示使用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列表,注意顺序要和训练时一致。界面程序运行时建议把verbose=False传给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曲线更有冲击力。如果要在论文里展示定量结果,还可以把每帧的类别输出为CSV:
python 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段完整游泳视频,整理出每段视频的动作切换表,这样无论评审问到数据分布还是模型鲁棒性,你都能拿出实际数字。
本文还有配套的精品资源,点击获取