首页 > 解决方案 > Python:在提取帧时检测一个罕见的奇怪 GIF

问题描述

我从网上收集了一个大规模的 gif 数据集(超过 100k),当我尝试用 python 提取 GIF 的帧时,我遇到了一些罕见的奇怪的 GIF。三个常用的包(moviepy, PIL, imageio)为这种罕见的奇怪 gif 提供了完全不同的结果。

  1. moviepy>=1.0.3将永远在第二帧循环阻塞VideoFileClip.iter_frames(),并且代码不会抛出异常
from moviepy.video.io.VideoFileClip import VideoFileClip

video = VideoFileClip(path)
frame_iterator = video.iter_frames()
  1. PIL>=7.1.2将输出与第一帧相同的多个帧。
from PIL import Image, ImageSequence
from PIL import ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES = True

video = Image.open(path)
frame_iterator = ImageSequence.Iterator(video)
  1. imageio>=2.6.1可以正确提取帧,而输出帧很奇怪
import imageio

frame_iterator = imageio.get_reader(path)

frame_iterator然后你可以从上面这些包提供的帧中转储:

def dump_video_frames(video_frames):
    root = 'data/frames'
    if os.path.exists(root):
        shutil.rmtree(root)
    os.makedirs(root)

    for i, frame in enumerate(video_frames):
        frame.save(os.path.join(root, '%d.jpg' % i))

frames = []
for frame in frame_iterator:
    if isinstance(frame, np.ndarray):
        frame = Image.fromarray(np.uint8(frame))
    frames.append(frame.convert('RGB'))

dump_video_frames(frames)

这是一个例子:

原始GIF:

在此处输入图像描述

的输出PIL

在此处输入图像描述

的输出imageio

在此处输入图像描述

你可以看到PIL只有第一帧没有任何黑色区域,这与imageio.

所以我的问题是如何在 python 中检测到这样一个奇怪的 gif?由于我moviepy首先使用它在其他 gif 中的良好性能,因此我需要在代码用于提取其帧之前检测这种类型的 GIF,moviepy以避免VideoFileClip.iter_frames()不会抛出任何异常的无限循环。我无法从 Google 获得有关这种罕见 gif 的任何信息。

我将在下面提供另外 2 个示例 GIF:

在此处输入图像描述

在此处输入图像描述

标签: pythonpython-imaging-librarygifmoviepypython-imageio

解决方案


推荐阅读