☰
基于YOLOv7与DeepSORT的智慧交通多目标跟踪系统实战
2026/10/1 5:27:16 网站建设 项目流程

简介:这份资源面向人工智能与智慧交通方向的课程实践者、毕业设计学生及算法入门开发者,围绕基于YOLOv7与Deepsort的智慧交通系统展开,可用于车辆检测、多目标跟踪与交通场景分析等典型任务,帮助读者理解智能车环境感知与道路目标识别的完整实现思路。压缩包共17个文件,以15张png与1张jpeg图片为主,配合1个py脚本,整体约8.15MB,图片多用于展示检测跟踪效果与运行界面,脚本则承担目录遍历等辅助功能,便于快速浏览项目结构与结果。目前已有213人学习下载,具备一定参考热度。读者可从中获取YOLOv7结合Deepsort的工程组织方式、检测与跟踪模块的衔接逻辑,以及配套教程所梳理的实践路径,适合作为智慧交通项目复现与二次开发的起点。

1. 智慧交通系统拆解:YOLOv7 加 DeepSORT 到底在做什么

路口摄像头每秒吐出 25 帧画面,画面里几十台车、电动车、行人混在一起,你要的不是「识别出有车」,而是「这台车从画面左边进来、被遮挡三次、又出现在右边,它还是同一台车」。这个「还是同一台车」的需求,就是智慧交通系统里最核心的多目标跟踪问题。基于 YOLOv7 和 DeepSORT 的智慧交通系统,本质是把检测和跟踪拼成一条流水线:YOLOv7 负责每一帧里「有什么、在哪」,DeepSORT 负责跨帧把同一个目标的身份串起来,再叠加计数、测速、轨迹绘制这些业务逻辑。这套组合是人工智能项目实践里最经典的落地形态之一,也是人工智能大作业、人工智能专业毕业设计里出现频率极高的选题。它适合两类人:一类是想找一个能跑通、能改、能写进简历的完整项目;另一类是已经在做交通视频分析,想搞清楚检测和跟踪怎么接、参数怎么调、为什么 ID 会跳。下面按「先立住原理、再动手复现、最后讲坑」的顺序讲透。

2. 检测与跟踪的分工:YOLOv7 出框,DeepSORT 给身份

2.1 为什么不是「一个模型全干完」

很多人第一反应是找一个端到端的多目标跟踪模型,输入视频直接输出带 ID 的轨迹。这条路在论文里成立,在工程里往往翻车,原因有三个。第一,端到端跟踪模型对训练数据的要求远高于检测模型,交通场景里遮挡、夜间、雨雾的标注成本极高。第二,检测和跟踪解耦之后,你可以单独替换检测器,今天用 YOLOv7,明天换更新的版本,跟踪逻辑不用动。第三,调试时能定位问题:ID 跳了,是检测框抖了还是匹配算错了,分开看一目了然。常见做法就是检测和跟踪分离,YOLOv7 只做单帧检测,DeepSORT 只做跨帧关联。

YOLOv7 在这一环里的角色是「每帧给出高质量的框」。它的输出是每个目标的边界框坐标、置信度和类别。交通场景里通常只关心几类:car、bus、truck、person、bicycle、motorbike。类别不用多,但框要稳,尤其是小目标和被遮挡目标。DeepSORT 拿到这些框之后,做两件事:一是用卡尔曼滤波预测每个已有轨迹在下一帧的位置,二是用外观特征和运动信息把新检测框和已有轨迹做匹配。匹配上了,ID 延续;匹配不上,新检测框开一条新轨迹;轨迹连续多帧没匹配上,就删掉。

2.2 DeepSORT 的三个关键部件

DeepSORT 相比早期的 SORT,核心改进是引入了外观特征。它内部有三个部件需要你理解,否则调参就是玄学。

第一个是卡尔曼滤波。它维护每个轨迹的状态,通常包括中心点坐标、宽高、以及它们在时间上的变化率。预测阶段根据上一帧状态推下一帧位置,更新阶段用当前帧的检测框修正预测。交通场景里目标运动相对规律,卡尔曼滤波的预测比较准,所以运动匹配的权重可以给高一些。

第二个是外观特征提取器。DeepSORT 会对每个检测框抠出一个固定维度的特征向量,通常来自一个轻量级的 ReID 网络。匹配时不仅看位置距离,还看特征余弦距离。这是解决遮挡后 ID 跳变的关键。如果外观特征质量差,遮挡一发生,ID 就换人了。

第三个是级联匹配。DeepSORT 不是一次性把所有轨迹和所有检测做全局匹配,而是按轨迹「失踪」的帧数分层,先匹配最近出现的轨迹,再匹配失踪久的。这个策略能减少 ID 切换,但也会让长时间遮挡后的重识别变难。

2.3 最小可跑通的代码骨架

下面这段代码是检测加跟踪的主循环骨架,用 Python 写,依赖 ultralytics 的 YOLOv7 推理接口和 deep_sort_realtime 的 DeepSORT 封装。实际项目里你会把它拆成多个文件,但核心逻辑就是这些。

import cv2 from deep_sort_realtime.deepsort_tracker import DeepSort # 初始化 DeepSORT # max_age: 轨迹丢失多少帧后删除 # n_init: 连续多少帧匹配上才确认轨迹 # max_cosine_distance: 外观特征匹配阈值,越小越严格 tracker = DeepSort( max_age=30, n_init=3, max_cosine_distance=0.2, nn_budget=100 ) # 假设 detector 是你封装好的 YOLOv7 推理函数 # 输入一帧,返回 [[x1, y1, x2, y2, conf, cls], ...] cap = cv2.VideoCapture("traffic.mp4") while True: ret, frame = cap.read() if not ret: break detections = detector(frame) # YOLOv7 单帧检测 # DeepSORT 要求检测格式为 ([left, top, w, h], confidence, class_name) ds_dets = [] for x1, y1, x2, y2, conf, cls in detections: ds_dets.append(([x1, y1, x2 - x1, y2 - y1], conf, str(cls))) tracks = tracker.update_tracks(ds_dets, frame=frame) for track in tracks: if not track.is_confirmed(): continue track_id = track.track_id l, t, w, h = track.to_ltrb() cv2.rectangle(frame, (int(l), int(t)), (int(l + w), int(t + h)), (0, 255, 0), 2) cv2.putText(frame, f"ID {track_id}", (int(l), int(t) - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2) cv2.imshow("traffic", frame) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows()

这段代码里,max_age=30表示轨迹丢失 30 帧后删除,按 25 帧每秒算大约 1.2 秒。交通场景里车辆被前车遮挡一两秒很常见,这个值可以适当放大到 50。n_init=3表示连续 3 帧匹配上才确认轨迹,能过滤掉检测抖动产生的假轨迹。max_cosine_distance=0.2是外观匹配阈值,越小越严格,太小会导致遮挡后匹配不上,太大会导致不同车辆被误匹配。nn_budget=100控制每个轨迹保留多少历史外观特征,值越大越稳但越慢。

提示:YOLOv7 的推理封装不在上面代码里,你需要根据自己的权重文件和推理框架补上。检测输出的坐标要和 DeepSORT 要求的格式对齐,这是新手最容易出错的地方。

3. 从零复现:环境、权重、参数与业务逻辑

3.1 环境搭建与依赖版本

这套方案对环境的敏感度中等,主要坑在 PyTorch 和 CUDA 的版本匹配上。我一般会先确认显卡驱动支持的 CUDA 版本,再装对应的 PyTorch,最后装 YOLOv7 和 DeepSORT 的依赖。下面是一套经过验证的安装顺序。

# 创建虚拟环境 conda create -n traffic python=3.8 -y conda activate traffic # 安装 PyTorch,以 CUDA 11.3 为例 pip install torch==1.12.1+cu113 torchvision==0.13.1+cu113 -f https://download.pytorch.org/whl/torch_stable.html # 安装 YOLOv7 依赖 pip install -r requirements.txt # 安装 DeepSORT 封装 pip install deep-sort-realtime # 安装视频处理依赖 pip install opencv-python

python=3.8是兼容性最好的版本,3.9 以上有时会遇到某些包没有预编译轮子。PyTorch 版本要和 CUDA 对齐,装错了会在推理时报「CUDA error: no kernel image is available」。deep-sort-realtime是一个封装好的库,比自己从头实现 DeepSORT 省事,但它的默认参数不一定适合交通场景,需要按上一节说的调。

3.2 权重选择与检测参数

YOLOv7 有多个版本:yolov7.pt、yolov7x.pt、yolov7-w6.pt 等。交通场景我一般先用 yolov7.pt 跑基线,它在速度和精度之间比较平衡。如果显卡显存够,可以上 yolov7x.pt,小目标检测会好一些。权重文件从官方仓库下载,不要用来路不明的权重,否则检测结果会莫名其妙。

检测阶段的参数直接影响跟踪效果,下面这张表是我在交通视频上常用的配置。

参数常用值作用调大后果调小后果
conf_thres0.4置信度阈值漏检增多误检增多
iou_thres0.45NMS 重叠阈值重叠目标被误删同一目标多个框
img_size640推理分辨率小目标更好但更慢速度快但小目标漏
max_det300单帧最大检测数显存占用高密集场景漏检

conf_thres在交通场景里不要设太低,0.3 以下会把路面反光、阴影当成车。iou_thres在车辆密集时容易出问题,两辆车挨得近,NMS 可能把其中一辆的框删掉,导致跟踪丢目标。img_size如果视频里远处车辆很小,可以提到 1280,但速度会明显下降。

3.3 跟踪参数与业务逻辑接入

跟踪参数调好之后,业务逻辑才有意义。智慧交通系统常见的业务功能有三个:车流量计数、车辆测速、轨迹绘制。计数用一条虚拟线,轨迹中心点从线的一侧到另一侧就计数加一。测速需要标定像素和实际距离的对应关系,再用轨迹位移除以时间。轨迹绘制就是把每个 ID 的历史中心点连起来。

# 车流量计数示例 count_line_y = 400 # 虚拟线纵坐标 counted_ids = set() vehicle_count = 0 for track in tracks: if not track.is_confirmed(): continue track_id = track.track_id l, t, r, b = track.to_ltrb() center_y = (t + b) / 2 # 中心点越过计数线且该 ID 未计过数 if center_y > count_line_y and track_id not in counted_ids: counted_ids.add(track_id) vehicle_count += 1 cv2.putText(frame, f"Count: {vehicle_count}", (20, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)

计数逻辑看起来简单,但有两个细节。第一,counted_ids要定期清理,否则长时间运行会内存泄漏。第二,虚拟线的位置要避开画面边缘,因为目标刚进画面时检测不稳定,容易误计数。测速的像素距离标定更麻烦,需要在画面里找一段已知实际长度的参照物,比如车道线间距,算出每像素对应多少米。

3.4 用配置文件管理参数

参数散落在代码里是后期维护的噩梦。我一般会用一个 YAML 文件集中管理检测和跟踪参数,代码启动时读取。这样换场景、换视频不用改代码,只改配置。

detector: weights: "yolov7.pt" conf_thres: 0.4 iou_thres: 0.45 img_size: 640 classes: [0, 1, 2, 3, 5, 7] # person, bicycle, car, motorbike, bus, truck tracker: max_age: 50 n_init: 3 max_cosine_distance: 0.2 nn_budget: 100 business: count_line_y: 400 speed_calibration: 0.05 # 每像素对应米数

classes里只保留交通相关类别,能减少无关检测对跟踪的干扰。max_age在交通场景里给到 50 比默认的 30 更稳,因为遮挡时间往往超过一秒。speed_calibration需要你根据实际摄像头视角标定,不同路口值不一样。

4. 避坑与排查:ID 跳变、漏检、显存和速度

4.1 ID 频繁跳变

现象:同一辆车在画面里行驶,ID 从 1 变成 5 又变成 12,轨迹断成好几段。

原因:外观特征匹配阈值太严,或者检测框抖动导致卡尔曼预测和实际位置偏差大。交通场景里车辆外观相似度高,尤其是同色同款车,外观特征区分度不够。

解决:先把max_cosine_distance从 0.2 放宽到 0.3 试试,同时把max_age调大,给遮挡后的重匹配留更多时间。如果还不行,检查检测框是否稳定,可以在检测后加一个简单的框平滑,用上一帧和当前帧的框做加权平均。

4.2 小目标漏检导致跟踪断

现象:远处车辆检测不到,等它开近了才被检测到,但此时已经是一条新轨迹,ID 和远处时对不上。

原因:YOLOv7 在 640 分辨率下对小目标召回不足,远处车辆只有几十个像素,特征也不明显。

解决:把img_size提到 1280,或者用 yolov7-w6 这类高分辨率版本。另一个办法是降低conf_thres到 0.3,但会引入误检,需要配合类别过滤。如果显卡吃不消,可以对画面做分区域推理,远处区域单独放大检测。

4.3 显存溢出

现象:跑几分钟后程序崩溃,报 CUDA out of memory。

原因:DeepSORT 的nn_budget设太大,或者检测的max_det太高,累积的特征和轨迹占用显存。长时间运行不清理已删除轨迹的特征也会导致泄漏。

解决:把nn_budget从 100 降到 50,max_det从 300 降到 150。定期检查 tracker 内部的轨迹列表,确认删除的轨迹特征被释放。如果还不行,把检测和跟踪分到两个进程,用队列传数据。

4.4 速度跟不上视频帧率

现象:处理后的视频卡顿,实际帧率只有 10 帧每秒,原视频是 25 帧。

原因:YOLOv7 推理占大头,DeepSORT 的特征提取也不便宜。如果每帧都做完整推理,中端显卡很难实时。

解决:用半精度推理,model.half()能提速 30% 左右。另一个办法是跳帧检测,每两帧检测一次,中间帧用卡尔曼预测补位,跟踪逻辑仍然每帧更新。交通场景里目标运动不会突变,跳帧检测对跟踪影响可控。

4.5 夜间和雨雾场景效果差

现象:白天跑得好好的,一到晚上或者下雨,检测框乱飞,ID 频繁切换。

原因:YOLOv7 在低照度和低对比度下检测质量下降,外观特征提取器也受影响,DeepSORT 的外观匹配基本失效。

解决:夜间场景可以先用图像增强做预处理,比如限制对比度自适应直方图均衡。跟踪侧把运动匹配的权重提高,外观匹配权重降低。如果条件允许,用夜间数据微调检测模型,这是最根本的办法。

5. 进阶技巧:用轨迹质量评估反推参数是否合理

参数调完之后,怎么知道调好了?不能只看画面「感觉还行」。我一般会用一个简单的轨迹质量评估脚本,统计每个 ID 的轨迹长度、中断次数和平均检测置信度。轨迹长度短、中断多的 ID 占比高,说明跟踪参数有问题。

# 轨迹质量统计 from collections import defaultdict track_history = defaultdict(list) for track in tracks: if not track.is_confirmed(): continue track_id = track.track_id l, t, r, b = track.to_ltrb() track_history[track_id].append({ "frame": frame_idx, "center": ((l + r) / 2, (t + b) / 2), "conf": track.det_conf if track.det_conf else 0 }) # 统计轨迹长度分布 lengths = [len(v) for v in track_history.values()] short_tracks = sum(1 for l in lengths if l < 10) print(f"总轨迹数: {len(lengths)}, 短轨迹数: {short_tracks}, 短轨迹占比: {short_tracks/len(lengths):.2%}")

短轨迹占比超过 30%,说明 ID 跳变严重,需要回头调max_cosine_distance和max_age。平均置信度低于 0.5,说明检测质量不行,要调conf_thres或者换权重。这个评估脚本比肉眼观察靠谱得多,也是我踩过坑之后养成的习惯。

另一个进阶方向是把跟踪结果存成结构化数据,比如每帧每个 ID 的坐标、速度、方向,再喂给下游的交通流分析。这样这套系统就不只是画框,而是真正能产出交通指标的数据管道。我一般会把结果写成 JSON Lines 格式,每行一条轨迹记录,方便后续用 Pandas 分析。

import json with open("tracks.jsonl", "w") as f: for track_id, records in track_history.items(): for rec in records: f.write(json.dumps({ "track_id": track_id, "frame": rec["frame"], "cx": rec["center"][0], "cy": rec["center"][1], "conf": rec["conf"] }) + "\n")

这套流程跑通之后,你会发现真正花时间的不是写代码,而是调参数和验证结果。我自己的习惯是每换一个场景,先跑 500 帧看短轨迹占比,再决定要不要动参数。希望帮到你。

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

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

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

立即咨询