☰
YOLOv10车辆行人检测系统搭建:从数据训练到UI界面落地
2026/10/19 2:40:34 网站建设 项目流程

跑目标检测项目的朋友应该能感受到一件事:YOLO的版本迭代快得让人追不动,v5还没吃透,v8已经成主流,v9才在圈子里热闹过一阵,v10又来了。但绝大多数新版本真正拿到工程里去用,总有几个让人头疼的地方——要么训练时数据处理特别麻烦,要么推理前还要单独挂一个NMS后处理模块,要么就是精度和速度总有一个拉胯。前几天我把基于YOLOv10的车辆行人检测系统完整搭建了一遍,从数据集整理、模型训练,到UI界面和源码整合全程跑通,最大的感受是:这可能是目前对工程落地和毕设项目最友好的一个版本。这篇文章就把整个系统的实现过程、每个模块怎么设计、有哪些我已经替你踩过的坑全部梳理出来,给正在做智能交通、安防监控或者辅助驾驶场景检测的朋友一份可以直接参考的完整方案。

1. 项目整体拆解:它到底在解决什么问题

1.1 这套系统由哪几个模块组成

这个系统说白了就是给电脑装上一双眼睛。输入一张图片、一段视频或者摄像头画面,它能把里面的车辆和行人用框标出来,同时给出每个目标的类别和置信度。整套东西拆开来看,由四个部分拼起来:数据侧、训练侧、推理侧和界面侧。

数据侧负责准备车辆和行人的样本,做标注和格式统一,这是整个流程的地基。训练侧负责把YOLOv10模型在这些数据上跑通,得到能用的权重文件。推理侧负责加载权重,并对新的图像或视频做检测。界面侧则是用Python写的一个图形窗口,让不熟悉命令行的人也能点上几个按钮就完成检测。

这四块的关系就像经营一家小餐馆:数据集是菜谱和食材,训练是把菜做出来,模型是提前做好的半成品,UI界面是前台点餐和上菜的环节。每一环都可以独立研究和替换,所以哪怕你只对其中一块感兴趣,也能单独拎出来学习。文章后面会按这个顺序逐个展开,每一环都给了可以直接用的方案和命令。

1.2 为什么选YOLOv10而不是v8/v9

选择YOLOv10,最核心的理由是它的端到端设计。推理阶段不需要非极大值抑制,也就是常说的NMS。NMS一直是YOLO系列里绕不开的负担,它要做大量框与框之间的交并比计算来过滤重复框,既拖慢推理速度,又增加了部署难度。YOLOv10在训练时引入了一种双分支匹配机制,一个分支做一对多监督,一个分支做一对一匹配,训练完成之后把冗余分支去掉,推理直接输出最终结果,速度和实现复杂度都明显改善。

另一个理由是生态。YOLOv10代码库是基于ultralytics这套成熟框架的,训练接口、数据集格式要求、命令行参数,和很多人已经用惯的v5/v8系基本一致,迁移成本很低。再加上车辆行人检测这个任务本身类别少、目标尺度相对固定,对网络容量的要求不像通用目标检测那么高,用一个中等或者轻量级的权重就能交出不错的成绩,这对在CPU上做演示或者部署到边缘设备来说非常友好。

这里说句实在话,如果机器配置一般,又想把项目快速落地,轻量权重的性价比很高。如果是追求极致精度,那上大模型也不亏,但我不建议盲目追求最大的权重,后面训练部分会细说原因。

2. 环境搭建与数据集处理:最容易被忽视的地基

2.1 开发环境怎么搭才不折腾

YOLOv10的底层是PyTorch,所以环境的核心就三件事:Python解释器、PyTorch、CUDA版本匹配。推荐Python 3.9到3.11之间,直接用conda建独立环境是最稳妥的。

conda create -n yolov10 python=3.9 conda activate yolov10 pip install ultralytics

如果你使用的是官方开源仓库,也可以clone到本地后执行pip install -e .,这样可以用上仓库里预置的训练脚本和配置。GPU环境需要先安装和显卡驱动匹配的CUDA版本,再装对应版本的PyTorch,这一步的版本不匹配会在训练时引发各种诡异报错,比如常见的no kernel image available。最好的做法是去PyTorch官网,用安装命令生成器按自己的CUDA版本挑选命令,不要自己在pip里乱拼版本号。

除了核心依赖,还需要准备opencv-python、pillow、matplotlib,做UI界面则需要PyQt5。如果你是纯CPU机器,PyTorch的CPU版本也能跑,只不过训练速度会慢到怀疑人生,建议至少找一张支持CUDA的GPU,哪怕显存不大也比CPU强很多。

2.2 车辆行人数据集怎么构建和标注

车辆行人检测的数据集来源一般有两种:直接用公开数据集,或者自己做标注。如果做毕设、课程作业或者功能演示,直接抽取公开数据里的车辆和行人子集就够了。但如果你的目标是特定场景,比如自己学校的路口、小区停车场或者某个园区的出入口,公开数据集的效果往往一般,因为场景光照、摄像头视角、目标距离都不一样,最好还是自己采集一些样本做微调。

标注工具我最常推荐的是LabelImg,界面简单,导出格式可以方便地转成YOLO需要的txt。YOLO标注格式其实非常简单,每个txt文件对应一张图片,每一行代表一个目标:

class_id x_center y_center width height

注意这四个坐标都是相对于图片宽高的归一化值。举个例子,一张1920x1080的图片里,某个行人的框中心在(960,540),框宽200像素、高500像素,那一行就是:

0 0.5 0.5 0.1041 0.4630

类别id从0开始,必须和后面data.yaml里的类别顺序一一对应。这个顺序一旦定下来就不要乱改,否则训练完加载权重时类别会整体错位,到时候画面里明明框的是汽车,显示的标签却是行人,排查起来非常折磨人。

数据在放入模型前还要做划分。常规做法是训练集、验证集、测试集按7:2:1左右分配。如果整体样本量不大,可以先只划训练集和验证集,测试阶段直接用真实视频看效果。目录结构建议这样组织:

datasets/ ├── images/ │ ├── train/ │ └── val/ ├── labels/ │ ├── train/ │ └── val/

一个很容易踩的坑是路径。整个项目不要出现中文,很多人把项目放在桌面或“我的文档”下面,路径一出现中文,训练时轻则读不到图片,重则模型保存直接报错。把项目放到磁盘根目录的纯英文路径下,是最省心的处理方式。

2.3 data.yaml配置与类别顺序的坑

训练前还需要写一个data.yaml文件,用来告诉模型数据在哪、类别有哪些。内容大致如下:

path: datasets train: images/train val: images/val names: 0: person 1: car 2: bus 3: truck

这里names的顺序必须和标注文件里的class_id对应。如果你还想检测摩托车、自行车,就继续往后面加类别。不过类别不是越多越好,每增加一个类别,对数据量、训练时间的要求都会上升,尤其有些类别样本少时,会导致严重的类别不平衡,模型会对那一类频繁漏检。如果只是做车辆和行人两个核心类别,先把这两个做精,比贪多要实用得多。

还有一个细节容易被忽略:标注框的类别顺序、data.yaml的类别顺序、训练脚本里的类别列表,这三处必须完全一致。我见过不少项目在标注一半时改了类别顺序,结果训练时损失函数能收敛,但推理结果完全是乱的。所以我每次都建议训练前花两分钟把这三处对着检查一遍,可以省掉后面一整天的排错时间。

3. 模型训练与调参:从命令行到权重落地的关键步骤

3.1 训练流程与关键参数

训练默认从预训练权重开始,这是深度学习里非常划算的做法。YOLOv10官方提供了n/s/m/b/l/x几个尺寸的预训练权重,体积从几兆到几十兆不等。在命令行里可以直接执行:

yolo train data=data.yaml model=yolov10s.pt epochs=100 imgsz=640 batch=16

训练过程中会自动把模型、训练曲线、验证指标保存到runs目录下。几个关键参数的取值,我结合自己的经验给一个参考:

  • epochs:数据集样本量小的画30到50轮就够,样本多了可以加到100到150轮,不是越多越好,跑过头就过拟合了。
  • imgsz:默认640。如果画面里的目标很小,比如监控中远处的行人只占几十个像素,可以试着提到800或960,但显存占用也会跟着涨。
  • batch:根据显存来定,6G显存跑yolov10s建议8到16,跑m以上模型先试4。
  • device:有GPU就填device=0,没有GPU用CPU训练会等到让人崩溃,尽量别试。
  • pretrained:默认True,用预训练权重能让收敛速度快很多,数据集规模不大的时候提升尤其明显。

对于车辆行人检测,我一般会优先考虑s或m这两个尺寸。它们兼顾了速度和精度,轻量级权重在CPU上还能勉强跑推理,做演示不至于卡到没法看。最大号的模型虽然精度上限更高,但训练时间、显存占用、推理耗时都成倍增加,对小团队或者单机实验来说性价比并不高。

3.2 训练日志怎么读,loss曲线怎么看

训练过程中,日志里会持续打印几个指标:box_loss、cls_loss、dfl_loss,以及验证集上的mAP50和mAP50-95。很多人盯着数字跳来跳去就是看不懂,其实只要抓住健康曲线应该长什么样就行。

健康的训练是训练loss整体下降,验证集指标波动上升。如果训练loss降得很舒服,但验证mAP在某个epoch之后开始明显往下掉,那基本就是过拟合了,需要减小epoch、增大数据增强、或者开启早停。YOLOv10在训练结束时会自动比较历轮的结果,保存表现最好的权重weights/best.pt,你后面做推理和UI加载只用best.pt就行,别拿last.pt硬刚。

如果在日志里看到loss变成了nan,多半是学习率太大或者梯度爆炸。解决办法是把学习率调到0.01以下,或者减小batch再试。还有一种情况是loss死活不降,这通常不是模型问题,而是数据没配对好,比如data.yaml里的类别顺序和标注不一致,或者标注文件里出现了超出类别范围的id。

3.3 评估指标和模型导出

模型训练完不能只看mAP,一定要拿几段没参与训练的真实视频跑一遍,看漏检和误检情况。mAP50关注的是目标有没有被框住,mAP50-95则更严格,会同时评估框位置的准确程度。在车辆行人检测中,行人是最容易出问题的类别,因为行人姿态复杂、相互遮挡加上尺寸小,漏检率通常比车辆高。如果发现漏检多,优先检查训练数据里行人的样本量,以及尺度和姿态是否丰富,而不是盲目加训练轮次。

导出模型这一步很多人会忽略,但它对工程部署非常重要。要脱离PyTorch训练环境,推荐导出成ONNX格式:

yolo export model=runs/train/xx/weights/best.pt format=onnx opset=12

导出的ONNX文件不依赖PyTorch运行,可以在很多推理框架里加载,也为后面接入UI和实时流提供了更灵活的方式。我通常会在项目里同时保留PyTorch权重和ONNX两个推理入口,按部署环境切换。

4. UI界面搭建与源码组织:从命令行到点一点就能用

4.1 UI功能怎么设计才完整

一个能拿去给别人演示的系统,界面至少要支持图片检测、视频检测、摄像头实时检测三种输入方式。功能上再加三个东西,体验会好很多:置信度阈值滑块、结果展示区域、检测统计信息。

置信度阈值滑块让用户能实时调整灵敏度,低于阈值的检测框会被过滤掉。这个设计在演示时特别有用,因为现场画面光照复杂,固定的置信度阈值往往不够用——调高了漏检,调低了误报多,给用户一个滑块,比写死参数合适得多。检测统计信息在视频流里很有价值,可以直接在界面上显示当前画面里有多少辆车、多少人,很适合做展示汇报。

界面布局可以参考经典风格:左侧放功能按钮,中间是画面显示,右侧展示检测结果信息。这样设计的好处是即使完全不懂代码的人,拿到界面上手也能操作。我在工程里还会加一个状态栏,显示当前帧率,这样演示的时候观众能直观感受到模型速度,不用你费口舌解释“很快”。

4.2 核心代码怎么组织

UI层我用的是PyQt5,模型加载放在主窗体的初始化里。这个设计保证模型只加载一次,不会每检测一张图片就重新加载一遍权重,否则演示时会卡到让人崩溃。

from ultralytics import YOLO class MainWindow(QMainWindow): def __init__(self): super().__init__() self.model = YOLO("best.pt") self.conf_thres = 0.5

图片检测的槽函数里,调用模型预测,然后绘制并显示。这里有一个非常经典的坑:OpenCV读出来的图像是BGR顺序,直接显示到Qt里颜色会错乱,必须先转成RGB。

def detect_image(self, path): results = self.model.predict(path, conf=self.conf_thres) annotated = results[0].plot() rgb = cv2.cvtColor(annotated, cv2.COLOR_BGR2RGB) pixmap = QImage(rgb.data, rgb.shape[1], rgb.shape[0], rgb.strides[0], QImage.Format_RGB888) self.label_result.setPixmap(QPixmap.fromImage(pixmap))

视频和摄像头检测不能放在主线程里,否则一遇到推理耗时,界面就会直接“未响应”。正确做法是用QThread把帧读取和推理扔到子线程,主线程只负责刷新画面。在工程里,我会写一个VideoThread类,在run方法里循环执行cap.read(),对每一帧做predict,然后通过Qt信号把处理结果发回主线程。

摄像头检测和视频检测其实是同一套逻辑,区别只在于cv2.VideoCapture的参数,视频文件传路径,摄像头传0或1。想要切换摄像头,只需要给VideoThread增加一个index参数,封装两三个方法就够用了,不要重复写两套代码。

4.3 轻量级UI备选方案

如果你不想花时间调Qt布局,可以试试Gradio。Gradio是一个Python库,几行代码就能出一个网页版界面,支持上传图片、拖拽视频,对做成果展示来说完全够用。缺点也很明显,实时摄像头推流在Gradio里做起来没有原生界面顺手,如果你只演示上传图片和视频,Gradio完全可以顶上,代码量只有PyQt5的五分之一不到。

打包发布时,常见的问题有两个。一是PyInstaller打包后模型路径读不到,因为打包后的程序会解压到一个临时目录,原来的相对路径失效了,需要用sys._MEIPASS来定位真实资源路径。二是打包出来的exe体积很大,这是正常的,毕竟模型文件本身就近百兆。如果想要小体积,可以把模型导出成ONNX之后再用onnxruntime推理,打包体积能小一些,但流程上需要多写一套推理代码。

5. 常见问题排查与性能优化:实战中踩过的坑全记录

5.1 训练阶段的坑和解决思路

数据、配置都正常,训练却出各种怪毛病,这是每个做目标检测的人都绕不过去的阶段。整理一下我遇到过最多的情况。

显存不足是最常见的,报错信息通常是CUDA out of memory。第一次遇到不要慌,优先减小batch,从16减到8,再不行减到4,同时可以考虑把imgsz降到512。如果你还想保住大batch,可以开启梯度累积,相当于分几次小batch凑成一个大batch,但训练时间会变长。loss不下降或者下降极慢,多半是学习率不合适,或者data.yaml写错了导致类别错位。训练到一半数据读取卡住,先检查图片路径里有没有损坏的图片文件,可以给dataloader设置workers=0排查。

还有一个非常隐蔽的坑:训练时验证集mAP看起来还挺高,但一到真实场景效果就很差。这种情况下,问题通常出在训练数据和真实场景差异太大,而不是模型结构有错。解决办法是采集真实场景的图片做针对性微调,而不是继续堆epoch。比如我用公开数据训练出来的模型,在室内测试效果不错,但拿到停车场夜间的画面就频繁漏检,补了几百张夜间图片微调之后才明显改善。

5.2 推理性能优化到底怎么做

如果只是做演示,直接加载best.pt就够了。但如果你打算跑摄像头实时监控,建议先做一个推理时间的压测。默认FP32精度下,YOLOv10在中等配置的GPU上处理640x640输入,通常稳定在几十毫秒以内,跑实时没问题。如果还想更快,有三个方向可以尝试:

方向一是导成ONNX格式,用onnxruntime加载推理。onnxruntime比PyTorch自带的推理路径更轻量,CPU上也能明显提速,而且不依赖特定的Python训练环境。方向二是用TensorRT加速,这个能在GPU上带来明显收益,但TensorRT生成的引擎和GPU型号强相关,换一张显卡可能要重新生成引擎文件,调试成本略高。方向三是把输入尺寸从640降到416,推理速度可以提升不少,代价是远处小目标的检测效果会下降。

我的建议是,工程里同时保留PyTorch和ONNX两套推理入口,调试的时候用PyTorch权重,部署上线的时候切到ONNX。这样既保持了开发阶段调试的便利性,又能获得部署阶段的性能提升。TensorRT可以作为进阶优化手段,等前面两条路走通之后再考虑。

5.3 常见问题速查表

现象可能原因解决办法
训练显存不足batch太大或imgsz太高减小batch到4或2,imgsz降到512
loss变成nan学习率过大或梯度爆炸调低lr,降低batch
验证mAP不高数据量少或类别不平衡补充样本,使用预训练权重,增加数据增强
漏检远处行人小目标样本不足提升imgsz,单独补充小目标样本
UI播放视频卡顿推理放在主线程用QThread处理,只把结果回传主线程
摄像头画面花屏摄像头索引冲突检查VideoCapture的index是否被占用
中文路径读不到图片路径编码问题项目放在纯英文路径下
导出ONNX后效果变化输入尺寸或预处理不一致保持训练时的imgsz和归一化方式一致
模型加载慢权重文件大或CPU推理换小模型,或导出ONNX加速
打包后模型路径报错相对路径失效用sys._MEIPASS定位资源路径

这张表格里的每一行,都是我实际跑项目时碰到过的场景。有些问题看起来是小事,不处理却能浪费一整天,比如路径里的中文问题,报错信息还不一定会直接提示。

写到最后,说点自己的体会。做这类检测系统,最难受的往往不是训练本身,而是数据、训练、界面三个环节之间的衔接。很多朋友模型已经跑得不错,却在UI集成时把BGR和RGB搞反,或者在数据路径上反复折腾。这套基于YOLOv10的车辆行人检测系统,从项目组织上讲其实很清晰,每一块都可以独立替换。如果你只想复现一个能跑的效果,建议先把第2章的数据准备好,再照第3章的跑命令训练,界面先从图片检测写起,跑通之后再接视频和摄像头。最后分享一个小技巧:训练前把标注文件的类别id、data.yaml里的names、训练脚本里的类别列表三者对着检查一遍,这三处的顺序是最容易被忽略、却影响最严重的一环。

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

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

立即咨询