编写程序将视频文件转换为NumPy数组,反之亦然。我在许多搜索引擎上进行了搜索,但无法找到答案。
编写程序将视频文件转换为NumPy数组,反之亦然。我在许多搜索引擎上进行了搜索,但无法找到答案。
有多个库可用于此(例如PyAV
,decord
,opencv
); 我个人经常使用Python OpenCV(主要与PyTorch一起使用,但原理相似),因此我将分享我的经验。您可以使用cv2.VideoCapture
将视频文件加载到numpy
数组中;理论上,您也可以使用cv2.VideoWriter
将其写回,但在实践中,我在自己的项目中很难使其奏效。
简而言之:创建一个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(*codec_id)
out = cv2.VideoWriter(filename, fourcc=fourcc, fps=20, frameSize=(width, height))
for frame in np.split(video, num_frames, axis=0):
out.write(frame)
np.ndarray
-> 图像的管道;我个人使用Pillow),然后使用ffmpeg
(一个命令行实用程序)将帧编码为视频文件。虽然这需要更多的空间,但当我需要检查视频数组的各个帧时,我会使用此方法(在这种情况下,我使用ffmpeg
,但那是另一种谈话)。codec_id
变量(如果这对您毫无意义,请不用担心 -- 这对您的应用程序可能没有影响);这只是一个四字节代码,用于标识生成视频所使用的视频编解码器(请参见此页面;可用性因平台而异。AFAIK,今天最常用的是H.264,其代码为“H264”或“X264”,但我尝试使用OpenCV时遇到了麻烦(更多细节请看这里);但是,从命令行使用ffmpeg
的数组 -> 图像 -> 视频文件
方法可无缝运行。