2025 / AI 视觉
YOLOv8 车辆速度检测系统
基于 YOLOv8 和目标跟踪做的车辆测速系统,包含视频上传、检测预览、测速线设置和速度结果展示。
技术栈
YOLOv8 / Python / 视频处理 / 目标跟踪 / 车辆测速
项目说明
项目截图

车辆速度跟踪与测速系统
项目简介
本项目是一个基于 YOLOv8、OpenCV 和 FastAPI 开发的车辆速度跟踪与测速系统。系统主要面向道路交通视频场景,用户可以通过网页端上传视频,系统会自动完成车辆识别、车辆跟踪、轨迹绘制、测速线判断以及速度计算,并将检测结果以视频流和表格的形式展示出来。
相比只在命令行中运行 YOLO 模型,本项目更加注重“可视化展示”和“完整业务流程”。系统不只是简单检测车辆,而是将车辆检测、车辆 ID 跟踪、车辆通过测速线的帧号记录、速度计算和结果展示整合到一个网页中,使整个项目更像一个可以操作、可以演示、可以扩展的实际应用系统。
技术栈
后端主要使用 Python + FastAPI 搭建接口服务,负责视频上传、模型推理、测速参数配置、视频流输出和结果查询。
核心视觉处理部分使用 OpenCV 读取视频帧、处理图像、绘制检测框、轨迹线和测速线。车辆检测部分使用 YOLOv8 模型完成目标识别,系统只保留 car、bus、truck、motorcycle 等车辆相关类别,避免无关目标干扰测速结果。
前端页面使用 HTML、CSS 和 JavaScript 编写,通过浏览器完成视频上传、测速线参数设置、检测启动和结果查看。页面整体采用深色控制台风格,左侧展示视频检测画面,右侧提供上传和参数配置操作,下方展示测速结果表格。
项目主要技术包括:
- Python 3.9
- FastAPI
- Uvicorn
- OpenCV
- YOLOv8 / Ultralytics
- NumPy
- Jinja2
- HTML / CSS / JavaScript
- IOU Tracker
- 双线测速算法
项目背景
车辆测速是计算机视觉中比较典型的综合应用场景。单独完成车辆检测并不难,但如果要让系统真正具备“测速”能力,就需要解决多个连续问题:
第一,系统要能在视频中识别车辆,而不是只识别单张图片。 第二,同一辆车在不同帧中需要保持同一个 ID,否则无法判断它从哪里来、经过了哪些位置。 第三,需要设置两条测速线,并记录车辆通过第一条线和第二条线的帧号。 第四,需要根据两条线之间的实际距离、视频 FPS 和帧差计算车辆速度。 第五,测速结果要直观展示出来,而不是只输出到控制台。
因此,这个项目的重点不是单纯调用 YOLOv8,而是把目标检测、目标跟踪、视频处理、参数配置和前端展示连接成一个完整系统。它更接近一个“AI 视觉应用系统”,而不是一个单独的模型脚本。
系统功能
1. 视频上传
系统支持在网页端上传本地交通视频,后端接收视频文件后保存到指定目录,并将当前视频路径交给视频处理模块。支持常见视频格式,例如 mp4、avi、mov、mkv 等。
上传完成后,用户不需要手动进入代码中修改视频路径,可以直接在页面中完成后续检测操作。这种方式更适合项目演示,也更接近真实 Web 系统的使用流程。
2. YOLOv8 车辆检测
系统使用 YOLOv8 作为目标检测模型,对视频中的车辆进行识别。为了避免行人、动物、路牌等无关目标影响测速结果,系统在检测后只保留车辆相关类别,包括小汽车、公交车、货车和摩托车。
每一帧视频都会经过模型推理,模型会返回车辆的位置框、类别名称和置信度。后续跟踪模块会基于这些检测框判断车辆在连续帧中的对应关系。
3. IOU 车辆跟踪
车辆测速不能只依赖单帧检测结果,因为速度计算需要知道同一辆车在前后帧中的移动轨迹。项目中使用 IOU Tracker 对车辆进行跟踪。
IOU Tracker 的核心思路是:如果当前帧中的检测框和上一帧中的某个车辆框重叠程度较高,就认为它们属于同一辆车,并继续沿用原来的车辆 ID。这样系统就可以在视频中持续追踪同一辆车的位置变化。
系统会为每辆新出现的车辆分配一个 track_id,并记录车辆中心点轨迹。当前端展示视频时,可以看到每辆车的检测框、车辆 ID 和运动轨迹线。
4. 双线测速
本项目采用双线测速方式。用户可以在页面中设置两条测速线的位置,并填写两条线之间的实际距离,例如 10 米。
当车辆轨迹穿过第一条测速线时,系统记录该车辆通过第一条线的帧号;当同一辆车继续穿过第二条测速线时,系统再次记录帧号。然后根据帧差、FPS 和实际距离计算车辆速度。
测速计算公式为:
time = frame_diff / fps
speed_mps = distance_m / time
speed_kmh = speed_mps * 3.6
其中,frame_diff 表示车辆通过两条线之间相差的帧数,fps 表示视频帧率,distance_m 表示两条测速线之间的实际距离。最终得到的 speed_kmh 即车辆速度,单位为 km/h。
这个设计的好处是系统不使用程序真实运行时间计算速度,而是使用视频帧号和 FPS 计算速度。这样即使电脑性能不同、模型推理速度不同,也不会直接影响测速结果。
5. 测速线参数配置
系统提供了测速线配置功能,用户可以在网页端输入第一条线和第二条线的坐标,也可以设置两条线之间的实际距离和视频 FPS。
这样做的原因是不同视频的拍摄角度、道路位置和画面大小都不一样,固定测速线无法适配所有视频。通过前端可配置参数,可以让系统适应更多道路场景。
用户可以配置:
- 第一条测速线起点坐标
- 第一条测速线终点坐标
- 第二条测速线起点坐标
- 第二条测速线终点坐标
- 两条测速线的实际距离
- 视频 FPS
配置保存后,后端会更新测速模块的参数,并重置跟踪状态,保证新的测速参数能够正确生效。
6. 视频流检测展示
项目不是简单生成一张结果图,而是通过视频流的形式实时返回处理后的画面。后端读取视频帧后,会完成车辆检测、车辆跟踪、测速判断和画面绘制,然后将处理后的帧编码成 JPG,并通过 StreamingResponse 返回给前端。
前端页面可以连续显示处理后的检测画面,用户能够直观看到车辆框、车辆 ID、车辆轨迹、测速线、距离信息和车辆速度。
7. 测速结果表格展示
当车辆成功通过两条测速线后,系统会将测速结果保存下来,并在前端结果表格中展示。结果表格包含:
- 车辆 ID
- 第一条线帧号
- 第二条线帧号
- 间隔帧数
- 用时
- 两线距离
- 速度 km/h
这种表格展示方式方便用户查看每辆车的测速结果,也便于后续扩展导出 Excel、保存数据库或生成检测报告。
系统模块设计
项目整体按模块划分,结构比较清晰,主要包括接口层、服务层、配置层、前端页面和静态资源。
1. 接口层
接口层主要负责和前端进行数据交互,包括视频上传接口、测速线配置接口、结果查询接口和视频流接口。
视频上传接口负责接收用户上传的视频,并保存到本地目录。测速线配置接口负责接收前端传来的测速线坐标、距离和 FPS 参数。结果查询接口用于返回当前已经计算出的测速结果。视频流接口用于持续输出处理后的视频画面。
2. 检测服务
检测服务负责加载 YOLOv8 模型,并对每一帧图像进行车辆检测。为了提高系统针对性,检测结果会过滤掉非车辆类别,只保留交通场景中需要关注的车辆目标。
检测服务返回的数据包括车辆边界框、置信度、类别编号和类别名称,这些数据会继续交给跟踪服务处理。
3. 跟踪服务
跟踪服务负责为车辆分配 ID,并维护车辆在连续帧中的轨迹。系统采用 IOU 匹配方式,根据检测框之间的重叠程度判断是否为同一辆车。
当车辆短暂丢失时,系统会允许一定的丢失帧数,不会立刻删除该车辆轨迹。这样可以降低遮挡、检测不稳定带来的影响。
4. 测速服务
测速服务负责判断车辆轨迹是否与测速线相交,并在车辆通过两条测速线后计算速度。
系统会为每辆车维护一个测速状态,包括第一次通过的测速线、第一线帧号、第二线帧号、帧差、用时和速度。只有当同一辆车完整通过两条测速线后,系统才会生成一条测速结果。
5. 视频处理服务
视频处理服务是整个系统的核心调度模块。它负责读取视频、逐帧处理、调用检测模块、调用跟踪模块、调用测速模块,并把检测后的结果绘制到画面上。
每一帧的处理流程大致如下:
- 从视频中读取一帧图像;
- 调整图像尺寸;
- 使用 YOLOv8 检测车辆;
- 使用 IOU Tracker 跟踪车辆;
- 判断车辆是否通过测速线;
- 计算车辆速度;
- 绘制检测框、车辆 ID、轨迹、测速线和速度;
- 编码成图片帧返回给前端。
核心实现思路
1. 为什么使用帧号计算速度
很多初学者做测速系统时,可能会直接使用程序运行时间计算速度。但这种方式并不稳定,因为模型推理速度会受到电脑性能、显卡性能、视频分辨率和后台任务影响。
本项目使用视频帧号和 FPS 计算速度。例如车辆通过两条线之间相差 15 帧,视频 FPS 为 30,那么车辆通过两条线的时间就是:
15 / 30 = 0.5 秒
如果两条线实际距离是 10 米,那么车辆速度就是:
10 / 0.5 = 20 m/s
20 * 3.6 = 72 km/h
这种方式更符合视频分析逻辑,也能保证不同电脑运行时测速结果相对一致。
2. 为什么使用双线测速
单线无法直接计算速度,因为只知道车辆经过某一条线的时间点,并不知道车辆在多长时间内移动了多远。双线测速通过两条线构造一个已知距离区间,只要记录车辆通过两条线的帧号,就可以计算车辆通过该距离所花费的时间。
这种方法实现简单,适合固定摄像头道路场景,也方便在网页端进行可视化配置。
3. 为什么要做车辆跟踪
如果没有车辆跟踪,系统只能知道每一帧有哪些车辆,却无法判断前后帧中的车辆是不是同一辆。测速必须针对同一辆车进行,否则第一条线可能记录的是 A 车,第二条线可能记录的是 B 车,计算结果就会错误。
因此,车辆检测只是第一步,车辆跟踪才是测速系统能正常工作的关键。
4. 为什么要提供网页端
AI 项目如果只能在命令行运行,展示效果会比较弱,也不方便别人使用。通过网页端,用户可以直接上传视频、设置参数、查看检测过程和测速结果。
这个项目把算法能力包装成一个可操作的系统,让项目从“能跑代码”变成“能演示功能”。
项目亮点
1. 完整的视频测速流程
项目从视频上传、目标检测、目标跟踪、轨迹绘制、速度计算到结果展示,形成了完整闭环。不是单一算法 Demo,而是一个具备前后端交互的视觉应用系统。
2. 支持网页端参数配置
测速线位置、实际距离和 FPS 都可以通过网页端进行配置,不需要频繁修改代码。这样系统可以适配不同视频画面,提高了项目的灵活性。
3. 使用帧号而不是运行时间测速
系统根据车辆通过两条测速线的帧差和视频 FPS 计算速度,避免了电脑性能和模型推理速度对测速结果的影响。
4. 检测、跟踪、测速模块解耦
项目将车辆检测、车辆跟踪、速度估计、视频处理和接口服务拆分成不同模块,代码结构更加清晰,后续扩展也更方便。
5. 可视化效果直观
系统会在画面中绘制车辆框、车辆 ID、运动轨迹、测速线和速度信息,同时在页面底部展示结果表格,方便项目演示和结果查看。
项目运行方式
首先进入项目根目录,安装依赖:
pip install -r requirements.txt
然后将 YOLOv8 权重文件放到:
weights/yolov8m.pt
启动项目:
python run.py
启动成功后,在浏览器中访问:
http://127.0.0.1:8000
进入页面后,先上传交通视频,然后设置两条测速线的位置、实际距离和 FPS,保存配置后点击开始检测,即可看到车辆识别和测速结果。
使用流程
- 打开系统首页;
- 上传一段交通视频;
- 根据视频画面设置两条测速线;
- 设置两条线之间的实际距离;
- 设置视频 FPS;
- 保存测速线配置;
- 点击开始检测;
- 查看视频中的车辆框、车辆 ID、轨迹和速度;
- 在下方表格查看每辆车的测速结果。
遇到的问题与解决思路
1. 车辆检测结果不稳定
在视频中,车辆可能会因为遮挡、距离过远、光照变化等原因出现检测框抖动。为了解决这个问题,系统没有直接使用单帧结果测速,而是结合跟踪模块维护车辆轨迹,让测速判断更加连续。
2. 同一辆车 ID 容易变化
如果连续帧之间的检测框变化较大,IOU 匹配可能会出现 ID 切换。项目中通过设置 IOU 阈值和允许丢失帧数,在一定程度上减少 ID 频繁变化的问题。
3. 视频运行速度影响测速结果
如果使用程序运行时间测速,电脑慢一点或者模型推理慢一点,计算出来的速度就会偏低。因此项目改用帧号和 FPS 进行速度计算,让测速结果与视频本身绑定,而不是与电脑运行速度绑定。
4. 不同视频画面测速线位置不同
不同视频的道路位置、摄像头角度和画面分辨率都不一样,固定测速线无法适配所有情况。因此系统将测速线位置做成可配置参数,用户可以根据具体视频进行调整。
后续优化方向
目前系统已经完成了基础的车辆检测、跟踪和测速功能,后续还可以继续扩展:
- 增加检测结果导出 Excel 功能;
- 将测速结果保存到 MySQL 数据库;
- 支持生成检测后的视频文件;
- 增加用户登录和历史记录管理;
- 支持多模型选择;
- 优化测速线拖拽交互,让用户可以直接在画面上拖动线条;
- 增加车流量统计、平均速度统计和超速车辆标记;
- 支持摄像头实时视频流;
- 引入更稳定的 DeepSORT、ByteTrack 等跟踪算法;
- 对测速结果增加误差说明和标定功能。
项目总结
这个项目让我更加完整地理解了 AI 视觉系统从模型到应用的开发流程。YOLOv8 负责车辆检测,OpenCV 负责视频处理和画面绘制,IOU Tracker 负责车辆跟踪,FastAPI 负责后端接口,前端页面负责交互和展示。
通过这个项目,我不只是完成了一个车辆检测模型调用,而是把检测、跟踪、测速和 Web 展示整合成了一个完整系统。这个过程提升了我对计算机视觉应用开发、前后端交互、视频流处理和算法工程化的理解。
项目最大的收获是:AI 项目真正落地时,模型只是其中一部分。如何上传数据、如何配置参数、如何展示结果、如何处理异常、如何让别人看懂并使用系统,同样非常重要。