为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

莫回无 2022-07-12 10:27:20
是否可以使用 PyAV 将视频直接读入 3D Numpy?目前,我正在遍历每一帧:i = 0container = 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 灰度帧数组。
查看完整描述

1 回答

?
临摹微笑

TA贡献1982条经验 获得超2个赞

我找不到使用 PyAV 的解决方案,而是使用ffmpeg-python

ffmpeg-pythonFFmpeg的 Pythonic 绑定,例如PyAV

该代码一次将整个视频读入灰度帧的 3D Numpy 数组。

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

  • 创建一个输入视频文件(用于测试)。

  • 使用“探针”获取视频文件的分辨率。

  • 将视频流式传输到字节数组中。

  • 将字节数组重塑为n x height x widthnumpy 数组。

  • 显示第一帧(用于测试)。

这是代码(请阅读评论):

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 to get video frames resolution

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

输出:

//img1.sycdn.imooc.com//62ccdc2b0001a8fe01620128.jpg

查看完整回答
反对 回复 2022-07-12
  • 1 回答
  • 0 关注
  • 234 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信