news 2026/9/10 16:16:15

YOLOv5道路目标检测-识别-计数一体化实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
YOLOv5道路目标检测-识别-计数一体化实战指南

简介:本资源是一套基于YOLOv5的端到端道路车辆与行人检测识别计数系统,面向计算机、人工智能及相关专业本科生毕业设计、课程设计及项目实战学习者,解决交通场景下目标检测、跟踪与实时计数的核心任务。压缩包共78个文件,含50个Python源码(如main.py、detector.py、tracker.py)、6个YOLO配置yaml文件(yolov5s/m/l/x.yaml)、5个XML标注样本、3个Shell脚本(含push.sh)、2个JPG示例图及1个MP4测试视频,辅以requirements.txt、使用说明.txt和Dockerfile等工程化支持文件,整体82.69MB,结构清晰、模块解耦。已有442人学习下载,资源经严格调试,提供预训练模型(yolov5m.pt)、完整数据处理与推理流程、DeepSORT多目标跟踪集成及可视化计数结果,开箱即用,无需额外配置即可运行演示。

1. 这不是“跑通YOLOv5”的演示,而是面向真实道路场景的检测-识别-计数闭环系统

你下载的这个.zip文件,表面看是“YOLOv5源码+模型+文档”,但实际封装了一个可直接部署到交通监控、智慧园区或校园安防场景的轻量级视觉分析流水线。它不依赖云端API,不调用第三方服务,所有逻辑在本地完成:从视频流或图像帧中定位车辆与行人(检测),区分小轿车、卡车、自行车、成人、儿童等细粒度类别(识别),并按时间窗口/区域/类型持续统计数量(计数)。这套方案避开复杂工程链路——没有K8s编排、不对接消息队列、不集成GIS地图,只用OpenCV + PyTorch + NumPy三件套,在普通笔记本(GTX 1650起步)或边缘设备(Jetson Nano/Orin)上即可实现实时推理(30 FPS@640×480)。适合两类人:一是毕设/课设学生需要可交付、可答辩、可展示完整工作流的项目;二是中小项目现场工程师,需快速验证算法效果、调试参数、生成带标注的统计报表。它不教你怎么从零训练YOLOv5,而是告诉你:当模型已存在、数据已标好、硬件已就位时,如何让“检测框”真正变成“可读数字”。


2. 用YOLOv5s-v6.1模型在本地跑通最小检测流水线

2.1 为什么选YOLOv5s而非YOLOv8或YOLOv11?

当前压缩包内模型基于YOLOv5官方v6.1版本(非v7或v8),核心原因在于部署确定性:v6.1的ONNX导出兼容性极佳,TensorRT 8.4/8.6均可无损优化;其COCO预训练权重在道路场景泛化强(尤其对遮挡车辆、远距离行人);且PyTorch 1.12+生态对其torch.hub加载、model.eval()torch.no_grad()支持最成熟。相比之下,YOLOv8虽新,但其Ultralytics库默认启用AMPautocast,在老旧GPU驱动下易触发CUDA context error;YOLOv11尚未发布稳定版。本系统采用yolov5s.pt(14.2MB),兼顾速度(~45 FPS on GTX 1650)与精度(mAP@0.5=56.2 on COCO val2017),是道路场景落地的“甜点模型”。

2.2 解压后目录结构与关键文件定位

解压.zip得到标准YOLOv5工程目录:

road_counting/ ├── models/ # 模型定义:yolov5s.yaml ├── weights/ # 预训练权重:yolov5s.pt(COCO通用) + road_best.pt(本项目微调) ├── detect.py # 主检测脚本(含计数逻辑) ├── utils/ # 工具模块:plots.py(绘图)、general.py(NMS)、metrics.py(评估) ├── data/ # 数据配置:road.yaml(定义classes: ['car','truck','bus','person','bicycle']) ├── README.md # 说明文档(含环境要求、命令示例、参数说明) └── requirements.txt # 依赖清单(明确指定torch==1.12.1+cu113, opencv-python==4.8.0)

提示road_best.pt是作者在BDD100K+UA-DETRAC道路数据集上微调后的权重,比原始yolov5s.pt对“侧方停车车辆”、“雨天模糊行人”召回率高12.7%。使用前务必确认detect.pyweights='weights/road_best.pt'路径正确。

2.3 最小可运行命令与参数解析

road_counting/根目录执行以下命令,启动单帧检测并显示计数结果:

python detect.py --source "test_videos/highway.mp4" \ --weights weights/road_best.pt \ --data data/road.yaml \ --conf 0.4 \ --iou 0.5 \ --save-txt \ --save-conf \ --line-thickness 2
  • --source:支持*.mp4*.avi0(USB摄像头)、'path/to/images/'(批量图片)
  • --conf 0.4:置信度阈值。道路场景推荐0.35~0.45——低于0.3易出误检(如广告牌误判为车),高于0.5漏检率陡增(尤其远距离行人)
  • --iou 0.5:NMS IoU阈值。保持0.5是YOLOv5默认值,若目标密集(如拥堵路段),可降至0.45提升框分离度
  • --save-txt:生成runs/detect/exp/labels/下每帧的.txt标注文件(格式:class_id center_x center_y width height conf
  • --save-conf:在输出图像上叠加置信度数值(非仅画框)
输出结果解读

运行后生成runs/detect/exp/目录,其中:

  • exp/:含带红框标注的视频帧截图(image0.jpg,image1.jpg...)
  • exp/labels/:对应.txt文件,每行代表一个检测目标,例如:
    0 0.421 0.632 0.185 0.291 0.873class_id=0(car),x_center=0.421,y_center=0.632,width=0.185,height=0.291,conf=0.873
  • exp/counts.csv关键输出!每秒统计表,含timestamp, car, truck, bus, person, bicycle, total七列

3. 从检测到计数:三步实现区域化、时段化、分类化统计

3.1 计数逻辑嵌入detect.py的核心修改点

原生YOLOv5detect.py仅输出检测框,本项目在run()函数末尾插入计数模块,关键代码段如下(detect.py第328行起):

# detect.py 片段:计数统计逻辑 if save_txt and not webcam: # 仅对视频/图片启用计数 # Step1: 加载预定义ROI区域(多边形坐标) roi_poly = np.array([[100, 300], [500, 300], [600, 480], [0, 480]]) # 示例:画面底部车道区 # Step2: 对当前帧所有检测框,判断中心点是否在ROI内 for *xyxy, conf, cls in reversed(det): # det: [x1,y1,x2,y2,conf,cls_id] c1, c2 = (int(xyxy[0]), int(xyxy[1])), (int(xyxy[2]), int(xyxy[3])) center_x = (c1[0] + c2[0]) // 2 center_y = (c1[1] + c2[1]) // 2 if cv2.pointPolygonTest(roi_poly, (center_x, center_y), False) >= 0: class_name = names[int(cls)] # names = ['car','truck','bus','person','bicycle'] count_dict[class_name] += 1 # Step3: 写入CSV(每帧写一行,含时间戳和各类别计数) with open(f'{save_dir}/counts.csv', 'a') as f: f.write(f"{time.time():.3f},{count_dict['car']},{count_dict['truck']},{count_dict['bus']},{count_dict['person']},{count_dict['bicycle']},{sum(count_dict.values())}\n")
  • roi_poly:定义兴趣区域(Region of Interest),此处为四边形车道区。实际部署需用cv2.polylines()在视频首帧手动绘制并保存坐标
  • cv2.pointPolygonTest():高效判断点是否在多边形内(O(1)复杂度),比遍历所有像素快10倍以上
  • counts.csv:以时间戳为索引,支持后续用Pandas做滚动平均(如每30秒均值)、趋势分析(如早高峰车流峰值)

3.2 支持多ROI与跨帧去重的进阶计数策略

单纯“框中心在ROI内”会因车辆移动导致同一辆车被重复计数(如车头进入→车身全入→车尾离开)。本系统提供两种防重方案:

方案A:基于Kalman滤波的轨迹跟踪(轻量级)

启用--track参数后,调用utils.tracker.sort.Sort()(SORT算法),为每个目标分配唯一ID,并记录其历史轨迹:

python detect.py --source "test_videos/crossroad.mp4" \ --weights weights/road_best.pt \ --data data/road.yaml \ --conf 0.35 \ --iou 0.45 \ --track \ --save-txt \ --line-thickness 2
  • 输出runs/detect/exp/tracks/.txt文件,每行格式:frame_id, track_id, x1, y1, x2, y2, conf, cls_id, unused, unused
  • 计数时仅统计首次进入ROI的track_id,避免重复计数
方案B:基于IoU的帧间匹配(无额外依赖)

若不希望引入SORT依赖,可在detect.py中添加简易匹配逻辑:

# 在循环检测框前初始化prev_boxes = [] for *xyxy, conf, cls in reversed(det): curr_box = np.array([*xyxy]) # 计算与上一帧所有框的IoU ious = [bbox_iou(curr_box, prev) for prev in prev_boxes] if max(ious) < 0.3: # IoU<0.3视为新目标 # 执行ROI判断与计数 ... prev_boxes = [np.array([*xyxy]) for *xyxy, conf, cls in reversed(det)]

注意:此方案计算开销略高,但完全免依赖,适合资源受限边缘设备。

3.3 统计结果可视化:生成带时间轴的折线图

utils/plots.py新增plot_counts_csv()函数,自动读取counts.csv并绘制:

def plot_counts_csv(csv_path, output_path='counts_plot.png'): df = pd.read_csv(csv_path, names=['timestamp','car','truck','bus','person','bicycle','total']) df['time_min'] = (df['timestamp'] - df['timestamp'].iloc[0]) / 60 # 转换为分钟 plt.figure(figsize=(12,6)) for col in ['car','truck','bus','person','bicycle']: plt.plot(df['time_min'], df[col], label=col, linewidth=2) plt.xlabel('Time (minutes)') plt.ylabel('Count') plt.title('Vehicle & Pedestrian Counting Over Time') plt.legend() plt.grid(True) plt.savefig(output_path, dpi=300, bbox_inches='tight') plt.close()

执行python utils/plots.py --csv runs/detect/exp/counts.csv即生成高清统计图,可直接用于汇报材料。


4. 模型微调:用自定义道路数据集训练road_best.pt

4.1 数据准备规范:LabelImg标注+YOLO格式转换

本系统要求输入数据严格遵循YOLO格式:

  • 图像:images/train/xxx.jpg,images/val/xxx.jpg
  • 标注:labels/train/xxx.txt,labels/val/xxx.txt,每行格式:class_id center_x center_y width height(归一化到0~1)
  • 关键约束:
    class_id必须与data/road.yamlnames:顺序一致(0=car, 1=truck, 2=bus, 3=person, 4=bicycle)
    ❌ 不允许空行、负坐标、宽高超1.0、center_x±width/2越界

提示:使用labelImg标注时,务必在Auto Save mode下勾选Use automatic saving of annotations,并设置Save As格式为YOLO。标注完成后,用utils/general.pyconvert_labels()函数校验格式。

4.2 训练命令与超参数调优指南

road_counting/目录执行:

python train.py --data data/road.yaml \ --weights weights/yolov5s.pt \ --cfg models/yolov5s.yaml \ --epochs 100 \ --batch-size 16 \ --img 640 \ --name road_finetune \ --cache \ --workers 4
  • --cache:将图像缓存到RAM,加速IO(需≥32GB内存)
  • --workers 4:DataLoader进程数,设为CPU核心数一半(i5-10400F建议设4,i7-11800H建议设6)
  • --img 640:输入尺寸。道路场景推荐640(平衡细节与速度),若需检测小目标(如远处行人),可试--img 1280(显存需≥12GB)
关键超参数调整表
参数默认值道路场景推荐值作用说明
lr0(初始学习率)0.010.005避免微调时破坏COCO预训练特征
lrf(终学习率比例)0.20.1确保最后10轮学习率足够低,稳定收敛
mosaic1.00.5Mosaic增强对道路场景增益有限,降低比例减少伪影
mixup0.00.1少量mixup提升遮挡目标鲁棒性(如树荫下车辆)
scale(缩放增强)0.50.3道路目标尺度变化小,降低缩放幅度

修改方式:编辑models/yolov5s.yaml同级目录下的hyp.scratch-low.yaml,或直接在train.py中覆盖--hyp参数。

4.3 验证训练效果:mAP与FPS双指标评估

训练完成后,runs/train/road_finetune/下生成:

  • results.csv:每epoch的Box(P),Box(R),Box(mAP@0.5),Box(mAP@0.5:0.95)
  • val_batch0_pred.jpg:验证集首批预测效果可视化
  • weights/best.pt:最佳权重(mAP最高)

必须验证的两项指标

  1. mAP@0.5:应≥58.0(对比原始yolov5s.pt的56.2)
  2. FPS:在目标设备上实测,命令:
    python detect.py --source "test_videos/test1.mp4" --weights runs/train/road_finetune/weights/best.pt --device 0 --half
    • --half启用FP16推理,GTX 1650上提速约1.8倍(从25→45 FPS)
    • 若FPS下降,检查--img尺寸是否过大,或--batch-size是否超出显存

5. 边缘部署与实时性能调优:Jetson Nano实测参数配置

5.1 TensorRT加速:将PyTorch模型转为引擎文件

在Jetson Nano(Ubuntu 18.04 + JetPack 4.6)上,将road_best.pt转为TensorRT引擎:

# 1. 导出ONNX(主机端,x86环境) python export.py --weights weights/road_best.pt --include onnx --opset 12 # 2. 在Nano上构建TensorRT引擎(需安装tensorrt==8.2.5.1) trtexec --onnx=yolov5s.onnx \ --saveEngine=yolov5s.engine \ --fp16 \ --workspace=2048 \ --minShapes=input:1x3x640x480 \ --optShapes=input:4x3x640x480 \ --maxShapes=input:8x3x640x480
  • --fp16:强制FP16精度,Nano上推理速度提升2.3倍(对比FP32)
  • --workspace=2048:分配2GB显存用于优化,避免编译失败
  • --min/opt/maxShapes:定义动态batch size范围,适配不同负载

5.2 Nano端推理代码精简:绕过PyTorch依赖

detect_trt.py(替代原detect.py)直接加载TensorRT引擎:

import pycuda.autoinit import pycuda.driver as cuda import tensorrt as trt import numpy as np class TRTYOLOv5: def __init__(self, engine_file): self.runtime = trt.Runtime(trt.Logger(trt.Logger.WARNING)) with open(engine_file, "rb") as f: self.engine = self.runtime.deserialize_cuda_engine(f.read()) self.context = self.engine.create_execution_context() # 分配GPU显存buffer(省略细节) def infer(self, img_np): # img_np: (3,640,480) float32 # cudaMemcpy H2D → execute → cudaMemcpy D2H return detections # shape: (N, 6) [x1,y1,x2,y2,conf,cls_id] # 使用示例 detector = TRTYOLOv5("yolov5s.engine") cap = cv2.VideoCapture("csi://0") # 直接读取CSI摄像头 while cap.isOpened(): ret, frame = cap.read() if not ret: break frame_resized = cv2.resize(frame, (480,640)).transpose(2,0,1) # CHW dets = detector.infer(frame_resized) # 后处理:NMS、ROI计数(同detect.py逻辑)
  • 此方案完全移除PyTorch依赖,仅需tensorrtpycudaopencv-python三库
  • Nano实测:640×480输入,FPS达21.3(对比PyTorch原生12.7 FPS)

5.3 CPU-only模式应急方案:OpenVINO量化压缩

若无GPU,可用OpenVINO将模型转为INT8:

# 安装openvino-dev==2022.3.0 python mo.py --input_model yolov5s.onnx \ --data_type FP16 \ --input_shape [1,3,640,480] \ --output_dir openvino_ir/ \ --reverse_input_channels # 量化(需校准数据集) pot -c pot_config.json
  • pot_config.json需指定stat_subset_size: 200(校准图像数)
  • 量化后模型体积减小58%,CPU推理速度提升3.1倍(i5-8250U实测)
  • 精度损失:mAP@0.5下降≤1.2%,仍在道路场景可用范围内

6. 故障排查:五类高频报错与对应解决指令

6.1 “CUDA out of memory” —— 显存不足的精准定位

detect.py报此错,不要盲目调小--batch-size,先执行诊断:

# 查看GPU显存占用(实时) nvidia-smi --query-compute-apps=pid,used_memory --format=csv # 检查PyTorch缓存 python -c "import torch; print(torch.cuda.memory_summary())" # 强制释放缓存(在detect.py开头添加) import gc gc.collect() torch.cuda.empty_cache()
  • 根本解法:在detect.py中设置torch.backends.cudnn.benchmark = False(禁用cudnn自动优化),可降低显存峰值15%
  • 临时解法:加--device cpu强制CPU推理(速度降为1/10,但能跑通)

6.2 “ModuleNotFoundError: No module named 'utils.plots'” —— 路径导入错误

此错表明Python未将road_counting/设为工作目录。必须在项目根目录执行命令:

cd /path/to/road_counting # 确保在此目录 python detect.py --source ... # 此时utils可被正确导入
  • 若用IDE(PyCharm/VSCode),需在运行配置中设置Working directory为项目根路径
  • 禁止在子目录(如/road_counting/utils/)下执行,否则from utils.plots import *会失败

6.3 视频输出无计数框/空白CSV —— ROI坐标未生效

检查detect.pyroi_poly定义是否被注释或路径错误:

# 错误写法(坐标未更新) roi_poly = np.array([[0,0], [100,0], [100,100], [0,100]]) # 覆盖整个画面左上角100x100 # 正确写法(用实际视频分辨率) cap = cv2.VideoCapture(source) w, h = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) roi_poly = np.array([[int(0.1*w), int(0.6*h)], [int(0.9*w), int(0.6*h)], [int(0.9*w), int(0.9*h)], [int(0.1*w), int(0.9*h)]])
  • 建议:先用cv2.imshow()显示ROI区域,确认覆盖目标车道后再运行计数

6.4counts.csv时间戳乱序 —— 多线程写入冲突

当启用--device 0,1(多GPU)时,多个进程同时写counts.csv会导致时间戳错乱。必须加文件锁:

# 在写CSV前添加 import threading csv_lock = threading.Lock() # 写入时 with csv_lock: with open(f'{save_dir}/counts.csv', 'a') as f: f.write(f"{time.time():.3f},...\n")
  • 单GPU无需此操作,多GPU必加锁

6.5 检测框全部偏右/偏下 —— 图像预处理尺寸不匹配

若输出框位置系统性偏移,检查detect.pyletterbox()调用:

# 确保resize后pad方式一致 img = letterbox(img0, new_shape=imgsz, auto=True, stride=32)[0] # auto=True自动pad # 错误:img = cv2.resize(img0, (640,480)) # 无pad,导致坐标映射错误
  • letterbox函数在utils.general.py中,其auto=True保证长边缩放到imgsz,短边pad至32整数倍,是YOLOv5坐标映射正确的前提

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

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

AI率居高不下?学姐熬夜半个月测出10款降AI工具红黑榜(2026最新版)

季面对飘红的文章检测报告&#xff0c;如果你自己改&#xff0c;非常容易语无伦次。为了帮助学弟学妹们提升文本的自然度与原创性&#xff0c;作为已经两年的老学姐&#xff0c;我把市面上主流的降ai率工具都测了一遍。 今天这篇干货&#xff0c;无论你是急需深层优化的&#…

作者头像 李华
网站建设 2026/9/10 16:15:03

医学图像分割实战:Python+3D CNN轻量部署与空间一致性处理

简介&#xff1a;本资源是一套基于Python实现的CNN医学图像分割完整项目源码&#xff0c;面向医学影像处理方向的AI初学者与实践开发者&#xff0c;聚焦于肺部CT、MRI等常见医疗图像的像素级分割任务。项目结构清晰&#xff0c;包含17个Python核心模块&#xff08;涵盖数据预处…

作者头像 李华
网站建设 2026/9/10 16:14:42

科技中介服务专业化与效率提升的实践策略

1. 科技中介服务的现状与挑战 科技中介机构作为连接技术供需双方的桥梁&#xff0c;在创新生态系统中扮演着关键角色。但现实中&#xff0c;这类机构普遍面临着服务同质化严重、专业深度不足、响应效率低下等痛点。我曾参与过多个技术转移项目&#xff0c;亲眼见证过专业服务带…

作者头像 李华
网站建设 2026/9/10 16:12:19

前端版本信息展示的两种主流实现方案

1. 前端版本信息展示的两种主流实现方案在Web应用开发中&#xff0c;版本信息的可视化展示是一个看似简单却直接影响用户体验的细节功能。最近接手的一个后台管理系统项目就遇到了这样的需求&#xff1a;需要在页面右下角清晰展示当前前端构建版本号&#xff0c;同时支持通过不…

作者头像 李华
网站建设 2026/9/10 16:11:06

Telegram Bot API自定义扩展终极指南:如何快速添加新的API端点和方法

Telegram Bot API自定义扩展终极指南&#xff1a;如何快速添加新的API端点和方法 Telegram Bot API是一个功能强大的机器人开发框架&#xff0c;而telegram-bot-api项目提供了Golang语言的完整绑定支持。&#x1f4f1; 本文将详细介绍如何在这个库中自定义扩展&#xff0c;添加…

作者头像 李华