实战 | 基于YOLOv8的车辆跟踪与车速计算应用(步骤 + 源码)

视觉/图像重磅干货,第一时间送达!

背景介绍

在人工神经网络和计算机视觉领域,物体识别和跟踪是极其重要的技术,可以应用于无数的项目,其中许多可能不是很明显,例如使用这些算法来测量距离或物体的速度。因此,我向你介绍一个旨在使用 YOLOv8 测量高速公路上汽车速度的 Python 项目,目的是让你了解这些算法如何在日常解决方案中使用。

实现步骤

【1】安装依赖项。需要安装opencv-python,ultralytics和lapx:

代码语言:javascript
复制
pip install ultralytics
pip install opencv-python
pip install --no-cache "lapx>=0.5.2"

【2】下载YoloV8模型文件。这里使用的是yolov8s.pt,下载地址:

代码语言:javascript
复制
https://docs.ultralytics.com/tasks/detect/#models

【3】准备测试视频。下载地址:

代码语言:javascript
复制
https://www.youtube.com/watch?v=-59Mr4UTgNg%27

【4】测试代码与运行结果。

完整代码:

代码语言:javascript
复制
from ultralytics import YOLO
from ultralytics.solutions import speed_estimation
import cv2

model = YOLO("yolov8s.pt")
names = model.model.names

cap = cv2.VideoCapture("src.mp4")
assert cap.isOpened(), "Error reading video file"
w, h, fps = (int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS))

video_writer = cv2.VideoWriter("out.avi",
cv2.VideoWriter_fourcc(*'mp4v'),
fps,
(w, h))

line_pts = [(0, 400), (1280, 400)]

speed_obj = speed_estimation.SpeedEstimator()
speed_obj.set_args(reg_pts=line_pts,
names=names,
view_img=True)

while cap.isOpened():

success, im0 = cap.read()
if not success:
    print("Video frame is empty or video processing has been successfully completed.")
    break

tracks = model.track(im0, persist=True, show=False)

im0 = speed_obj.estimate_speed(im0, tracks)
video_writer.write(im0)

cap.release()
video_writer.release()
cv2.destroyAllWindows()

运行结果:

代码解释

【1】识别车辆。为了识别物体,我们使用了可以从ultralytics库中获得的预训练 YOLO模型。该算法可以实时识别感兴趣的物体,并且准确率很高。

代码语言:javascript
复制
model = YOLO("yolov8s.pt")

这里yolov8s 模型已足够。

【2】应用跟踪。YOLO模型中还包含一个跟踪算法,旨在通过连续帧连续监视和跟踪特定对象的运动。它的实现很简单,如下所示:

代码语言:javascript
复制
tracks = model.track(im0, persist=True, show=False)

在这里,我们将一个函数直接合并到对象识别模型中。

【3】定义区域。该项目的一个重要步骤是定义物体必须穿过的区域,以便可以测量该点的穿过时间,从这个参考点我们计算速度。

为此,我们定义该区域应开始和结束的坐标(x 和 y 点),如下所示:

代码语言:javascript
复制
line_pts = [(0, 400), (1280, 400)] #绘制从屏幕一侧到另一侧的线

该区域作为参数传递给负责计算速度的函数:

代码语言:javascript
复制
speed_obj.set_args(reg_pts=line_pts, names=names, view_img=True)

【4】“SpeedEstimator” 如何计算速度?该函数通过存储随时间推移的跟踪位置来处理帧,因此通过比较当前位置与定义区域内的先前位置来计算每个检测到的物体的速度,从而可以通过物体在该区域内移动所需的时间来估算物体的速度,这遵循了物理学中一个非常著名的术语:

v = Δs/Δt

其中,v为速度,Δs为位移(距离),Δt为时间间隔。

代码语言:javascript
复制
line_pts = [(0, 400), (1280, 400)]
speed_obj = speed_estimation.SpeedEstimator()
speed_obj.set_args(reg_pts=line_pts,
names=names,
view_img=True)