【发布时间】:2021-04-03 09:16:14
【问题描述】:
将视频文件转换为 NumPy 数组的程序,反之亦然。我搜索了很多搜索引擎,但都找不到答案。
【问题讨论】:
标签: python arrays numpy cv2 converters
将视频文件转换为 NumPy 数组的程序,反之亦然。我搜索了很多搜索引擎,但都找不到答案。
【问题讨论】:
标签: python arrays numpy cv2 converters
人们为此使用了多个库(即PyAV、decord、opencv);我个人为此经常使用 Python OpenCV(主要是使用 PyTorch,但原理相似),所以我将谈谈我在那里的经验。您可以使用cv2.VideoCapture 将视频文件加载到numpy 数组中;理论上,您也可以使用cv2.VideoWriter 将其写回,但实际上,我很难在自己的项目中使用它。
tl;dr: 创建一个cv2.VideoCapture 包装器;从视频中迭代加载图像(即帧)。
frames = []
path = "/path/to/my/video/file.mp4"
cap = cv2.VideoCapture(path)
ret = True
while ret:
ret, img = cap.read() # read one frame from the 'capture' object; img is (H, W, C)
if ret:
frames.append(img)
video = np.stack(frames, axis=0) # dimensions (T, H, W, C)
请注意,图像将以 BGR 通道格式返回,而不是更常见的 RGB;如果您需要将其转换为 RGB 颜色空间,img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) 就足够了。
理论上,我看到的使用 cv2.VideoWriter 的示例类似于
# let `video` be an array with dimensionality (T, H, W, C)
num_frames, height, width, _ = video.shape
filename = "/path/where/video/will/be/saved.mp4"
codec_id = "mp4v" # ID for a video codec.
fourcc = cv2.VideoWriter_fourcc(*code)
out = cv2.VideoWriter(filename, fourcc, 20, (width, height))
for frame in np.split(video, num_frames, axis=0):
out.write(frame)
您也可以将帧保存到临时图像(存在许多 np.ndarray -> 图像管道;我个人使用 Pillow),然后使用 ffmpeg(命令行实用程序)将帧编码为视频文件.不过,这会占用更多空间,当我需要检查视频阵列的各个帧时,我会使用此方法(在这种情况下,我使用 ffmpeg,但这是另一回事)。
另外,您可能需要更改 codec_id 变量,具体取决于您希望如何对视频进行编码(如果这对您没有任何意义,请不要担心 - 这对您来说可能无关紧要应用);这只是一个四字节代码,用于标识用于生成视频的视频编解码器(请参阅this page;可用性可能因平台而异(。H.264 是当今 AFAIK 中最常用的一种,由代码给出“H264”或“X264”,但我无法让它与 OpenCV (more details here) 一起使用;但是,array -> images -> video file 方法与命令行中的 ffmpeg 无缝协作。
【讨论】: