
简介本资源是一个基于YOLOv5与DeepSORT算法的车辆检测与追踪实战项目面向计算机视觉初学者、AI开发者及智能交通方向研究者解决视频流中多车辆实时检测、ID关联与轨迹持续跟踪的技术难点。压缩包共2000个文件29.76MB含1588个XML标注文件PASCAL VOC格式、409个TXT标签文件YOLO格式、2个Markdown文档含环境配置与训练说明、1个Python脚本数据集划分工具结构清晰支持开箱即用。已有150人学习下载适合快速复现实验、开展二次开发或学术验证。资源提供预训练YOLOv5模型、经清洗与对齐的车辆图像数据集含多角度、多光照场景并附完整README与split_train_val.py等实用工具显著降低算法集成门槛便于理解目标检测与多目标跟踪的协同实现逻辑。1. 为什么用 YOLOv5 DeepSORT 做车辆检测比单靠一个模型更稳、更准、更实用你训练好一个 YOLOv5 模型在测试视频里跑出框——看起来不错但一到十字路口、车流密集或遮挡频繁的场景ID 就开始乱跳同一辆车刚过红绿灯ID 从 3 变成 17两辆车并行时ID 频繁交换甚至一辆车被公交车挡住 3 秒后重新出现系统直接当成“新车”再分配 ID。这不是模型不准而是检测detection和跟踪tracking本就是两个任务YOLOv5 负责“此刻在哪”DeepSORT 负责“这辆是不是刚才那辆”。标题里这个项目之所以值得复现不是因为它用了两个热门算法堆砌而是它把车辆检测落地中最痛的三个现实问题闭环了ID 持续性避免跳变、跨帧关联鲁棒性应对遮挡/相似外观、以及开箱即用的数据集省去你花 3 天清洗、标注、格式转换的血泪时间。它面向的是真实部署场景——比如园区出入口统计、高速卡口辅助稽查、智能泊车引导系统而不是 Kaggle 排名榜。如果你正卡在“模型能检出车但业务系统要的是每辆车的连续轨迹”那这个组合不是可选项是当前工业级车辆分析最成熟、文档最全、社区支持最强的最小可行路径。别急着调 YOLOv8 或 ByteTrack先把 YOLOv5 DeepSORT 这条链路跑通、调稳、踩透坑才是真正在工程侧站住脚的第一步。2. 从零搭建 YOLOv5 DeepSORT 车辆检测流水线环境、模型、数据三件套怎么配2.1 环境配置Conda CUDA 版本对齐是第一道生死线YOLOv5 官方推荐torch1.13.1cu117CUDA 11.7而 DeepSORT 的torchreid依赖项在torch1.12下才稳定支持 ReID 模块。但实际部署中很多人卡在nvidia-smi显示驱动支持 CUDA 12.x却硬装cu117导致torch.cuda.is_available()返回False。我的血泪经验是先查驱动再定 CUDA最后选 PyTorch。# 1. 查当前 NVIDIA 驱动支持的最高 CUDA 版本关键 nvidia-smi --query-gpuname,driver_version --formatcsv # 2. 创建隔离环境避免全局污染 conda create -n yolov5ds python3.8 conda activate yolov5ds # 3. 根据上一步结果安装对应 CUDA Toolkit例如驱动支持 12.1则装 cu121 # 注意这里不装 cudatoolkit而是通过 PyTorch 官网命令带 CUDA 编译版本 pip install torch1.13.1cu117 torchvision0.14.1cu117 --extra-index-url https://download.pytorch.org/whl/cu117 # 4. 验证 GPU 可用性必须看到 True python -c import torch; print(torch.cuda.is_available(), torch.version.cuda)提示如果torch.version.cuda输出为空或报错说明 PyTorch 未正确链接 CUDA。此时不要降级驱动而是改用torch1.12.1cu116兼容性更广或升级到torch2.0.1cu118需确认驱动支持。切记nvcc --version显示的版本 ≠ 驱动支持的版本以nvidia-smi为准。2.2 模型选择YOLOv5s 是车辆检测的“甜点模型”不是越小越好YOLOv5 提供yolov5s/m/l/x四个尺寸。很多新手直接拉yolov5x结果在 Jetson Orin 上推理延迟 280ms根本无法实时。而yolov5s在保持 72.5% mAP0.5COCO vehicle subset的同时单帧推理仅 12msRTX 3090且参数量仅 7.2M便于后续剪枝或量化。更重要的是DeepSORT 的卡尔曼滤波器对检测框抖动极其敏感yolov5s的轻量结构反而带来更稳定的 bbox 坐标输出减少 tracker 输入噪声。# 下载预训练权重官方 release 最稳定 wget https://github.com/ultralytics/yolov5/releases/download/v6.2/yolov5s.pt # 验证模型加载与推理关键检查点 python detect.py --weights yolov5s.pt --source test_video.mp4 --conf 0.4 --iou 0.5参数说明--conf 0.4是车辆检测的黄金阈值——低于 0.3 会引入大量误检如广告牌、阴影高于 0.5 则漏检低置信度但真实的遮挡车辆--iou 0.5控制 NMS 抑制强度车辆密集时可降至0.45减少框合并。2.3 数据集结构标题里“处理好的数据集”到底长什么样标题强调“附带处理好的数据集”这绝非指简单放几张图。一个真正可用的车辆检测数据集必须满足3 层结构 2 个校验文件目录层级内容说明必须存在datasets/vehicles/images/所有.jpg图像分辨率统一为 1280×720适配 YOLOv5 默认输入✅datasets/vehicles/labels/对应.txt标签YOLO 格式class_id center_x center_y width height归一化坐标✅datasets/vehicles/trainval/test.txt划分文件每行一个图像相对路径如images/00001.jpg✅datasets/vehicles/classes.txt单行类别定义car truck bus van顺序必须与标签中class_id严格一致✅datasets/vehicles/README.md包含采集设备如 Hikvision DS-2CD3T47G2-L、光照条件晴/阴/夜、场景类型城市主干道/高速收费站/停车场✅注意该数据集已做过3 项关键预处理① 使用labelImg人工复核所有遮挡车辆的 bounding box避免自动标注漏标② 对夜间图像做直方图均衡化增强cv2.createCLAHE(clipLimit2.0)③ 删除所有width 20px或height 15px的极小目标YOLOv5s 对此类样本学习效果差反增噪声。你拿到后无需再做任何标注清洗直接进训练流程。3. 训练自己的车辆检测模型从数据准备到收敛监控的完整闭环3.1 数据集划分与 YAML 配置别让 train/val 比例毁掉你的验证可信度YOLOv5 要求data.yaml文件定义路径和类别。但新手常犯的致命错误是把test.txt当作验证集写入val:字段导致训练时验证集与测试集重复mAP 虚高 5~8 个点。真实验证必须独立于测试集且比例需符合车辆检测场景特性——城市道路车辆尺度变化大需保证小车如摩托车在 val 中占比 ≥15%。# datasets/vehicles/data.yaml train: ../datasets/vehicles/train.txt val: ../datasets/vehicles/val.txt # ← 不是 test.txt test: ../datasets/vehicles/test.txt nc: 4 names: [car, truck, bus, van]划分子技巧用split_train_val.py脚本按场景平衡采样而非随机打乱# 按图像路径中的子目录名分组如 images/city_street/, images/highway/ # 每组内按 7:2:1 划分确保 val/test 包含各场景样本3.2 训练命令与超参调优YOLOv5 超参数不是玄学是车辆检测的物理约束YOLOv5 的hyp.scratch-low.yaml是通用起点但车辆检测有其独特约束小目标多→scale增强需设为0.5-1.5默认0.5-1.0不够运动模糊严重→mosaic概率从1.0降至0.7避免合成模糊破坏真实运动特征类间差异大卡车 vs 微型车→cls_pw分类损失权重设为0.5默认1.0会过度拟合 car 类python train.py \ --img 1280 \ --batch 16 \ --epochs 150 \ --data datasets/vehicles/data.yaml \ --weights yolov5s.pt \ --name yolov5s_vehicles \ --hyp data/hyps/hyp.vehicles.yaml \ --cache关键参数解释--img 1280车辆检测需更高分辨率捕捉车牌、车型细节1280 是 RTX3090 下 batch16 的极限--cache将标签缓存为.cache文件加速 epoch 加载尤其大数据集--name生成唯一实验目录避免覆盖历史权重。3.3 收敛监控与早停看 loss 曲线不如盯住box_loss和obj_loss的比值YOLOv5 的results.csv包含 10 项指标但车辆检测只需盯死3 条曲线box_loss下降缓慢说明 anchor 匹配差 → 检查kmeans重聚类obj_loss持续高于cls_loss2 倍说明负样本过多 → 调高iou_tNMS 阈值val/box_loss与train/box_loss差值 0.05过拟合 → 开启--rect矩形推理或增加copy_paste增强。# 实时查看训练日志比 TensorBoard 更快定位问题 tail -f runs/train/yolov5s_vehicles/results.csv | awk -F, {print $1,$5,$6,$7} | column -t # 输出列epoch, train/box_loss, train/obj_loss, val/box_loss避坑经验当val/box_loss在第 80 epoch 后停滞不要盲目加 epoch。先用val_batch0_pred.jpg可视化验证集预测——若大量漏检出现在车尾因遮挡说明模型对rear_view特征学习不足此时应① 在hyp.vehicles.yaml中增加perspective增强② 手动补充 200 张车尾视角图像到val集。4. DeepSORT 集成与 ID 关联为什么 tracker 参数比 detector 还重要4.1 DeepSORT 架构拆解卡尔曼滤波 外观 ReID 级联匹配三者缺一不可DeepSORT 不是“黑匣子”它的稳定性来自三层设计卡尔曼滤波KF预测车辆下一帧位置状态向量[x,y,a,h,vx,vy]对抗短时遮挡外观 ReID 模块提取 bbox 内部特征ResNet-50 backbone解决外观相似车辆如同款出租车ID 混淆级联匹配Cascade Matching先用运动信息KF 预测匹配高置信度检测再用外观特征匹配剩余检测避免“一错全错”。关键认知YOLOv5 输出的 bbox 坐标是 tracker 的“输入噪声源”。若 detector 的box_loss高KF 预测误差放大整个 tracker 就崩。所以tracker 调优的前提是 detector 已收敛。4.2 Tracker 参数精调3 个必改参数决定 ID 稳定性DeepSORT 的deep_sort_pytorch/deep_sort/configs/deep_sort.yaml中以下参数直接影响车辆场景表现参数默认值车辆检测推荐值作用说明max_age3060卡尔曼滤波允许目标消失的最大帧数。城市路口车辆平均遮挡时长 2~5 秒60fps 下约 300 帧设为 60 帧1 秒太激进易造成 ID 断裂设为 602 秒更稳妥。n_init35新目标需连续n_init帧被检测到才确认为有效 track。车辆启动/停止频繁设为 3 易产生 ghost track误检触发5 帧可过滤 95% 的单帧噪声。nn_budget100200外观特征库最大存储量。高速场景车辆密度高ID 数量可达 150预算不足会导致旧特征被强制淘汰引发 ID 交换。# tracker.py 中加载配置的关键代码必须显式指定路径 from deep_sort import build_tracker tracker build_tracker( config_deepsortdeep_sort_pytorch/configs/deep_sort.yaml, use_cudaTrue )注意build_tracker会自动加载ckpt.t7ReID 模型权重该权重必须与torch1.13.1兼容。若报RuntimeError: version_ kMaxSupportedFileFormatVersion说明权重是 PyTorch 2.0 训练的需下载deep_sort_pytorch仓库的v1.0tag 版本。4.3 检测-跟踪联合推理如何让 YOLOv5 输出适配 DeepSORT 输入YOLOv5 的detect.py默认输出xyxy坐标左上右下而 DeepSORT 要求xyah中心点 x,y 宽高比 a 高 h。必须插入坐标转换层且需保留原始置信度用于 tracker 的confidence门限# utils/detections.py def yolov5_to_deepsort(detections): detections: list of [x1,y1,x2,y2,conf,class_id] return: np.array([[x,y,a,h,conf], ...]) output [] for *xyxy, conf, cls in detections: x1, y1, x2, y2 map(int, xyxy) x, y (x1 x2) / 2, (y1 y2) / 2 w, h x2 - x1, y2 - y1 a w / h if h ! 0 else 1.0 output.append([x, y, a, h, float(conf)]) return np.array(output) # 在 inference 主循环中调用 preds model(img)[0].cpu().numpy() # YOLOv5 输出 dets yolov5_to_deepsort(preds) # 转换为 DeepSORT 输入 tracks tracker.update(dets) # 获取 track 结果参数说明float(conf)是 DeepSORT 的min_confidence门限依据默认 0.3低于此值的检测直接丢弃不参与匹配。车辆检测中conf0.35是平衡漏检与误检的临界点。5. 避坑指南YOLOv5 DeepSORT 车辆检测的 5 个真实翻车现场5.1 现象ID 在车辆并行时高频交换A 车 ID 1B 车 ID 23 秒后 A 变 ID 2B 变 ID 1原因DeepSORT 的外观 ReID 特征区分度不足尤其对同品牌同色系车辆如滴滴蓝车。默认ckpt.t7是在 MOT17 上训练的车辆外观多样性远低于真实城市场景。解决替换 ReID 模型为osnet_ain_x1_0_msmt17在 MSMT17 数据集上训练对相似车辆判别更强在deep_sort.py中修改self.encoder load_pretrained_weights(...)加载新权重将max_cosine_distance从0.2降至0.15提高匹配严格度。5.2 现象夜间视频中车辆 ID 大量丢失track 时长普遍 5 帧原因YOLOv5 检测框在低照度下偏移严重box_loss高导致卡尔曼滤波预测发散。单纯调 tracker 参数无效。解决在train.py中启用--evolve自动超参搜索重点优化hsv_v亮度增强和translate平移增强对输入视频做实时预处理cv2.createCLAHE(clipLimit3.0).apply(gray)增强对比度将max_age设为 1202 秒容忍更长遮挡。5.3 现象训练时val/mAP0.5达 78%但部署到实车视频中 mAP 50%原因数据集与真实场景域偏移domain shift。标题中“处理好的数据集”虽已做直方图均衡但未模拟雨雾天气、镜头畸变、运动模糊等。解决使用albumentations添加MotionBlur(blur_limit7)和RandomRain(slant_lower-10, slant_upper10)在hyp.vehicles.yaml中开启mosaic: 0.5降低 mosaic 强度避免合成伪影用test.py在真实视频片段上做--task test生成confusion_matrix.png定位漏检类别如van类漏检率高则针对性补充 van 图像。5.4 现象CPU 占用率 100%GPU 利用率仅 30%推理卡顿原因DeepSORT 的nn_matching最近邻匹配在 CPU 上计算未启用 GPU 加速。YOLOv5 的 GPU 推理与 tracker 的 CPU 匹配形成瓶颈。解决将deep_sort_pytorch/deep_sort/nn_matching.py中的np.linalg.norm替换为torch.norm并在cuda上运行修改tracker.pyself.metric NearestNeighborDistanceMetric(cosine, self.max_cosine_distance, devicecuda)设置torch.set_num_threads(1)避免多线程争抢。5.5 现象同一辆车在不同摄像头视角下 ID 不一致跨摄像头追踪失败原因DeepSORT 是单摄像头 tracker无跨相机关联能力。标题项目未包含 re-identification 跨镜模块。解决短期方案用track_id % 1000作为临时 ID人工标注跨镜映射表长期方案集成StrongSORT开源改进版其appearance模块支持跨相机特征对齐工程取巧在路口部署时用 GPS 坐标 时间戳做粗粒度关联需车辆装有 OBD 设备。6. 验证与部署用真实指标说话而不是只看 mAP6.1 ID 切换次数ID Switches车辆检测的终极 KPImAP 只反映检测精度而业务系统真正需要的是ID 连续性。DeepSORT 官方评估工具mot_metrics提供IDSWID Switches指标数值越低越好。计算方式# 生成 tracker 输出格式frame,id,x,y,w,h,conf,-1,-1,-1 python track.py --source test_video.mp4 --output results.txt # 用 MOTChallenge 格式评估需 ground truth .txt mot_metrics --gt-dir gt/ --det-dir results/ --fmt motchallenge行业基准城市道路场景IDSW/frame 0.05为合格即每 20 帧最多 1 次切换 0.02为优秀。若你的结果IDSW 0.12优先检查max_age和n_init而非重训 detector。6.2 多尺度车辆检测验证用scale_analysis.py定位模型弱点车辆尺度跨度极大摩托车宽 0.8m集装箱车宽 2.5mYOLOv5 的 anchor 设计是否合理运行以下脚本生成尺度分布热力图# utils/scale_analysis.py def analyze_scale_distribution(labels_dir): scales [] for label in Path(labels_dir).glob(*.txt): with open(label) as f: for line in f: cls, cx, cy, w, h map(float, line.split()) # w,h 是归一化值转为像素尺度假设图像宽1280 w_px, h_px w * 1280, h * 720 scales.append((w_px, h_px)) # 绘制 w-h 散点图叠加 YOLOv5s 默认 anchor[10,13, 16,30, 33,23, ...] plot_scale_scatter(scales, anchors)解读方法若散点集中在(w_px50, h_px30)区域摩托车但 anchor 最小值为(10,13)说明小目标召回率必然低。此时需① 在train.py中添加--multi-scale② 用kmeans -x 9 datasets/vehicles/labels/重聚类 anchor。6.3 边缘部署实战树莓派 5 上跑通 YOLOv5s DeepSORT 的 3 个硬核技巧标题项目虽未提部署但“车辆检测”天然指向边缘设备。树莓派 58GB RAM RP1 芯片跑原生 PyTorch 会内存溢出。我的落地方案模型量化用torch.quantization.quantize_dynamic对 YOLOv5s 做动态量化体积减 40%速度提 2.3×Tracker 精简删掉 DeepSORT 中gmc.py全局运动补偿树莓派用不到内存锁频sudo nano /boot/config.txt添加gpu_freq500稳定 GPU 频率避免 thermal throttling。# 树莓派 5 部署命令实测 12.4 FPS python track_pi.py \ --source /dev/video0 \ --weights yolov5s_quantized.pt \ --tracker-config deep_sort_pi.yaml \ --view-img最后一句经验我曾为一个园区项目调了 17 天 tracker直到发现是摄像头时间戳不同步导致跨帧匹配失效——最终用ntpd校时解决。技术栈再熟也得低头看一眼物理世界。希望帮到你。本文还有配套的精品资源点击获取