尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

基于YOLOv8的雾天车辆行人检测系统实战解析

基于YOLOv8的雾天车辆行人检测系统实战解析 简介目标检测是计算机视觉领域的核心任务在智能交通与安防监控中具有广泛应用。然而雾天环境下图像对比度降低、边缘信息弱化导致传统检测模型精度显著下降。YOLOv8作为高效的一阶段检测框架凭借anchor-free设计与C2f特征提取模块成为雾天场景下的理想基础模型。通过合成雾增强、亮度对比度扰动等数据增强策略可有效模拟雾天数据分布提升模型泛化能力。结合PyQt5构建的GUI系统实现图片、视频、摄像头三种输入模式的实时检测与结果导出支持车辆与行人的精准定位。该方案覆盖数据准备、模型训练、推理部署全流程为雾天监控、自动驾驶等实际应用提供了可靠的技术支撑。 雾天环境下的车辆和行人检测说实话是目标检测落地时绕不开的一个坎。普通模型在晴天数据上刷得再高一到雾天、霾天精度掉得让人头疼因为图像对比度低、边缘信息弱模型很容易漏检。我做的这套系统就是用YOLOv8专门针对雾天场景做了一套检测方案从数据集增强、模型训练到GUI推理界面全链路都跑通了支持图片、视频、摄像头三种输入方式检测结果可以导出图片和CSV文件。不管是做毕设、课程设计还是自己手里有雾天监控视频想跑个检测流程这套东西应该都能给你省下不少时间。这篇文章我会把整个项目的思路、每个环节怎么做的、踩了哪些坑、最后怎么调优的都摊开来讲尽量做到你看完就能上手复现。1. 项目整体设计与思路拆解1.1 为什么雾天检测不能用普通模型凑合很多人第一反应是雾天检测不就是拿普通YOLO模型跑一下吗真不是这么回事。雾天的图像退化是全局性的远处的车辆和行人对比度极低纹理细节被雾层抹掉了一部分模型提取特征的时候很难抓到有效信息。我试过直接用COCO预训练权重去跑雾天测试集结果是车辆检出率还行行人漏检非常严重尤其是距离远、衣服颜色和背景融为一体的情况基本是隐身状态。所以雾天检测系统的核心思路有两个一是让训练数据贴近雾天分布二是让模型在低特征可见度下依然能学到判别性特征。前者靠数据增强和去雾预处理后者靠模型选型和训练策略调整。1.2 为什么选YOLOv8作为基础框架YOLOv8的优点不用我多说——anchor-free设计、C2f特征提取模块、自适应的正负样本分配策略在精度和速度的平衡上确实做得很好。更重要的是ultralytics这个框架把训练、验证、导出、推理一系列流程都封装得很顺手社区生态成熟遇到问题基本都能搜到答案。我选的是YOLOv8s作为主力模型而不是更小的n或者更大的m/l。原因很简单n精度略微不够雾天场景下小目标检测容易漏m精度是高了但显存占用和推理时间都上去了做实时摄像头推理时帧率会受影响。s版本在GTX 1660 Ti这类中端卡上640分辨率输入推理时间大概20到30毫秒一帧配上合理的GUI线程设计跑实时视频完全够用。1.3 系统整体架构与模块划分整个系统分四个模块模型加载与推理模块、图像输入模块、GUI交互模块、结果导出模块。每个模块各干各的事不要混在一起这个是我踩过坑之后才想明白的后面详细讲。模型加载与推理模块负责加载训练好的best.pt权重对输入帧做预处理resize、归一化、前向推理、后处理NMS、置信度过滤、类别过滤输出最终的检测框和标签。图像输入模块统一封装了三种来源图片文件、视频文件、摄像头实时流。三个入口最终都转成单帧图像交给推理模块处理这样代码结构就非常干净。GUI交互模块用PyQt5实现窗口左侧显示原始画面右侧显示检测结果底部状态栏显示FPS和检测数量还有操作按钮区。结果导出模块支持两种方式导出带检测框的图片或视频以及导出CSV格式的检测记录包含类别、置信度、坐标框信息。2. 环境配置与数据集准备2.1 环境版本与依赖说明先说环境这套东西我用的版本组合是经过实际验证的Python 3.9PyTorch 2.0.1 CUDA 11.81660 Ti也能用这个组合稳ultralytics 8.0.xxPyQt5 5.15.xopencv-python 4.8.xnumpy、pandas导出CSV用不建议用太新的PyTorch版本搭配旧显卡驱动我一开始用的PyTorch 2.2结果CUDNN初始化报错查了半天是因为显卡驱动版本偏低。后来直接降级到2.0.1配合CUDA 11.8一次性跑通。这块的经验是能用稳定组合就别追新。2.2 数据集来源与标注格式转换雾天车辆行人检测的数据集主流有两种获取渠道。一种是直接用公开的雾天目标检测数据集比如Foggy Cityscapes它在Cityscapes基础上做了合成雾处理包含车辆、行人、自行车等类别另一种是用正常天气数据集自己加雾增强来扩充样本。我自己用的是Foggy Cityscapes的YOLO格式转换版本再混入少量真实雾天拍摄的图片做微调。注意一点Foggy Cityscapes默认是Cityscapes的标注格式json多边形需要转成YOLO的txt格式也就是每行一个目标格式是类别id x_center y_center width height并且都是归一化到0到1的坐标值。如果自己标注数据推荐用LabelImg或者labelme先画框然后导出成YOLO格式。标注的时候有个细节雾天图片里看不清的目标宁可不标也不要漏标错标不然模型学到的特征就是错的。2.3 针对雾天的数据增强策略数据增强这块非常关键直接决定了模型在真实雾天场景下的泛化能力。YOLOv8自带的数据增强管线Mosaic、MixUp、HSV扰动、随机翻转等之外我又加了两个针对雾天的专属处理。第一个是合成雾增强。用RGB雾化公式给正常图片加雾模拟不同浓度的雾天效果import cv2 import numpy as np def add_fog(image, intensity0.5): # 生成白色雾层 fog np.ones_like(image) * 255 # 线性叠加 foggy cv2.addWeighted(image, 1 - intensity, fog, intensity, 0) return foggy这个增强操作放在ultralytics数据加载的pipeline里做也就是训练过程中每张图有一定概率先加雾再喂给模型。这样的好处是模型见过正常天气和雾天的联合分布不会出现换了个环境就失灵的问题。第二个是亮度对比度随机扰动。雾天实际场景不是均匀的有些地方雾浓有些地方雾薄通过随机调整亮度、对比度、Gamma校正模拟这种不均匀性让模型对光照变化更鲁棒。3. 模型训练与权重获取3.1 训练参数配置详解训练这块我直接用的ultralytics命令行方式但参数是调过的。数据集配置文件dataset.yaml长这样path: ./datasets/foggy_yolo train: images/train val: images/val names: 0: person 1: car 2: bus 3: truck 4: bicycle 5: motorcycle训练命令yolo train modelyolov8s.pt datadataset.yaml epochs150 imgsz640 batch8 patience20 optimizerSGD lr00.01几个参数说一下为什么这么设。epochs设150配合early stoppingpatience20防止过拟合实际训练到110个epoch左右就收敛了。batch设8因为Foggy Cityscapes的图片比较大显存不够大的卡硬上大batch会OOM8是一个1660 Ti 6GB能稳定跑住的数。优化器选了SGD而不是默认的AdamW这个是我对比过之后的选择SGD收敛速度慢一点但最终精度更高泛化也更好代价就是需要把lr0设大一点到0.01。预训练权重用的是yolov8s.pt在COCO上训好的。COCO里本来就有person、car、bus、truck、bicycle、motorcycle这些类别和我的目标类别高度重合所以迁移学习的收益非常明显训练初期loss下降得很快。如果完全从零开始训数据量不够的话基本很难收敛。3.2 训练过程监控与调优训练过程中我重点看两条曲线train/cls_loss和val/cls_loss也就是分类损失。如果val loss先降后升说明过拟合了早停机制会自动停下来。如果val loss一直不降那就要怀疑学习率是不是大了或者数据增强是不是太强把有效特征都破坏了。还有一个我后来才注意到的点置信度阈值。推理阶段默认confidence0.25但对雾天场景我实际测试下来0.3到0.35的效果更好因为雾天背景干扰多低置信度的误检框特别多。而且类别置信度过滤这个后处理过程对低对比度小目标的召回率影响很大需要根据实际检测效果微调。训练完成后模型权重保存在runs/train/exp/weights/best.pt。best.pt是基于验证集mAP最高的权重不是最后一轮的权重这个要记清楚。3.3 权重文件的使用与验证拿到best.pt之后先做一个快速验证确保权重文件能正常加载和推理from ultralytics import YOLO model YOLO(best.pt) results model(test_foggy.jpg, conf0.3) results[0].show()这一步能跑通说明模型文件没问题。注意如果训练时用的Python环境和推理环境不一致比如训练用的ultralytics版本比推理时新很多可能出现模型加载报错遇到这种情况尽量保证两端版本一致。4. GUI界面设计与推理系统实现4.1 GUI框架选型PyQt5 vs Tkinter vs Streamlit三个可选方案我都认真考虑过。Tkinter上手最简单但控件样式老旧做图像显示和画框标注这种功能要写不少额外代码界面丑。Streamlit做Web界面很快但摄像头实时流处理很别扭而且它是前后端分离的浏览器架构部署起来没有桌面程序轻量。PyQt5虽然学习曲线陡一点但QThread多线程支持非常好这对实时视频推理太重要了。摄像头采集和模型推理如果放在主线程UI会卡到怀疑人生。所以最终选了PyQt5这个决定在后续开发中被证明是完全正确的。4.2 核心GUI界面布局与交互逻辑界面布局大概是这样的左侧QWidget区域显示原始输入画面右侧QWidget区域显示检测结果画面顶部按钮栏打开图片、打开视频、打开摄像头、保存结果、导出CSV、停止底部状态栏实时FPS、检测到的目标数量、当前处理模式为了避免界面卡顿图像采集和推理都必须放到QThread子线程里主线程只负责刷新界面。这里有个很关键的点OpenCV的VideoCapture对象不能在子线程创建、主线程使用或者反过来跨线程使用确实会出奇怪问题。我的做法是在子线程里完成采集和推理然后把结果图已经画好框的numpy数组通过信号signal发到主线程主线程只负责显示。这样线程安全界面流畅。4.3 图片、视频、摄像头三种输入模式的实现三种输入模式在实现上统一抽象成读帧→推理→显示这个循环区别只在于帧的来源。图片模式最简单打开文件对话框选择图片读进来推理一次显示结果。这里注意OpenCV读取的图片是BGR格式PyQt5显示需要转成RGB直接用cv2.cvtColor转换。视频模式的流程是OpenCV按帧读取视频文件每帧送入模型推理结果叠加画框后显示在界面上。这里要处理一个问题视频文件帧率可能比推理速度快所以需要控制循环节奏不然视频会放得飞快。我的做法是读取视频帧率然后按帧率间隔sleep对应的时间。摄像头模式是实时性要求最高的需要确保推理速度高于摄像头帧率否则画面会越来越滞后。这块我做了两个优化一个是推理输入分辨率从640降到544或480速度提升明显精度损失很小另一个是开启FP16半精度推理在支持FP16的显卡上能再快一截。实测下来1660 Ti跑yolov8s 摄像头实时流能达到25到30 FPS基本流畅。4.4 结果导出功能的实现结果导出分两部分。一是导出检测后的图片或视频图片直接用cv2.imwrite保存视频用cv2.VideoWriter按帧写入这个没什么难度。二是导出CSV检测记录这个做数据统计很好用。每行记录一个检测目标字段包括帧号视频模式、类别名称、置信度、检测框坐标xmin, ymin, xmax, ymax。import csv import os def export_to_csv(detections, output_path): with open(output_path, w, newline, encodingutf-8) as f: writer csv.writer(f) writer.writerow([frame, class, confidence, xmin, ymin, xmax, ymax]) for det in detections: writer.writerow([det.frame_id, det.class_name, det.confidence, det.xmin, det.ymin, det.xmax, det.ymax])导出CSV这个功能实战里太重要了比如你想统计某段雾天监控视频里各个时段车辆和行人的数量分布把检测结果导出来做个透视表就能分析。这个需求如果只靠肉眼看视频去数能数到崩溃。5. 系统部署实测与常见问题排查5.1 实际运行效果实测我在三组测试数据上做了效果评估合成雾测试集、真实雾天图片、雾天行车记录仪视频。合成雾测试集上mAP50大概在0.85左右mAP50-95在0.62左右比直接用COCO权重跑的0.55高出一截提升主要来自行人和自行车的检测。真实雾天图片上车辆检测非常稳行人检测稍有波动但整体可用。行车记录仪视频上中近距离的车辆和行人基本都能正确框出来远距离小目标偶尔漏检这个也不意外毕竟雾天远距离目标本身就几乎不可见。推理速度方面图片模式单张耗时约25ms视频模式能达到30 FPS左右摄像头模式因为输入分辨率降低能达到35 FPS满足实时性要求。5.2 高频问题排查与解决方案第一个高频问题训练时loss直接NaN。大概率是学习率太大或者batch中某张图有问题排查方法是从小学习率开始试逐步加大。第二个高频问题模型加载后推理时GPU显存不足。解决办法是降低推理分辨率、缩小batch到1或者强制使用CPU推理虽然慢但能跑。第三个高频问题GUI界面打开视频时卡死。这个几乎都是线程问题排查方法是看推理是不是放在主线程里执行的。把推理放到QThread里用信号槽传结果问题解决。第四个细节坑中文路径问题。OpenCV读取文件路径时如果路径里有中文经常读取失败返回空。我的解决方案是所有项目文件路径全部用英文图片和视频文件名也改成英文简单粗暴但有效。第五个坑是导出视频时视频编码器的问题。OpenCV的VideoWriter在不同平台支持的编码器不一样Windows上建议用mp4v或XVIDLinux上用mp4v容易踩雷我最后统一用mp4v .mp4后缀实测兼容性最好。5.3 性能优化进阶指南如果想让系统跑得更快可以按这个顺序优化。第一步输入分辨率trade-off。从640降到480速度和精度之间的平衡最划算。第二步FP16半精度推理ultralytics里model.half()一行代码搞定速度提升约20%到30%。第三步导出TensorRT引擎这对NVIDIA显卡效果非常显著但网上教程也很多这里不展开了注意TensorRT版本要对应你的显卡驱动的CUDA版本。我自己实测走完这三步1660 Ti上yolov8s的推理时间能从25ms优化到10ms左右实时性非常充裕。6. 项目经验总结与后续扩展建议做这个项目踩过的坑不少但最有价值的收获是雾天检测不是单纯靠换模型就能解决的数据层面怎么模拟雾天分布、推理层面怎么设置置信度阈值、工程层面怎么让GUI和推理流畅协作每一环都影响最终效果。如果后续要扩展我会优先考虑这几个方向一是接入DeepSORT或ByteTrack做多目标跟踪这样不仅能检测还能统计车辆行人轨迹二是给系统增加一个去雾预处理模块在图片进入模型之前先去一层雾实测对浓雾场景有额外增益三是把模型替换成YOLOv8-seg做实例分割不仅能知道目标在哪还能知道目标的轮廓在遮挡严重的雾天场景下能提供更多信息。这套系统的完整代码和训练好的权重文件都打包好了GUI、推理、导出全都跑通你拿到手之后改一下模型路径和类别配置就能直接用。如果你打算自己重新训练记住本文提到的数据增强和置信度阈值这两个关键点能让你的模型在雾天场景下少走很多弯路。本文还有配套的精品资源点击获取
返回列表