☰
基于YOLOv8的宠物行为分析系统:完整源码、权重与部署实战
2026/10/12 12:07:28 网站建设 项目流程

简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的YOLOv8宠物行为分析完整项目,可直接用于毕业设计、课程设计或大作业。资源包含训练好的模型权重、完整数据集、可视化交互界面与部署说明,部署后即可运行,能输出核心指标曲线、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果及标签分布图,便于答辩展示与结果分析。压缩包共97个文件,约24.21MB,以70个Python源码文件为主,辅以pt模型权重、xml标注、pyc缓存及少量txt说明与mp4演示视频,结构清晰,覆盖训练、检测与界面服务等模块。目前已有46人学习。读者可据此快速复现完整流程,理解数据组织、模型训练与可视化评估思路,并在此基础上修改扩展功能,适合作为毕设或课设的可靠起点。

1. 从一份能直接跑通的宠物行为分析系统说起

如果你正在找一份能直接跑通的 YOLOv8 实战项目,尤其是带完整数据集、可视化界面和部署说明的那种,这份《基于 YOLOv8 的宠物行为分析系统》值得花时间拆一遍。它不是那种只丢几个脚本、缺权重、缺数据的半成品,而是把源码、best.pt 权重、五类行为检测服务、可视化页面、训练脚本和部署说明打包在一起的完整工程。拿到手后,按 README.txt 走一遍,基本能在本地把检测跑起来,看到视频里的宠物行为被框出来并打上类别标签。

这套东西解决的核心问题是:把 YOLOv8 从“能训练”推进到“能演示、能答辩、能交作业”。它适合计算机、人工智能、通信、自动化等专业的在校学生做毕设或课程设计,也适合刚接触目标检测、想找一个完整工程练手的新手。项目里已经包含五类宠物行为的检测逻辑、训练配置、评估指标输出,以及一个基于 PyQt 或类似框架的可视化界面,省去了自己从零搭界面的时间。接下来我会按“资源里有什么 → 怎么跑起来 → 怎么训练自己的数据 → 坑在哪 → 怎么改”的顺序,把这份资源拆成可复现的步骤。

2. 资源结构拆解:从 main.py 到 best.pt 的完整链路

2.1 目录里真正值得关注的几个文件

拿到压缩包后,先别急着双击 main.py。我一般会先扫一遍目录,确认权重、数据、服务脚本和界面入口是否齐全。这份资源里,下面这些文件是核心:

文件/目录作用是否必须
main.py可视化界面入口,启动后加载模型和视频是
five_type_det_service.py五类行为检测服务,封装推理逻辑是
model/best.pt训练好的 YOLOv8 权重,直接用于推理是
模型训练/train_mode.py训练脚本,支持自定义数据集训练时需要
模型训练/yolov8n.pt官方预训练权重,用于迁移学习训练时需要
abnoenal_video_five_type_test/测试视频目录,含 mp4 样本演示时需要
utils/数据加载、增强、指标、绘图等工具是
config/模型配置文件,含 rtmdet、faster-rcnn 等参考用
README.txt部署说明和运行步骤必读

从目录能看出,作者把训练和推理分开了:推理走 main.py + five_type_det_service.py + best.pt,训练走 模型训练/train_mode.py + yolov8n.pt。这种拆分对毕设答辩很友好,演示时不用等训练,直接加载权重就能出结果。

2.2 五类行为检测服务是怎么封装的

five_type_det_service.py 是整个系统的推理核心。它把 YOLOv8 的加载、预处理、推理、后处理封装成一个服务类,main.py 只需要调用这个服务,传入视频帧或图片路径,就能拿到检测结果。常见做法是继承 YOLO 类,重写 predict 或call,把类别映射和置信度阈值固定下来。

下面是我根据这类工程常见写法还原的一个简化版服务封装,你可以对照源码看结构:

# five_type_det_service.py 简化示意 from ultralytics import YOLO import cv2 import numpy as np class FiveTypeDetService: def __init__(self, weight_path, conf=0.25, iou=0.45): # 加载训练好的权重,best.pt 里已经包含五类行为的分类头 self.model = YOLO(weight_path) self.conf = conf # 置信度阈值,低于这个值的框会被过滤 self.iou = iou # NMS 的 IoU 阈值,控制重叠框合并程度 self.class_names = ['sitting', 'standing', 'walking', 'eating', 'sleeping'] def detect_frame(self, frame): # 直接传 numpy 数组,YOLOv8 内部会做 letterbox 和归一化 results = self.model.predict(frame, conf=self.conf, iou=self.iou, verbose=False) boxes = [] for r in results: for box in r.boxes: x1, y1, x2, y2 = box.xyxy[0].cpu().numpy() cls_id = int(box.cls[0].cpu().numpy()) score = float(box.conf[0].cpu().numpy()) boxes.append({ 'bbox': [int(x1), int(y1), int(x2), int(y2)], 'class': self.class_names[cls_id], 'score': round(score, 3) }) return boxes def detect_video(self, video_path, output_path=None): cap = cv2.VideoCapture(video_path) fps = cap.get(cv2.CAP_PROP_FPS) w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) writer = None if output_path: fourcc = cv2.VideoWriter_fourcc(*'mp4v') writer = cv2.VideoWriter(output_path, fourcc, fps, (w, h)) while cap.isOpened(): ret, frame = cap.read() if not ret: break detections = self.detect_frame(frame) for det in detections: x1, y1, x2, y2 = det['bbox'] cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2) label = f"{det['class']} {det['score']}" cv2.putText(frame, label, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2) if writer: writer.write(frame) cv2.imshow('Pet Behavior', frame) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() if writer: writer.release() cv2.destroyAllWindows()

这段代码的关键参数有三个:conf 控制检测框的严格程度,调高会减少误检但可能漏检;iou 控制重叠框的合并,宠物姿态变化大时可以适当调低;class_names 的顺序必须和训练时 data.yaml 里的 names 一致,否则会出现“框对了但标签错了”的翻车现场。源码里的 five_type_det_service.py 大概率还加了异常处理和日志,但核心逻辑就是上面这些。

2.3 可视化界面和推理入口怎么衔接

main.py 是界面入口,通常用 PyQt5 或 tkinter 搭一个窗口,上面放“选择视频”“开始检测”“停止”几个按钮,中间是视频显示区域。它不直接碰 YOLO,而是实例化 FiveTypeDetService,把视频路径传进去,服务层返回带框的帧,界面层负责显示。这种分层的好处是:你想换模型,只改服务层;你想换界面,只改 main.py。

我一般会先单独跑 five_type_det_service.py 里的测试代码,确认模型能加载、能出框,再去调界面。因为界面报错往往只是表象,真正的问题多半在权重路径或类别映射上。资源里带了 abnoenal_video_five_type_test 目录下的 mp4 样本,拿一个出来测,能最快验证整条链路是否通。

3. 本地部署实操:环境、权重、视频检测三步走

3.1 环境配置:Python 版本和依赖怎么定

这份资源的目录里有pycache/detect.cpython-39.pyc,说明作者用的是 Python 3.9。我建议直接对齐 3.9,避免 ultralytics 和 PyQt5 的版本冲突。常见做法是建一个 conda 环境:

conda create -n pet_yolov8 python=3.9 -y conda activate pet_yolov8 pip install ultralytics opencv-python PyQt5 numpy matplotlib pandas seaborn -i https://pypi.tuna.tsinghua.edu.cn/simple

ultralytics 会自动装 torch、torchvision 等依赖。如果你有 NVIDIA 显卡,想用 GPU 加速,需要去 PyTorch 官网按 CUDA 版本装对应的 torch。没有显卡也能跑,CPU 推理一张图大概几百毫秒,视频会慢一些,但演示够用。装完后用下面这行验证:

import torch print(torch.__version__) print(torch.cuda.is_available()) # 有显卡且驱动正常会返回 True

如果 torch.cuda.is_available() 返回 False,先别急着怀疑代码,大概率是 CUDA 版本和驱动不匹配。我一般会先用 CPU 把流程跑通,再折腾 GPU。

3.2 权重加载和路径问题

资源里有两个 best.pt:一个在 model/ 目录下,一个在 模型训练/ 目录下。推理用 model/best.pt,训练时用 模型训练/yolov8n.pt 做预训练起点。加载权重时,路径最好用绝对路径,或者用 os.path.dirname(file) 拼相对路径,避免从不同目录启动时找不到文件。

import os from ultralytics import YOLO # 用脚本所在目录拼权重路径,避免工作目录变化导致找不到 base_dir = os.path.dirname(os.path.abspath(__file__)) weight_path = os.path.join(base_dir, 'model', 'best.pt') model = YOLO(weight_path) # 打印模型类别,确认和你的预期一致 print(model.names)

model.names 会输出类别索引和名称的映射。如果这里输出的类别和你数据集里的不一致,后面画框的标签就会全错。这是血泪经验:先看 names,再跑推理。

3.3 跑通第一个视频检测

环境好了、权重能加载了,下一步就是拿测试视频跑一遍。资源里 abnoenal_video_five_type_test 目录下有 mp4 文件,直接用它:

python main.py

如果 main.py 是界面入口,启动后点“选择视频”,选中测试 mp4,再点“开始检测”。如果界面没弹出来,或者报错,可以先用命令行方式调服务层:

from five_type_det_service import FiveTypeDetService service = FiveTypeDetService('model/best.pt', conf=0.25, iou=0.45) service.detect_video('abnoenal_video_five_type_test/your_video.mp4', 'output.mp4')

命令行能跑通,说明模型和服务层没问题,问题就在界面层。命令行跑不通,就看报错是权重加载失败、opencv 读视频失败,还是类别映射越界。常见的是 opencv 读视频返回 None,原因是视频编码格式不支持,换一个 mp4 样本或者用 ffmpeg 转码即可。

3.4 训练自己的数据集:从 data.yaml 到 train_mode.py

如果你想用自己的宠物行为数据重新训练,资源里的 模型训练/train_mode.py 就是入口。YOLOv8 训练需要准备 data.yaml,里面写清楚 train、val 路径和类别名称:

# data.yaml train: ./dataset/images/train val: ./dataset/images/val nc: 5 names: ['sitting', 'standing', 'walking', 'eating', 'sleeping']

然后改 train_mode.py 里的参数:

from ultralytics import YOLO model = YOLO('yolov8n.pt') # 从官方预训练权重开始,收敛更快 model.train( data='data.yaml', epochs=100, # 毕设级别 100 轮通常够用,数据少可以降到 50 imgsz=640, # 输入尺寸,显卡显存小就降到 416 或 320 batch=16, # 批大小,显存不够就减半 device=0, # 0 表示第一块 GPU,CPU 训练写 'cpu' project='runs/train', name='pet_behavior' )

训练完成后,best.pt 会保存在 runs/train/pet_behavior/weights/ 下,把它替换到 model/ 目录,再跑 main.py,就能用新权重检测了。资源摘要里提到的混淆矩阵、F1 曲线、PR 曲线,YOLOv8 训练结束后会自动生成在 runs/train/pet_behavior/ 下,答辩时直接截图用。

4. 避坑与排查:权重、类别、显存和界面四个高频问题

4.1 现象:检测框位置对但标签全错

原因:训练时 data.yaml 的 names 顺序和推理时 class_names 的顺序不一致。YOLOv8 输出的是类别索引,索引到名称的映射一旦错位,就会出现“框对了但标签是另一个行为”。

解决:先打印 model.names,再对照 five_type_det_service.py 里的 class_names,确保顺序完全一致。如果源码里是硬编码的列表,直接改成从 model.names 动态读取,避免以后换数据集又错。

4.2 现象:CUDA out of memory

原因:batch 或 imgsz 设得太大,显存不够。GTX 1660 Ti 这类 6GB 显存的卡,跑 yolov8n 用 imgsz=640、batch=16 可能会爆。

解决:先把 batch 降到 8 或 4,再把 imgsz 降到 416。如果还爆,检查是不是同时开了其他占显存的程序。训练时可以用 amp=True 开启混合精度,能省不少显存。

4.3 现象:main.py 启动后界面卡死或闪退

原因:PyQt5 的事件循环和 OpenCV 的 waitKey 冲突,或者视频读取在主线程里阻塞了界面刷新。

解决:把视频检测放到 QThread 里,通过信号槽把帧传给界面显示。如果不想大改,可以先在服务层用 cv2.imshow 单独测试,确认模型没问题后,再排查界面代码。常见做法是界面只负责显示,检测逻辑全部丢到子线程。

4.4 现象:训练 loss 不下降或 mAP 一直很低

原因:学习率太大、数据标注质量差、类别不平衡,或者预训练权重没加载成功。

解决:先确认 yolov8n.pt 真的被加载了,可以看训练日志第一行有没有 “Transferred X/X items”。然后检查标注文件,YOLO 格式的 txt 里类别索引是否从 0 开始、坐标是否归一化到 0-1。如果某类样本特别少,可以在 data.yaml 里加权重,或者用增强手段扩充。

4.5 现象:换了自己的数据集后,验证集预测结果图全是乱框

原因:验证集路径写错,或者图片和标签文件名不对应。YOLOv8 要求 images/val 下的 jpg 和 labels/val 下的 txt 同名。

解决:写个脚本检查文件名匹配:

import os img_dir = 'dataset/images/val' label_dir = 'dataset/labels/val' img_files = {os.path.splitext(f)[0] for f in os.listdir(img_dir)} label_files = {os.path.splitext(f)[0] for f in os.listdir(label_dir)} missing = img_files - label_files print('缺少标签的图片:', missing)

把 missing 里的文件补上标签,或者从验证集里移除,再重新跑验证。

5. 进阶用法:把五类行为扩展到更多类别并验证指标

5.1 扩展类别时改哪几个地方

这份资源默认是五类行为,如果你想加“抓挠”“跳跃”等类别,需要同步改四个地方:data.yaml 的 nc 和 names、训练脚本里的模型头(YOLOv8 会自动根据 nc 调整)、five_type_det_service.py 里的 class_names、以及界面里如果有类别筛选也要改。改完后重新训练,不要直接在旧权重上微调新类别,否则旧类别的性能会掉。

5.2 用验证集指标判断模型能不能上答辩

训练结束后,runs/train/pet_behavior/ 下会有 results.csv,里面记录了每轮的 precision、recall、mAP50、mAP50-95。我一般会重点看三个数:mAP50 是否稳定在 0.8 以上、recall 是否明显低于 precision、以及验证集预测结果图里有没有大量漏检。如果 mAP50 高但 recall 低,说明模型偏保守,可以适当降低推理时的 conf 阈值。

import pandas as pd df = pd.read_csv('runs/train/pet_behavior/results.csv') # 看最后 10 轮的平均 mAP50 print(df.tail(10)[['metrics/mAP50(B)', 'metrics/precision(B)', 'metrics/recall(B)']].mean())

如果这三个指标都在 0.75 以上,答辩演示基本稳了。如果偏低,优先检查数据标注,而不是盲目加轮数。

5.3 一个我常用的验证习惯

每次换权重或改类别后,我不会直接跑完整视频,而是先抽三张验证集图片,用命令行跑单图推理,看框和标签对不对。确认没问题,再跑视频。这个习惯帮我省了很多“视频跑一半发现标签全错”的时间。从那以后我每次替换 best.pt 或改 data.yaml,都强制走一遍单图验证,再进界面演示。希望这份拆解能帮你把这份资源真正跑起来,而不是只躺在硬盘里。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询