Datasets 文档

加载视频数据

Hugging Face's logo
加入 Hugging Face 社区

并获得增强的文档体验

开始使用

加载视频数据

视频支持尚处于实验阶段,并可能发生更改。

视频数据集包含 Video 类型列,其中包含 torchvision 对象。

要使用视频数据集,您需要安装 torchvisionav 包。请查看 安装指南了解如何安装它们。

加载视频数据集并调用视频列时,视频将解码为 torchvision Videos

>>> from datasets import load_dataset, Video

>>> dataset = load_dataset("path/to/video/folder", split="train")
>>> dataset[0]["video"]
<torchcodec.decoders._video_decoder.VideoDecoder object at 0x14a61d5a0>

使用行索引,然后是 video 列来索引视频数据集 - dataset[0]["video"] - 以避免创建数据集中的所有视频对象。否则,如果您有一个大型数据集,这可能会是一个缓慢而耗时的过程。

有关如何加载任何类型数据集的指南,请参阅通用加载指南

读取帧

使用 VideoReader 通过 next() 直接访问视频帧

>>> video = dataset[0]["video"]
>>> first_frame = video.get_frame_at(0)
>>> first_frame.data.shape
(3, 240, 320)
>>> first_frame.pts_seconds  # timestamp
0.0

要一次获取多个帧,您可以调用 .get_frames_in_range(start: int, stop: int, step: int)。这将返回一个帧批。这是获取长帧列表的有效方法,请参阅 torchcodec 文档以了解更多用于有效访问数据的函数。

>>> import torch
>>> frames = video.get_frames_in_range(0, 6, 1)
>>> frames.data.shape
torch.Size([5, 3, 240, 320])

还有一个 .get_frames_played_in_range(start_seconds: float, stop_seconds: float),用于访问在特定时间范围内播放的所有帧。

>>> frames = video.get_frames_played_in_range(.5, 1.2)
>>> frames.data.shape
torch.Size([42, 3, 240, 320])

本地文件

您可以从视频路径加载数据集。使用 cast_column() 函数接受视频文件路径列,并使用 Video 特征将其解码为 torchcodec 视频。

>>> from datasets import Dataset, Video

>>> dataset = Dataset.from_dict({"video": ["path/to/video_1", "path/to/video_2", ..., "path/to/video_n"]}).cast_column("video", Video())
>>> dataset[0]["video"]
<torchcodec.decoders._video_decoder.VideoDecoder object at 0x14a61e080>

如果您只想加载视频数据集的底层路径而不解码视频对象,请在 Video 特征中设置 decode=False

>>> dataset = dataset.cast_column("video", Video(decode=False))
>>> dataset[0]["video"]
{'bytes': None,
 'path': 'path/to/video/folder/video0.mp4'}

VideoFolder

您也可以使用 VideoFolder 数据集构建器加载数据集,该构建器不需要编写自定义数据加载器。这使得 VideoFolder 非常适合快速创建和加载具有数千个视频的大型视频数据集,用于不同的视觉任务。您的视频数据集结构应如下所示:

folder/train/dog/golden_retriever.mp4
folder/train/dog/german_shepherd.mp4
folder/train/dog/chihuahua.mp4

folder/train/cat/maine_coon.mp4
folder/train/cat/bengal.mp4
folder/train/cat/birman.mp4

如果数据集遵循 VideoFolder 结构,则可以直接使用 load_dataset() 加载它。

>>> from datasets import load_dataset

>>> dataset = load_dataset("username/dataset_name")
>>> # OR locally:
>>> dataset = load_dataset("/path/to/folder")

对于本地数据集,这等同于在 load_dataset() 中手动传递 videofolder,并在 data_dir 中传递目录。

>>> dataset = load_dataset("videofolder", data_dir="/path/to/folder")

然后,您可以将视频作为 torchcodec.decoders._video_decoder.VideoDecoder 对象进行访问。

>>> dataset["train"][0]
{"video": <torchcodec.decoders._video_decoder.VideoDecoder object at 0x14a61e080>, "label": 0}

>>> dataset["train"][-1]
{"video": <torchcodec.decoders._video_decoder.VideoDecoder object at 0x14a61e090>, "label": 1}

要忽略元数据文件中的信息,请在 load_dataset() 中设置 drop_metadata=True

>>> from datasets import load_dataset

>>> dataset = load_dataset("username/dataset_with_metadata", drop_metadata=True)

如果您没有元数据文件,VideoFolder 会自动从目录名称推断标签名称。如果您想删除自动创建的标签,请设置 drop_labels=True。在这种情况下,您的数据集将只包含一个视频列。

>>> from datasets import load_dataset

>>> dataset = load_dataset("username/dataset_without_metadata", drop_labels=True)

最后,filters 参数允许你仅加载数据集的子集,该子集基于标签或元数据的条件。如果你使用的是 Parquet 格式的元数据,这一点尤其有用,因为这种格式支持快速过滤。还建议将此参数与 streaming=True 一起使用,因为默认情况下,数据集会在过滤之前被完全下载。

>>> filters = [("label", "=", 0)]
>>> dataset = load_dataset("username/dataset_name", streaming=True, filters=filters)

有关创建自己的 VideoFolder 数据集的更多信息,请参阅 创建视频数据集指南。

WebDataset

WebDataset 格式基于 TAR 存档文件夹,适用于大型视频数据集。由于其大小,WebDatasets 通常以流式传输模式加载(使用 streaming=True)。

您可以像这样加载 WebDataset:

>>> from datasets import load_dataset

>>> dataset = load_dataset("webdataset", data_dir="/path/to/folder", streaming=True)

视频解码

默认情况下,当您迭代数据集时,视频会作为 torchvision VideoReaders 顺序解码。它会顺序解码视频的元数据,并且在您访问它们之前不会读取视频帧。

但是,通过多线程解码可以显著加快数据集的速度。

>>> import os
>>> num_threads = num_threads = min(32, (os.cpu_count() or 1) + 4)
>>> dataset = dataset.decode(num_threads=num_threads)
>>> for example in dataset:  # up to 20 times faster !
...     ...

您可以使用 num_threads 启用多线程。这对于加快远程数据流传输特别有用。但是,对于快速磁盘上的本地数据,它可能比 num_threads=0 慢。

如果您不关心解码为 torchvision VideoReaders 的视频,并且希望访问路径/字节而不是,则可以禁用解码。

>>> dataset = dataset.decode(False)

注意:IterableDataset.decode() 目前仅适用于流式数据集。

在 GitHub 上更新

© . This site is unofficial and not affiliated with Hugging Face, Inc.