資料集文件

載入影片資料

Hugging Face's logo
加入 Hugging Face 社群

並獲得增強的文件體驗

開始使用

載入影片資料

影片支援功能目前為實驗性質,未來可能會有變動。

影片資料集具有 Video 類型的欄位,其中包含 torchcodec 物件。

若要使用影片資料集,您需要安裝 torchcodecffmpeg 套件。請參閱安裝指南以了解如何進行安裝。

當您載入影片資料集並呼叫影片欄位時,影片會被解碼為 torchcodec 影片物件。

>>> 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>

請先使用列索引 (row index) 再加上 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)。這將會回傳一個影格批次 (frame batch)。這是獲取大量影格列表的有效方式,請參閱 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 資料集建構器來載入資料集,這不需要撰寫自訂的資料載入器 (dataloader)。這使得 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)

如果您沒有詮釋資料 (metadata) 檔案,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)

Lance

Lance 是一種開放的多模態資料湖倉表格式。Lance 表不僅能原生儲存文字和純量值,還能與您的表格資料一同儲存影像、音訊和影片等大型二進位物件 (blobs)。在 Lance 表中,像影片這樣的大型 Blob 儲存為帶有偏移量的位元組(詳情請參閱 blob 指南),這使得掃描和篩選詮釋資料變得容易,無需載入更沉重的影片 Blob,並可視需要僅擷取您所需的特定影片 Blob。

此外,由於 Lance 是列式格式 (columnar format),您可以僅投影和篩選您關心的詮釋資料欄位(而無需提取大型影片檔案),並在準備好時才檢索少量的列(包含影片)。這將您的詮釋資料和影片集中在一處,而不需要額外的檔案儲存空間或外部索引。

import lance

ds = lance.dataset("hf://datasets/lance-format/openvid-lance/data/train.lance")

# 1. Browse metadata without loading video blobs.
metadata = ds.scanner(
    columns=["caption", "aesthetic_score"],
    filter="aesthetic_score >= 4.5",
    limit=2,
).to_table().to_pylist()

# 2. Fetch a single video blob by row index.
selected_index = 0
blob_file = ds.take_blobs("video_blob", ids=[selected_index])[0]
with open("video_0.mp4", "wb") as f:
    f.write(blob_file.read())

在此範例中,影片以原生方式(編碼後的位元組)儲存在 Lance 表中,因此您可以將其直接寫入本機檔案系統中的 mp4 檔案,無需任何額外的轉換步驟。

有關使用 Lance 資料集的更多詳細資訊,請參閱 Lance 文件

影片解碼

預設情況下,當您迭代資料集時,影片會依序解碼為 torchcodec 的 VideoDecoders。系統會循序解碼影片的詮釋資料,且直到您實際存取它們之前,都不會讀取影片的影格。

然而,使用多執行緒解碼可以顯著加快資料集的處理速度。

>>> 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 更慢。

如果您不希望將影片解碼為 torchcodec 的 VideoDecoders,而是想存取路徑或位元組,則可以停用解碼。

>>> dataset = dataset.decode(False)

注意:IterableDataset.decode() 目前僅適用於串流數據集。

在 GitHub 上更新

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