为什么在将图像转换为视频时总是排除最后一帧?

Why is the last frame always excluded, when converting images into a video?

我有一个包含 225 张地图图片的文件夹。所以,我使用 imageio 将它编译成一个 mp4 文件。不管是编10张图,150张,还是全部225张,视频里总是没有最后一张图。

import os
from natsort import humansorted
import imageio

os.chdir(r'folder/path/')
filenames = humansorted((fn for fn in os.listdir('.') if fn.endswith('.png')))
with imageio.get_writer('earthquake_video.mp4', mode='I', fps=2) as writer:
    for filename in filenames:
        image = imageio.imread(filename)
        writer.append_data(image)
    writer.close()

对我来说,您的代码适用于 10、150 甚至 225 张图像——只要我在 Windows 媒体播放器中打开生成的视频。如果我在 VLC 媒体播放器中打开视频,播放会失真,不仅会跳过最后一帧。 (我的数字从 0 到 224,所以每个错误的帧都会被注意到。)因此,如果您使用 VLC 媒体播放器,您的问题很可能是 this Whosebug Q&A.

中讨论的问题

imageio GitHub 问题跟踪器上,还有 this issue, linking to this other Whosebug question,这似乎与您遇到的问题相同。但是,我仍然认为这是 VLC 媒体播放器的上述问题。

不幸的是,我无法从使用 imageio 中的 output_params 的第一个链接问答中获得解决方法,即设置 -framerate-r。因此,我的解决方法是设置所需的 fps(此处:2)和实际播放的 fps(在 VLC 媒体播放器中),例如30,然后根据需要添加尽可能多的相同帧来伪造所需的 fps,即此处 30 // 2 = 15

这是一些代码:

import os
import imageio

os.chdir(r'folder/path')
filenames = [fn for fn in os.listdir('.') if fn.endswith('.png')]
fps = 2             # Desired, "real" frames per second
fps_vlc = 30        # Frames per second needed for proper playback in VLC
with imageio.get_writer('earthquake_video.mp4', fps=fps_vlc) as writer:
    for filename in filenames:
        image = imageio.imread(filename)
        for i in range(fps_vlc // fps):
            writer.append_data(image)
    writer.close()

生成的视频“看起来”和以前一样(在 Windows 媒体播放器中),但现在,它也可以在 VLC 媒体播放器中正常播放。

即使这不是您的实际问题,我想这些信息也会帮助其他人解决您的问题,但实际上遇到了 VLC 媒体播放器的所述问题。

----------------------------------------
System information
----------------------------------------
Platform:      Windows-10-10.0.16299-SP0
Python:        3.9.1
PyCharm:       2021.1.1
imageio:       2.9.0
----------------------------------------