所有人。
现在我有一个对象分类任务,并且我有一个包含大量视频的数据集。在每个视频中,有些帧(不是每帧,约16万帧)都有其标签,因为一个帧可能有多个对象。
我对创建数据集有些困惑。我的想法是先将视频转换为帧,然后将仅带有标签的每个帧制作为tfrecord或hdf5格式。最后,我将每帧的路径写入用于任务的csv文件(训练和验证)中。
我的问题是: 1.是否有足够的效率(tfrecord或hdf5)?在创建tfrecord或hdf5文件之前,是否应该对每一帧进行预处理(例如压缩)以节省存储空间? 2.有没有一种方法可以直接在tensorflow或pytorch中处理视频数据集?
我想找到一种有效且常规的方式来处理视频数据集。真的很期待每个答案。
答案 0 :(得分:1)
我不是TensorFlow的人,所以抱歉,我的回答无法解决问题。
由于利用数据中的时间相关性,视频格式通常以更长的随机访问时间为代价获得压缩。这是有道理的,因为通常是按顺序访问视频帧,但是如果访问完全是随机的,建议您转换为hdf5。否则,如果您访问视频的子序列,则保持视频格式可能有意义。
PyTorch对视频AFAIK没有任何“有福”的方法,但是我使用imageio
来阅读视频并查找特定的帧。简短的包装使其遵循PyTorch Dataset
API。该代码相当简单,但有一个警告,必须将其与多处理DataLoader
结合使用。
import imageio, torch
class VideoDataset:
def __init__(self, path):
self.path = path
# explained in __getitem__
self._reader = None
reader = imageio.get_reader(self.path, 'ffmpeg')
self._length = reader.get_length()
def __getitem__(self, ix):
# Below is a workaround to allow using `VideoDataset` with
# `torch.utils.data.DataLoader` in multiprocessing mode.
# `DataLoader` sends copies of the `VideoDataset` object across
# processes, which sometimes leads to bugs, as `imageio.Reader`
# does not support being serialized. Since our `__init__` set
# `self._reader` to None, it is safe to serialize a
# freshly-initialized `VideoDataset` and then, thanks to the if
# below, `self._reader` gets initialized independently in each
# worker thread.
if self._reader is None:
self._reader = imageio.get_reader(self.path, 'ffmpeg')
# this is a numpy ndarray in [h, w, channel] format
frame = self._reader.get_data(ix)
# PyTorch standard layout [channel, h, w]
return torch.from_numpy(frame.transpose(2, 0, 1))
def __len__(self):
return self.length
此代码可以调整为支持多个视频文件,并根据需要输出标签。