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

问题描述

我有一个文件夹,里面有 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 Media Player 中打开生成的视频。如果我在 VLC 媒体播放器中打开视频,我的播放会失真,不仅会跳过最后一帧。 (我有从 0 到 224 的数字,所以每个错误的帧都会被注意到。)所以,如果您使用 VLC 媒体播放器,那么您的问题很可能就是 this StackOverflow Q&A 中讨论的问题。

imageio GitHub 问题跟踪器上,还有 this issue,链接到 this other StackOverflow 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
----------------------------------------