news 2026/9/26 1:56:36

yolov8行人检测毕设实战:从环境搭建到ONNX部署

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
yolov8行人检测毕设实战:从环境搭建到ONNX部署

简介:基于YOLOv8的行人检测系统,是一套面向计算机专业本科毕业设计的高分完整项目,曾获导师指导与评审认可,代码完整、可直接运行,特别适合正在筹备毕业设计的学生,以及需要课程设计、期末大作业或项目实战练习的学习者。资源内包含项目全部源码、多种规格的训练后权重模型、用于效果验证的示例图片、模型配置文件以及训练脚本和文档说明,能够覆盖从数据准备、模型训练到推理检测的常规流程,即使是基础薄弱的使用者,也能根据说明快速复现。整个压缩包共十五个文件,整体大小约一百五十五点七四兆字节,其中图片文件用于展示检测效果,权重文件对应不同精度与速度的模型版本,配置文件和脚本则支持自定义训练与融合策略,目录划分清晰,方便按需取用。目前已有一百一十六人学习下载,整体体量适中、应用价值明确,既可用于学术研究参考,也能作为工程化改造的起点。

1. 一套配齐源码+模型+数据的yolov8行人检测毕设,先搞清楚它装了什么

“基于yolov8的行人检测系统源码+训练好的模型+全部数据”这类毕业设计项目,在现在的CSDN和GitHub上几乎成了标配打包形式。我拿到手的第一反应不是先翻文档,而是先验证一件事:这套代码在我的机器上,能不能把一张行人照片直接推出结果。如果模型路径和源码对不上,后面所有训练都是在补无底洞。这套项目的完整形态一般包含三块:训练脚本和推理脚本组成的源码、一个或多个训练好的.pt权重文件、以及标注好的行人检测数据集。对毕设来说,它们分别对应三个验收点——系统能不能跑、检测准不准、数据是不是你自己能讲清楚的。这篇文章按一条可复现的落地方案拆开讲,从环境搭建到数据组织、训练调参、避坑、导出部署全覆盖,适合要交毕设的学生,也适合第一次碰yolov8行人检测的开发者照着自己电脑一步步复现。

2. 拆解yolov8行人检测项目的目录:源码、权重和数据集各管哪一段

2.1 拿到压缩包先看这四类文件:训练脚本、推理入口、配置、权重

解开压缩包后,常见目录形态是这样的:

pedestrian_detect/ ├── train.py # 训练入口 ├── detect.py # 推理入口 ├── utils/ │ ├── datasets.py │ └── plots.py ├── runs/ │ └── detect/ │ └── train/ │ └── weights/ │ ├── best.pt │ └── last.pt └── datasets/ └── pedestrian/ ├── data.yaml ├── images/ └── labels/

train.py负责读数据集和训练参数,detect.py负责加载权重推理。runs/detect/train/weights下面那两个.pt是核心交付物:best.pt是验证集上mAP最高的那一轮权重,last.pt是训练结束时的最后一轮权重。对毕设答辩来说,演示优先用best.pt;但如果你发现best.pt在个别测试图上出现过拟合,换成last.pt反而可能更稳。datasets/pedestrian目录就是“全部数据”所指的内容,YOLO系列项目的数据到这里全是图片配txt标签的平铺结构,具体组织方式下一节细说。

2.2 训练好的模型怎么被调用:ultralytics推理接口的最小用法

不管源码里封装了多少层,yolov8的推理核心就一段代码:

from ultralytics import YOLO # 加载训练好的权重,路径换成你自己的 best.pt model = YOLO("runs/detect/train/weights/best.pt") # 对单张图推理,conf 是置信度阈值,iou 是 NMS 阈值 results = model("street.jpg", conf=0.25, iou=0.45, imgsz=640, save=True)

model("street.jpg", ...)返回的是一个Results列表,每张图对应一个元素。取框和置信度时,用boxes属性:

for r in results: for box in r.boxes: # xyxy 是归一化前的像素坐标,conf 是置信度,cls 是类别 id x1, y1, x2, y2 = box.xyxy[0].tolist() conf = box.conf[0].item() cls = int(box.cls[0].item()) print(f"person: {conf:.2f} box: {x1:.0f},{y1:.0f},{x2:.0f},{y2:.0f}")

save=True会把画好框的结果图存到runs/detect/predict目录下,这是最快的“跑通”验证方式。参数里conf=0.25表示低于25%置信度的框全部丢掉,iou=0.45是NMS合并重叠框的阈值,imgsz=640会把输入图缩放成640x640再推理。这三个参数对行人检测的效果影响很大,后面第3章单独讲。

2.3 数据集的目录组织与标注格式:YOLO的txt标签到底写了什么

行人检测数据集的目录必须严格匹配data.yaml里的路径,否则训练直接报错。常见结构:

datasets/pedestrian/ ├── data.yaml ├── images/ │ ├── train/ │ └── val/ └── labels/ ├── train/ └── val/

images和labels文件名一一对应,图片是000001.jpg,标签就是000001.txt。txt里每行代表一个目标框,格式是:

0 0.521484 0.437500 0.183594 0.410156

五个数分别是类别id、归一化后的中心点x、中心点y、框宽、框高。这个关键点很反直觉:yolov8的标签不是左上角和右下角,而是中心点加宽高。我见过有人直接拿VOC的xml坐标换算成xyxy塞进txt,结果训练出来的模型框全部偏到图片右下角。

data.yaml是数据集的身份证:

path: datasets/pedestrian train: images/train val: images/val nc: 1 names: ["person"]

nc: 1表示只有一个类别,names里写person。如果你用的是基于opencv的传统行人检测做对照实验,这套YOLO格式的布局依然成立——只是传统方法吃的是图片,不吃txt标签。

3. ubuntu20.04上搭建yolov8环境:CPU版本也能把行人检测跑通

3.1 环境准备:从conda建环境到装ultralytics的完整命令

在ubuntu20.04上搭一套CPU版本的yolov8环境,是很多学生卡住的第一道坎。先装Miniconda,然后按下面的顺序执行:

# 创建独立环境,避免把系统 python 弄乱 conda create -n yolo python=3.10 -y conda activate yolo # 安装 ultralytics 库,yolov8 的训练和推理都封装在里面 pip install ultralytics # CPU 版本的 torch,不装 CUDA 版也能跑推理和训练 pip install torch torchvision --index-url https://download.pytorch.org/whl/cpu

这里有两个关键点。第一,必须用conda activate yolo把环境切过去,不然pip装到系统python里,后面import ultralytics会报ModuleNotFoundError。第二,CPU版本torch和CUDA版本不能混装,如果之前装过带cuda的torch,建议先pip uninstall torch torchvision再执行上面最后一行。装完后验证一下:

python -c "from ultralytics import YOLO; print(YOLO.__name__)"

能打印出YOLO就说明环境通了。很多人卡在“pip install ultralytics”这一步下载慢,常见的做法是加-i https://pypi.tuna.tsinghua.edu.cn/simple换国内源,但对毕设项目来说,等官方源一次装完反而少踩版本坑。

3.2 用训练好的模型跑一张行人照片:把推理保存到本地

环境就绪后,新建一个detect_pedestrian.py,写最简推理脚本:

from ultralytics import YOLO model = YOLO("runs/detect/train/weights/best.pt") results = model("test.jpg", conf=0.25, iou=0.45, imgsz=640, save=True) for r in results: # speed 字典包含预处理、推理、后处理耗时,CPU 上可以看到瓶颈在哪 print(r.speed) print(f"检测到 {len(r.boxes)} 个行人")

运行:

python detect_pedestrian.py

跑完看runs/detect/predict/test.jpg,如果框画在行人身上,说明模型和代码路径都对了。在这个CPU环境里,r.speed打印出的inference时间通常是几百毫秒到一两秒,取决于你的机器。这个脚本是整个系统的地基,之后接摄像头也好、接GUI也好,都是在这段代码外面包一层循环。

3.3 三个必调参数:conf、iou、imgsz对行人检测的影响

参数名作用推荐值调参方向
conf置信度阈值,低于该值的框被丢弃0.25行人太密容易漏检就调低到0.1,误检多就调高到0.5
iouNMS合并重叠框的阈值0.45行人互相遮挡严重时调低到0.3,减少重复框
imgsz输入缩放尺寸640小目标多就调成960,但CPU推理时间会翻倍

imgsz是这里面最容易忽略的参数。行人检测场景里,远处的小行人只有二三十个像素,用640推理可能直接漏掉,这时候调到960能明显提升召回。代价是计算量几乎翻倍,CPU环境下跑一帧从1秒变成2秒以上。我的建议是:先拿640跑通全流程,最后调优阶段再试960。iou在行人密集的街景里很关键,两个行人叠着走,阈值太高会把两个人都框成一个。

注意:CPU环境训练yolov8不是不行,但效率很低。如果你的项目数据量超过两三千张,建议找一台带NVIDIA显卡的机器跑训练,CPU只负责推理。gtx1660ti这类6G显存显卡跑yolov8n是够用的,后面训练章节会讲怎么设batch。

4. 用全部数据重新训练yolov8行人检测模型:从labelme标注到train.py参数

4.1 labelme标注数据转成YOLO格式:JSON转txt脚本

很多行人检测数据集是用labelme标注的,生成的是JSON文件。yolov8不认JSON,要先转成txt。这里给一个可以直接用的转换脚本:

import json import os def labelme_to_yolo(json_path, out_txt_path, target_label="person"): with open(json_path, "r", encoding="utf-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 != target_label: continue # labelme 的 points 是多边形顶点,这里取外接矩形 xs = [p[0] for p in shape["points"]] ys = [p[1] for p in shape["points"]] xmin, xmax = min(xs), max(xs) ymin, ymax = min(ys), max(ys) # 转成 YOLO 需要的中心点 + 宽高,并归一化 cx = (xmin + xmax) / 2 / img_w cy = (ymin + ymax) / 2 / img_h w = (xmax - xmin) / img_w h = (ymax - ymin) / img_h lines.append(f"0 {cx:.6f} {cy:.6f} {w:.6f} {h:.6f}") with open(out_txt_path, "w") as f: f.write("\n".join(lines)) # 批量转换:遍历 labels 目录下的所有 json for fname in os.listdir("labels"): if fname.endswith(".json"): labelme_to_yolo( os.path.join("labels", fname), os.path.join("labels", fname.replace(".json", ".txt")) )

脚本的逻辑是:把labelme的多边形顶点取最小外接矩形,再转成归一化的中心点坐标。这里有三个坑。第一,类别id必须从0开始,目标类别是person就写0,如果数据集里还有car,car就写1,顺序必须和data.yaml里的names一一对应。第二,imageWidth和imageHeight必须和原图实际尺寸一致,有些人标注完改了图没重新标注,归一化全错。第三,txt文件名必须和图片名完全一致,包括后缀替换方式,不然训练时找不到标签。

4.2 训练参数怎么设:epochs、imgsz、batch、patience

转换完数据,训练代码是纯ultralytics风格:

from ultralytics import YOLO # 用 yolov8n 的预训练权重做初始化,比随机权重收敛快很多 model = YOLO("yolov8n.pt") results = model.train( data="datasets/pedestrian/data.yaml", epochs=100, imgsz=640, batch=16, patience=20, device=0, # 0 表示第一张显卡,CPU 训练改成 "cpu" name="pedestrian", # 训练结果保存到 runs/detect/pedestrian )

gtx1660ti这类6G显存显卡,batch=16和imgsz=640刚好能跑起来,再往上加batch就报CUDA out of memory。如果没有显卡,device="cpu"也能训练,只是epochs=100可能要跑到天荒地老,建议把epochs降到30先验证流程通不通。

参数名作用经验值
epochs训练轮数100,小数据集50就够
patience连续多少轮验证集mAP不涨就早停20,防止过拟合
batch每批图片数6G显存用16,CPU用8
imgsz训练时的输入尺寸640

patience=20是一道保险,训练到第80轮如果val mAP已经不再提升,它会自动停,省时间。训练结束后,runs/detect/pedestrian/weights目录下会出现新的best.pt和last.pt,这就是你重新训练的模型。

4.3 画损失函数曲线图:把结果可视化,训练过程中随时监控

训练时想确认模型有没有在收敛,可以画损失曲线。ultralytics在训练过程中会把每个epoch的指标写进results.csv,读出来画图:

import pandas as pd import matplotlib.pyplot as plt # results.csv 是训练过程中自动生成的 df = pd.read_csv("runs/detect/pedestrian/results.csv") plt.figure(figsize=(10, 6)) plt.plot(df["epoch"], df["train/box_loss"], label="train box_loss") plt.plot(df["epoch"], df["val/box_loss"], label="val box_loss") plt.xlabel("epoch") plt.ylabel("loss") plt.legend() plt.grid(True) plt.savefig("loss_curve.png", dpi=150)

判断模型好坏看两条曲线的走势:train和val的box_loss都下降且最终贴近,说明拟合正常;train不断下降但val先降后升,说明过拟合了,需要加数据增强或调高patience提前停。这张loss曲线图放毕设论文里很好用,比贴一堆训练日志直观得多。

5. 行人检测训练易翻车的5个坑:数据标签、显存与评估的踩坑记录

5.1 现象:训练完模型把什么都框成行人,连路牌和树都不放过

原因:data.yaml里的names顺序和标签txt里的类别id对不上。常见做法是从某个数据集里白嫖了labels,但names写成了["person", "car"],而txt里的id=0其实代表car。解决:打开一个txt文件看id,再对照data.yaml逐个核对;不要想当然认为id=0一定是person。

5.2 现象:val精度高得离谱,测试集上一塌糊涂

原因:数据划分时train和val里有重复图片,或者补丁数据没做过去重,模型相当于“开卷考试”。解决:用图片的md5做一次全量去重,保证train和val的图片文件名没有任何交集;更严格的做法是用工具按场景划分,把同一段视频抽出来的帧全部放进同一个集合。

5.3 现象:gtx1660ti一跑训练就报CUDA out of memory

原因:batch和imgsz把显存挤爆了,6G显存撑不住16张640x640的图。解决:先batch=8、imgsz=640跑通,再把batch提到12;还不行就把model=yolov8n.pt换成yolov8n(n是nano,最轻量),不要一上来就用yolov8s或yolov8m。yolov8n在行人检测上的精度损失很小,但对显存友好得多。

5.4 现象:近处行人都能框住,远处的行人全漏检

原因:数据集里近景行人太多,模型没见过多少小目标。解决:训练时开mosaic增强(ultralytics默认最后一个epoch关mosaic,不用改),数据侧把小目标样本单独复制几份,或者把imgsz调到960训练。这里有个玄学点:同样的数据,imgsz=640训练出来的模型对远处小行人基本无解,但用960训一版,漏检率能低不少。

5.5 现象:CPU推理一帧要两秒,接了视频流直接卡成幻灯片

原因:常见写法是每帧都重新加载模型,或者每帧都做letterbox缩放、BGR2RGB转换,把时间耗在无关操作上。解决:模型只加载一次,放进循环外面;预处理统一用cv2.resize加等比例填充,不要每帧都申请新数组。如果还嫌慢,把conf从0.25提到0.4,能跳过大量低置信度框的后处理。对毕设的演示场景来说,实时性不如检测效果重要,卡一点没关系,但代码里要能讲清楚瓶颈在哪。

6. 导出ONNX模型并验证精度:把yolov8行人检测接到部署侧

毕设做到“模型能跑”只是及格,加分项是把模型导出成ONNX,证明它能脱离ultralytics独立部署。导出代码很短:

from ultralytics import YOLO model = YOLO("runs/detect/train/weights/best.pt") # 导出 ONNX,imgsz 必须和训练时一致,这里用 640 model.export(format="onnx", imgsz=640)

生成best.onnx后用onnxruntime验证:

import onnxruntime as ort import cv2 import numpy as np sess = ort.InferenceSession("best.onnx") input_name = sess.get_inputs()[0].name img = cv2.imread("test.jpg") img = cv2.resize(img, (640, 640)) # YOLO 的 ONNX 输入是 RGB、0~1 归一化、NCHW 布局 img = img[:, :, ::-1].transpose(2, 0, 1)[None] / 255.0 out = sess.run(None, {input_name: img.astype(np.float32)})[0] print(out.shape) # (1, 84, 8400),84 = 4个框坐标 + 80个类别概率 + 背景

ONNX的输出维度里,8400是候选框数量,4是xyxy坐标,1是person类的置信度。验证方法很简单:拿十张图分别跑pytorch版和onnx版,对比输出的框和置信度,误差在0.01以内就算成功。这一步在答辩时很有说服力,因为你可以直接说“这个模型能接到rk3588这类边缘设备上”。以前我图省事,训练完直接说部署,结果在目标设备上框的位置偏了十来个像素,后来养成了导出后先对标一次的习惯。模型能跑不算完,能复现才算,这算是我在这个项目上最值的一条经验,希望帮到你。

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/26 1:56:32

Dynamo packages.zip 正确解压与部署指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/26 1:56:21

Visual Studio 2026是假消息?真相与VS 2022实战升级指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/26 1:54:29

华科数据库实验MySQL 8.0.33实战包:开箱即用+避坑指南

简介:本资源是华中科技大学《数据库系统原理实践——以MySQL为例》课程的完整实验配套材料,面向计算机专业本科生及数据库初学者,聚焦数据库核心原理的动手验证与工程实现。资源共92个文件,主体为62个SQL脚本(覆盖建库…

作者头像 李华
网站建设 2026/9/26 1:53:02

DDIA精读指南:复制、分区与一致性决策,后端架构进阶必读

简介:《设计数据密集型应用程序》(DDIA)中文翻译版,面向后端工程师、架构师与数据库方向学习者,帮助系统理解分布式系统与数据存储的核心设计思想。资源共147个文件,以40个Markdown格式的章节译文为主体&am…

作者头像 李华