我们得到了某监控点的检测视频数据,需要从数据当中得到车流量、速度、车辆时间占用率等基本数据然后用于车道推测拥堵。以某一路段内检测点为例利用YOLOv8实战检验。
假设:
- 车辆只有轿车与卡车两种类型并分别设置车长;
- 某路段只检测双车道并且应急车道不开放;
- YOLOv8在该情况下检测是准确的;
准备工作
首先需要安装python以及安装对应的库ultralytics,安装python可以参考CapRogers1之前的案例:利用背景去除和OpenCV哈里斯角点+透视变换实现任意四边物体的图像矫正-CSDN博客
安装完成python后需要安装对应库,首先我们新建一个文件夹将生数据放入其中并将文件夹命名为rawdata,内部存放采集的视频生数据。
接下来在此文件夹创建python虚拟环境,在此文件夹路径下打开一个终端(powershell或者cmd)并输入:
python -m venv venv
显示如上图所示表示创建成功。
首先由于我们接下来要处理视频文件,因此需要加快推理速度,建议有N卡的使用英伟达CUDA进行推理加速,首先安装CUDA,安装CUDA和cuDNN可参考:CUDA安装及环境配置,注意安装和自己显卡版本匹配的CUDA。
安装完成后然后回到之前的文件夹重新打开终端输入:
.\venv\Scripts\Activate.ps1
然后进入虚拟环境,接下来需要安装GPU版本的torch和torchvision,首先查看自己安装的CUDA是什么版本:
nvcc --version
例如我的cuda版本是11.6:
那么按照对应版本的torch,例如我的11.6版本cuda就寻找后缀是cu116,可以前往https://download.pytorch.org/whl/torch_stable.html查找对应版本torch和torchvision,同时注意torch和torchvision版本也是要对应的,查看对应版本的torch和对应vision可参考Torch和torchvision对应版本表
然后输入确定好的版本进行安装,以cu116为例输入下列指令:
pip install torch==1.13.1+cu116 -f https://download.pytorch.org/whl/torch_stable.html
pip install torchvision==0.14.1+cu116 -f https://download.pytorch.org/whl/torch_stable.html
安装完成torch-cu116显示如下:
安装完成torchvision-cu116显示如下:
然后再安装支持上述版本的ultralytics。
pip install ultralytics==8.2.21
输入上述代码后会自动安装yolov8并且安装其对应的依赖,已经安装的torch和torchvision在其支持版本内会自动跳过安装。
最后有显示successfully installed ultralytics表示安装成功。
Troubleshot
如果出现collection has no attribute的类似保存可以尝试输入下列指令重装:
pip uninstall ultralytics
pip install ultralytics==8.2.21
如果有报错如下:
如果出现上述错误说明numpy版本不匹配,由于pip自动安装最新版本numpy,如果出现上述错误请在虚拟环境内输入:
pip install numpy==1.23.5
检测是否安装成功,虚拟环境内输入:
yolo
如果显示如上表示安装成功,同时也可以用虚拟环境的python解释器输入import ultralytics检测。
预处理
首先需要对原本检测录像当中十抽一的视频裁剪非车道部分并去除然后为了方便计算进行降10帧逐帧处理。
预处理第一步:利用OpenCV可以对视频进行降帧处理:
import os
import cv2
input_root = 'rawdata' # 原始视频文件夹路径
output_root = 'slower' # 慢动作视频保存路径
slow_motion_factor = 10
# 检查并创建输出目录
if not os.path.exists(output_root):
os.makedirs(output_root)
total_videos = 0
for folder_name in ['32.31.250.103', '32.31.250.105', '32.31.250.107', '32.31.250.108']:
input_folder = os.path.join(input_root, folder_name)
total_videos += len([file for file in os.listdir(input_folder) if file.endswith('.mp4')])
video_index = 0
# 遍历 rawdata 文件夹中的子文件夹
for folder_name in ['32.31.250.103', '32.31.250.105', '32.31.250.107', '32.31.250.108']:
input_folder = os.path.join(input_root, folder_name)
output_folder = os.path.join(output_root, folder_name)
if not os.path.exists(output_folder):
os.makedirs(output_folder)
# 遍历该文件夹中的所有视频文件
for video_file in os.listdir(input_folder):
if video_file.endswith('.mp4'):
input_video_path = os.path.join(input_folder, video_file)
output_video_path = os.path.join(output_folder, video_file.replace('.mp4', '_slower.mp4'))
cap = cv2.VideoCapture(input_video_path)
if not cap.isOpened():
print(f"Error: Unable to open video {input_video_path}")
continue
fps = cap.get(cv2.CAP_PROP_FPS)
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
frame_size = (width, height)
total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) # 总帧数
# 计算新帧率
new_fps = fps / slow_motion_factor
# 定义输出视频的编码器和创建 VideoWriter 对象
fourcc = cv2.VideoWriter_fourcc(*'mp4v') # 使用 'mp4v' 编码格式保存为 MP4 文件
out = cv2.VideoWriter(output_video_path, fourcc, new_fps, frame_size)
video_index += 1
# 输出处理进度(正在处理第几个视频)
print(f"Processing video {video_index}/{total_videos}: {video_file}")
# 逐帧读取视频,写入到新文件
frame_count = 0
while True: