有哪些好用的Python库可以操作视频文件的帧?

13

我正在寻找一个Python视频处理库,类似于 PIL,其中我可以遍历源视频的所有帧,访问每个帧的像素数据,在每个帧上绘制并将结果保存为新的视频文件。

我找到了几个类似的问题,但它们现在已经过时了:

它们推荐使用PyMediaPyFFMPEG。 PyMedia似乎已经过时了(但仍然可能有效),而PyFFMPEG虽然更近期,但几乎没有文档。

我在Ubuntu 10.10上安装这两者都没有成功,所以在我继续之前,是否有:

a)更好的库我应该看看?

b)关于如何安装和运行这些的详细说明?

5个回答

9
我经常需要同样的东西,据我所知,在Python中没有良好的绑定解决方案。此外,操作视频文件的帧并不像看起来那么简单。现代视频文件格式不是将每个帧存储在另一个帧之后,而是使用“增量帧”,其中仅存储从一个帧到另一个帧的更改。其他考虑因素,如具有可变帧速率的视频,使问题更加困难。过去,我使用以下命令从视频生成图像。
ffmpeg -i /path/to/file.mpg -an -r 30 -s 320x240 tmp%06d.jpg

其中30是目标帧率,320x240是图像尺寸,tmp%06d.jpg是用于存储生成的JPEG文件的模式。然后您可以使用PIL来操作每个帧,并使用mencoder或ffmpeg将图像再次拼接成电影:

ffmpeg -r 30 -i tmp%06d.jpg output.mpg

显然,你会失去音频轨道。

是的,这就是我一直在尝试的,但它似乎非常浪费,而且应该有一种解决方案可以削减中间图像文件(因为它们有成千上万个)。我理解关键帧的问题,但我并不期望这里是无损过程。音轨可以很容易地用mencoder剥离出来并混合回去,ffmpeg也应该可以。 - Tom
这是一个合理的入门方法,也许是一个不错的简化,但把“现代视频文件格式使用增量帧”减少到这种程度可能太过简单了。算法在编解码器中有很大的差异,并且一些更复杂的编解码器使用许多不同类型的帧,而且大多数并没有保留所有数据(有损 vs 无损)。例如,H264会尝试保留对人类感知重要的帧数据。 - Profane

3

我为您推荐 scikit-video,这是我见过的最简单直接的Python视频处理库。

以下是官方网站对scikit-video的介绍:

Scikit-video旨在使用Python轻松进行视频处理。 它的设计灵感来自于其他成功的scikits,例如scikit-learn和scikit-image。 scikit-video的开发人员知道存在用于操作视频的库,例如PyFFmpeg,MoviePy,PyAV,imageIO和opencv。 但是,没有发现提供研究级别的视频处理工具的全能解决方案的库。


2

我一直在考虑使用py.processing来完成类似的工作。它可以做到你所需要的一切,但它是一个混合体与Processing。你并不是在写Python代码本身。 无论如何,它使得工作变得非常容易,但有很多程序/解释开销,因此实时修改电影可能会很慢。你说你想编辑文件,所以应该是可行的。


0

我发现imageio是最容易使用的Python视频处理库。 它可以轻松地逐帧读取视频、进行处理并保存回磁盘。现在,作者还提供了一个方便的pip install wrapper for ffmpeg,可以在Windows、Linux或OSX上使用。这个库还有一个活跃的社区,在[python-imageio]标签下回答与该库相关的问题。


0

你可以使用我的VidGear视频处理Python库的WriteGear API来利用FFmpeg支持的几乎所有可用参数(帧速率、比特率、编解码器、格式和大小、复用、解复用等)在压缩模式中轻松灵活地进行操作,同时它会非常静默地稳定处理整个过程中的所有错误/警告。

参数:

例如,为了使用x264编码器生成高质量视频的H.264,我们可以按以下方式调整其参数以产生无损输出视频:

 output_params = {"-vcodec":"libx264", "-crf": 0, "-preset": "fast", "tune": "zerolatency"} 

然后将此字典传递给WriteGear,如下所示的示例。

基本用法示例

# import libraries
from vidgear.gears import WriteGear
import cv2

output_params = {"-vcodec":"libx264", "-crf": 0, "-preset": "fast"} #define (Codec,CRF,preset) FFmpeg tweak parameters for writer

stream = cv2.VideoCapture(0) #Open live webcam video stream on first index(i.e. 0) device

writer = WriteGear(output_filename = 'Output.mp4', compression_mode = True, logging = True, **output_params) #Define writer with output filename 'Output.mp4' 

# infinite loop
while True:

    (grabbed, frame) = stream.read()
    # read frames

    # check if frame empty
    if not grabbed:
        #if True break the infinite loop
        break


    # {do something with frame here}
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    # write a modified frame to writer
        writer.write(gray) 

        # Show output window
    cv2.imshow("Output Frame", frame)

    key = cv2.waitKey(1) & 0xFF
    # check for 'q' key-press
    if key == ord("q"):
        #if 'q' key-pressed break out
        break

cv2.destroyAllWindows()
# close output window

stream.release()
# safely close video stream
writer.close()
# safely close writer

查看更多高级用法详情此处和完整文档此处


您也可以使用VidGear进行屏幕或网络摄像头捕获。 - alercelik
VidGear依赖于许多库,这真是令人沮丧。根据我在Python领域5年的经验,多个依赖项一直是个头疼的问题,因为当你将应用程序升级到新版本的库时,会出现各种冲突和错误。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接