如何在NumPy阵列中转换视频

mefy6pfw  于 2022-11-10  发布在  其他
关注(0)|答案(1)|浏览(221)

程序将视频文件转换为NumPy数组,反之亦然。我搜索了很多搜索引擎,但都找不到答案。

4nkexdtk

4nkexdtk1#

人们为此使用了多个库(即PyAVdecordopencv);我个人经常使用Python OpenCV(主要是通过PyTorch,但这是一个相似的原则),所以我将在那里谈谈我的经验。您可以使用cv2.VideoCapture将视频文件加载到numpy数组中;理论上,您也可以使用cv2.VideoWriter将其写回,但在实践中,我很难让它在我自己的项目中工作。

视频到Numpy阵列

Tl;dr:创建cv2.VideoCapture Package 器;迭代加载视频中的图片(即帧)。

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无缝地工作。

相关问题