【动手学YOLO】序列(三):计算机视觉AI工具库(Supervision库)视频处理的相关函数
5.3.1 在线下载视频
我们经常需要用到一些图片或者视频进行目标检测项目的训练、验证或推理。幸运的是,Supervision库自带了一些视频资源,可以利用supervision.assets的download_assets方法非常轻松地将视频下载到本地,方便后续使用。
我们通过下面的代码查看supervision.assets提供的可下载视频。
from supervision.assets import download_assets, VideoAssets
import re
# 查看VideoAssets的属性
my_list = dir(VideoAssets)
# 定义正则表达式模式
pattern = re.compile(r'^__.*__$')
# 使用列表推导式过滤列表
filtered_list = [item for item in my_list ifnot pattern.match(item)]
# 打印结果
print(filtered_list)
输出结果为:
['BASKETBALL', 'BEACH', 'GROCERY_STORE', 'MARKET_SQUARE', 'MILK_BOTTLING_PLANT', 'PEOPLE_WALKING', 'SKIING', 'SUBWAY', 'VEHICLES', 'VEHICLES_2']
在了解可下载的视频清单后,假如我们想下载行人走路的视频,可以通过下面的代码实现。
# 下载一段行人走路的视频
download_assets(VideoAssets.PEOPLE_WALKING)
下载完成后,当前目录中将有一个名为people-walking.mp4的视频文件。可以通过下面的代码读取刚下载的视频信息。
# 读取视频文件的宽度、高度、fps和总帧数。
video_info = sv.VideoInfo.from_video_path(video_path="videos/people-walking.mp4")
video_info
输出结果为:
VideoInfo(width=1920, height=1080, fps=25, total_frames=341)
people-walking.mp4视频的宽度为1920,高度为1080,fps(帧率)为25,总帧数为341。
5.3.2 生成并保存视频
sv.get_video_frames_generator函数可以创建一个生成器,该生成器逐帧生成视频帧。其参数如下:
-
source_path (str): 视频文件路径。 -
stride (int): 表示返回帧的间隔,每间隔 stride – 1 帧返回一个帧。 -
start (int): 表示视频开始生成帧的起始位置。 -
end (Optional[int]): 表示视频停止生成帧的结束位置。如果为 None,视频会一直读取到末尾。 -
iterative_seek (bool): 如果为 True,生成器将通过逐帧抓取的方式定位到 start 帧,这种方式会慢得多。这是对于设置 start 值时无法打开的视频的一种解决方法。
sv.VideoSink类是一个上下文管理器,用于使用OpenCV将视频帧保存到文件中。其参数如下:
-
target_path (str): 输出文件的路径,视频将保存到此位置。 -
video_info (VideoInfo): 视频的分辨率、帧率以及总帧数信息。 -
codec (str): 视频格式的FOURCC代码(默认为’mp4v’)。
下面的代码实现从一个视频文件中每隔10帧提取一帧,最多提取到第100帧(根据 stride 和 end 参数),然后将这些提取出的帧保存到一个新的视频文件中(格式为mp4)。并通过tqdm显示进度条,让用户了解处理进度。
import supervision as sv
from tqdm import tqdm
video_path = "videos/people-walking.mp4"
# 从源视频路径获取视频信息
video_info = sv.VideoInfo.from_video_path(video_path)
# 获取视频帧生成器
frames_generator = sv.get_video_frames_generator(source_path=video_path,
stride=10, start=0, end=100)
TARGET_VIDEO_PATH = "out.mp4"
# 使用VideoSink上下文管理器保存视频帧到目标路径
with sv.VideoSink(target_path=TARGET_VIDEO_PATH, video_info=video_info) as sink:
for frame in tqdm(frames_generator):
sink.write_frame(frame=frame) # 将每一帧写入到目标视频文件中
代码运行后,会在当前目录生成一个名为out.mp4的文件。
我们也可以利用sv.ImageSink类创建一个用于保存图像的上下文管理器,将视频保存为本地图片。其参数如下:
-
target_dir_path (str):图像被保存的目标目录。 -
overwrite (bool):是否覆盖现有目录,默认为 False。 -
image_name_pattern (str):图像文件名的格式。默认为 “image_{:05d}.png”。
通过下面的代码,将视频中的每一帧保存为本地的一张图片。
# 获取视频帧生成器
frames_generator = sv.get_video_frames_generator(source_path=video_path,
stride=10, start=0, end=100)
# 将生成视频保存为图片
with sv.ImageSink(target_dir_path='output', overwrite=True) as sink:
for image in frames_generator:
sink.save_image(image=image)
代码运行后,将在本地生成一个output文件夹,用于存放10张图片。
我们也可以直接将本地的视频文件保存为本地的图片,以下代码实现的结果与上面相同。
# 将本地的视频保存为本地图片
with sv.ImageSink(target_dir_path='output', overwrite=True) as sink:
for image in sv.get_video_frames_generator(source_path='out.mp4'):
sink.save_image(image=image)

夜雨聆风