gpt4 book ai didi

python - 使用 PyAV 将视频直接读入 Numpy(无迭代)

转载 作者:太空宇宙 更新时间:2023-11-03 19:48:43 32 4
gpt4 key购买 nike

是否可以使用 PyAV 将视频直接读入 3D Numpy?目前,我正在循环每一帧:

i = 0
container = av.open('myvideo.avi')
for frame in container.decode(video=0):
if i == 0: V = np.array(frame.to_ndarray(format='gray'))
else: V = np.dstack((V, np.array(frame.to_ndarray(format='gray'))))
i += 1

第一帧定义了一个2D Numpy数组(i=0);每个后续帧 (i>0) 都使用 np.dstack 堆叠到第一个数组上。理想情况下,我想一次性将整个视频读入 3D Numpy 灰度帧数组。

最佳答案

我找不到使用 PyAV 的解决方案,并使用 ffmpeg-python相反。

ffmpeg-pythonFFmpeg 的 Pythonic 绑定(bind)就像PyAV

代码一次性将整个视频读取到灰度帧的 3D NumPy 数组中。

该解决方案执行以下步骤:

  • 创建输入视频文件(用于测试)。
  • 使用“probe”获取视频文件的分辨率。
  • 将视频流式传输到字节数组中。
  • 将字节数组 reshape 为 n x height x width NumPy 数组。
  • 显示第一帧(用于测试)。

这是代码(请阅读注释):

import ffmpeg
import numpy as np
from PIL import Image

in_filename = 'in.avi'

"""Build synthetic video, for testing begins:"""
# ffmpeg -y -r 10 -f lavfi -i testsrc=size=160x120:rate=1 -c:v libx264 -t 5 in.mp4
width, height = 160, 120

(
ffmpeg
.input('testsrc=size={}x{}:rate=1'.format(width, height), r=10, f='lavfi')
.output(in_filename, vcodec='libx264', t=5)
.overwrite_output()
.run()
)
"""Build synthetic video ends"""


# Use FFprobe for getting the resolution of the video frames
p = ffmpeg.probe(in_filename, select_streams='v');
width = p['streams'][0]['width']
height = p['streams'][0]['height']

# https://github.com/kkroening/ffmpeg-python/blob/master/examples/README.md
# Stream the entire video as one large array of bytes
in_bytes, _ = (
ffmpeg
.input(in_filename)
.video # Video only (no audio).
.output('pipe:', format='rawvideo', pix_fmt='gray') # Set the output format to raw video in 8 bit grayscale
.run(capture_stdout=True)
)

n_frames = len(in_bytes) // (height*width) # Compute the number of frames.
frames = np.frombuffer(in_bytes, np.uint8).reshape(n_frames, height, width) # Reshape buffer to array of n_frames frames (shape of each frame is (height, width)).

im = Image.fromarray(frames[0, :, :]) # Convert first frame to image object
im.show() # Display the image
<小时/>

输出:
enter image description here

<小时/>

更新:

使用PyAV:

使用 PyAV 时,我们必须逐帧解码视频。

使用 PyAV 相对于 ffmpeg-python 的主要优点是,我们可以在没有 FFmpeg CLI 的情况下使用它(Windows 中没有 ffmpeg.exe)。

为了将所有视频帧读取到一个 NumPy 数组中,我们可以使用以下阶段:

  • 解码每一帧并将其转换为 NumPy 数组。
  • 将 NumPy 数组附加到列表中。
  • 迭代所有视频帧后,将列表转换为包含所有帧的 NumPy 数组。
<小时/>

代码示例(使用 OpenCV 显示测试框架):

import av
import numpy as np
import cv2

# Build input file using FFmpeg CLI (for testing):
# ffmpeg -y -f lavfi -i testsrc=size=192x108:rate=1:duration=10 -vcodec libx264 -pix_fmt yuv420p myvideo.avi

container = av.open('myvideo.avi')

frames = [] # List of frames - store video frames after converting to NumPy array.

for frame in container.decode(video=0):
# Decode video frame, and convert to NumPy array in BGR pixel format (use BGR because it used by OpenCV).
frame = frame.to_ndarray(format='bgr24') # For Grayscale video, use: frame = frame.to_ndarray(format='gray')
frames.append(frame) # Append the frame to the list of frames.

# Convert the list to NumPy array.
# Shape of each frame is (height, width, 3) [for Grayscale the shape is (height, width)]
# the shape of frames is (n_frames, height, width, 3) [for Grayscale the shape is (n_frames, height, width)]
frames = np.array(frames)

# Show the frames for testing:
for i in range(len(frames)):
cv2.imshow('frame', frames[i])
cv2.waitKey(1000)

cv2.destroyAllWindows()

关于python - 使用 PyAV 将视频直接读入 Numpy(无迭代),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59973078/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com