当前位置:网站首页 >  攻略

零基础实战:基于YOLOv8的实时汽车流量检测系统

时间:2026年06月10日 16:59:56 来源:易频IT社区

环境准备与依赖安装

在开始编写代码之前,必须先配置好Python运行环境。本指南基于Python 3.8或更高版本进行开发,所有操作均在命令行终端中完成,无需复杂的手动配置。

1. 安装核心依赖库

我们需要使用ultralytics库来加载YOLOv8模型,以及opencv-python来处理视频流。请在终端中直接执行以下命令进行安装:

``` pip install ultralytics opencv-python numpy ```

注意:如果你的网络环境访问官方源较慢,请务必使用国内镜像源加速安装,命令如下:

``` pip install ultralytics opencv-python numpy -i https://pypi.tuna.tsinghua.edu.cn/simple ```

2. 准备测试视频素材

为了验证代码效果,你需要一段包含车辆行驶的视频。你可以使用自己的监控视频,或者下载公开的交通数据集。为了方便测试,建议准备一个名为traffic.mp4的视频文件放在代码同级目录下。如果没有视频,代码也支持直接调用电脑摄像头进行实时检测。

核心代码实现

本系统将实现一个虚拟“检测线”,当车辆穿过该线时自动计数。这种方式比单纯的检测框数量更准确,能够有效避免同一辆车被重复计数。我们将利用YOLOv8内置的追踪功能来实现。

1. 完整代码逻辑

新建一个名为car_counter.py的文件,将以下代码完整复制进去。这段代码包含了模型加载、视频读取、目标追踪、穿越判断以及结果可视化。

``` from ultralytics import YOLO import cv2 def count_vehicles(): 加载预训练的YOLOv8n模型,首次运行会自动下载权重文件 model = YOLO('yolov8n.pt') 初始化视频捕获对象,0表示调用摄像头,或者替换为'traffic.mp4'读取本地视频 cap = cv2.VideoCapture(0) 获取视频的宽度和高度,用于设置检测线位置 width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) 设置检测线的位置(在画面垂直方向的一半处) line_y = height // 2 初始化计数器和车辆轨迹记录字典 vehicle_count = 0 track_history = {} 定义我们需要检测的车辆类别,对应COCO数据集的ID 2: car, 3: motorcycle, 5: bus, 7: truck target_classes = [2, 3, 5, 7] print(f"系统启动中... 检测线位置: Y={line_y}") print("按 'q' 键退出程序") while cap.isOpened(): success, frame = cap.read() if not success: print("视频读取结束或摄像头断开") break 使用model.track进行追踪,persist=True保持轨迹ID在帧之间的连续性 results = model.track(frame, persist=True, classes=target_classes, verbose=False) if results[0].boxes.id is not None: 获取检测框的ID、坐标和类别 boxes = results[0].boxes.xywh.cpu() 中心点x, 中心点y, 宽, 高 track_ids = results[0].boxes.id.int().cpu().tolist() for box, track_id in zip(boxes, track_ids): x, y, w, h = box current_y = float(y) 判断车辆是否穿越检测线 逻辑:如果车辆ID存在于历史记录中,且上一帧在检测线上方,当前帧在检测线下方 if track_id in track_history: prev_y = track_history[track_id] 从上往下穿过 (prev_y < line_y <= current_y) if prev_y < line_y and current_y >= line_y: vehicle_count += 1 print(f"车辆通过! 当前总数: {vehicle_count}") 从下往上穿过 (prev_y > line_y >= current_y),如果需要双向统计请取消注释 elif prev_y > line_y and current_y <= line_y: vehicle_count += 1 print(f"车辆通过! 当前总数: {vehicle_count}") 更新该ID的Y坐标记录 track_history[track_id] = current_y 在画面上绘制追踪框和ID cv2.rectangle(frame, (int(x - w / 2), int(y - h / 2)), (int(x + w / 2), int(y + h / 2)), (0, 255, 0), 2) cv2.putText(frame, f"ID: {track_id}", (int(x - w / 2), int(y - h / 2) - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1) 绘制红色检测线 cv2.line(frame, (0, line_y), (width, line_y), (0, 0, 255), 2) 显示当前计数 cv2.putText(frame, f"Count: {vehicle_count}", (20, 50), cv2.FONT_HERSHEY_SIMPLEX, 1.5, (0, 0, 255), 3) 显示处理后的画面 cv2.imshow("Vehicle Counting System", frame) 按q退出 if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows() if __name__ == "__main__": count_vehicles() ```

2. 代码关键点解析

为了确保你能够理解并根据实际情况修改代码,以下对核心逻辑进行详细拆解:

  • 模型选择 (YOLO('yolov8n.pt')):这里使用的是yolov8n.pt,即Nano版本。它的优点是速度极快,适合CPU实时运行。如果你需要更高的检测精度(例如识别远处的车辆),可以将文件名替换为yolov8s.ptyolov8m.pt,但运行速度会相应变慢。
  • 视频源设置 (cv2.VideoCapture):代码中默认传入参数0,这会调用你电脑的默认摄像头。如果你想测试本地视频文件,请将0修改为你的视频文件名,例如cv2.VideoCapture('highway_video.mp4')
  • 目标追踪:这是实现准确计数的核心。普通的model()只能检测,无法区分帧与帧之间的关系。使用model.track()后,每个检测到的物体都会获得一个唯一的track_id。只有当同一个ID的车辆中心点坐标跨越了设定的line_y时,计数器才会+1。
  • 类别过滤 (target_classes):我们只关心车辆。代码中定义的[2, 3, 5, 7]分别对应COCO数据集中的Car(汽车)、Motorcycle(摩托车)、Bus(巴士)和Truck(卡车)。如果你只想统计轿车,可以将其修改为[2]

运行与验证

代码编写完成后,直接在终端运行脚本即可启动系统。

1. 启动命令

零基础实战:基于YOLOv8的实时汽车流量检测系统

car_counter.py文件所在目录下打开终端,执行:

``` python car_counter.py ```

2. 观察输出

启动后,屏幕会弹出一个名为“Vehicle Counting System”的窗口。你会看到画面中间有一条红色的横线。当你(或视频中的车辆)从上往下穿过这条红线时,左上角的“Count”数值会增加,同时终端控制台会打印出“车辆通过!”的日志。

常见问题处理与优化

在实际落地过程中,可能会遇到以下具体问题,请参考对应的解决方案进行调整。

1. 检测线位置调整

默认检测线在画面正中间(height // 2)。如果你的摄像头架设位置较高,或者车辆主要在画面下方行驶,可以手动修改line_y的值。例如,设置为画面高度的3/4处:

``` line_y = int(height 0.75) ```

2. 摄像头帧率低导致丢车

如果使用的是USB摄像头且帧率较低(低于15FPS),车辆在两帧之间移动距离过大,可能会直接跳过检测线,导致漏计。解决方法是在代码中增加“缓冲区”逻辑,或者改用更粗的“检测带”代替“检测线”。简单的优化是将判断逻辑从==改为范围判断:

``` 定义检测带区域 line_y_top = height // 2 - 10 line_y_bottom = height // 2 + 10 修改判断逻辑 if prev_y < line_y_top and current_y >= line_y_bottom: vehicle_count += 1 ```

3. 逆行车辆误计

默认代码只统计“从上往下”穿的车辆。如果是双向车道,且你需要统计双向流量,请取消代码中“从下往上穿过”部分的注释。如果只想统计单向,请确保检测线方向与车流方向垂直,并检查坐标判断逻辑是否符合你的实际车流方向(例如车流是从左往右,则需要判断x坐标的变化)。

4. 保存统计结果

当前的计数只在程序运行时存在于内存中。如果你需要将结果保存到日志文件,可以在vehicle_count += 1下方添加文件写入代码:

``` with open("traffic_log.txt", "a") as f: f.write(f"Time: {timestamp}, Count: {vehicle_count}\n") ```

通过以上步骤,你已经拥有了一个完全可用的汽车流量统计系统。该方案成本低廉,只需一个普通的USB摄像头或现成的视频文件即可运行,且代码结构清晰,便于后续集成到更大的监控平台中。

标签 汽车流量

相关推荐

最新

热门

推荐

精选

标签

易频IT社区是综合性互联网IT技术门户网站,专注分享网络技术、服务器运维、网络安全、编程开发、系统架构、云计算、大数据等行业干货,实时更新IT行业资讯、零基础教程、实战案例,为IT从业者、技术爱好者提供专业的学习交流平台。

Copyright © 2021-2026 易频IT社区. All Rights Reserved. 备案号:闽ICP备2023013482号 网站地图