首页 > 解决方案 > 在 Python 中将动画 GIF 转换为 4D 数组

问题描述

我想将 .gif 文件转换为 4D 数组/RGB 值的 3D 数组。

我试过 PIL,但这似乎只能让我将 gif 作为灰度图像读取。 ndimagefrom numpy 没有这个问题,但它只会导致 gif 的第一帧。

为了测试目的,我尝试转换的 .gif 是

在此处输入图像描述(非常小,用 GIMP 制造)

它只是在第一帧的顶部以红色增加,在第一帧的侧面以绿色增加,随着帧的前进,在左上角以蓝色增加。

PIL给了我

[[[ 0  3  5  6  8]
  [ 7 12 12 12 12]
  [ 9 12 12 12 12]
  [10 12 12 12 12]
  [11 12 12 12 12]]
 [[ 1 12 12 12 12]
  [12 12 12 12 12]
  [12 12 12 12 12]
  [12 12 12 12 12]
  [12 12 12 12 12]]
 [[ 2 12 12 12 12]
  [12 12 12 12 12]
  [12 12 12 12 12]
  [12 12 12 12 12]
  [12 12 12 12 12]]
 [[ 4 12 12 12 12]
  [12 12 12 12 12]
  [12 12 12 12 12]
  [12 12 12 12 12]
  [12 12 12 12 12]]]

而 numpy 给了我

[[[  0   0   0]
  [ 20   0   0]
  [ 40   0   0]
  [ 60   0   0]
  [ 80   0   0]]

 [[  0  20   0]
  [255 255 255]
  [255 255 255]
  [255 255 255]
  [255 255 255]]

 [[  0  40   0]
  [255 255 255]
  [255 255 255]
  [255 255 255]
  [255 255 255]]

 [[  0  60   0]
  [255 255 255]
  [255 255 255]
  [255 255 255]
  [255 255 255]]

 [[  0  80   0]
  [255 255 255]
  [255 255 255]
  [255 255 255]
  [255 255 255]]]

这两者都不是我想要的。

标签: pythonpython-3.xgifanimated-gif

解决方案


import numpy as np
from PIL import Image, ImageSequence

img = Image.open('test.gif')
frames = np.array([np.array(frame.copy().convert('RGB').getdata(),dtype=np.uint8).reshape(frame.size[1],frame.size[0],3) for frame in ImageSequence.Iterator(img)])

输出:

(frame_num * frame_width * frame_height * 3(RGB))

    [array([[[  0,   0,   0],
             [ 20,   0,   0],
             [ 40,   0,   0],
             [ 60,   0,   0],
             [ 80,   0,   0]],

            [[  0,  20,   0],
             [255, 255, 255],
             [255, 255, 255],
             [255, 255, 255],
             [255, 255, 255]],

            [[  0,  40,   0],
             [255, 255, 255],
             [255, 255, 255],
             [255, 255, 255],
             [255, 255, 255]],

            [[  0,  60,   0],
             [255, 255, 255],
             [255, 255, 255],
             [255, 255, 255],
             [255, 255, 255]],

            [[  0,  80,   0],
             [255, 255, 255],
             [255, 255, 255],
             [255, 255, 255],
             [255, 255, 255]]], dtype=uint8), 
     array([[[  0,   0,  20],
             [255, 255, 255],
             [255, 255, 255],
             [255, 255, 255],
             [255, 255, 255]],

            [[255, 255, 255],
             [255, 255, 255],
             [255, 255, 255],
             [255, 255, 255],
             [255, 255, 255]],

            [[255, 255, 255],
             [255, 255, 255],
             [255, 255, 255],
             [255, 255, 255],
             [255, 255, 255]],

            [[255, 255, 255],
             [255, 255, 255],
             [255, 255, 255],
             [255, 255, 255],
             [255, 255, 255]],

            [[255, 255, 255],
             [255, 255, 255],
             [255, 255, 255],
             [255, 255, 255],
             [255, 255, 255]]], dtype=uint8), 
     array([[[  0,   0,  40],
             [255, 255, 255],
             [255, 255, 255],
             [255, 255, 255],
             [255, 255, 255]],

            [[255, 255, 255],
             [255, 255, 255],
             [255, 255, 255],
             [255, 255, 255],
             [255, 255, 255]],

            [[255, 255, 255],
             [255, 255, 255],
             [255, 255, 255],
             [255, 255, 255],
             [255, 255, 255]],

            [[255, 255, 255],
             [255, 255, 255],
             [255, 255, 255],
             [255, 255, 255],
             [255, 255, 255]],

            [[255, 255, 255],
             [255, 255, 255],
             [255, 255, 255],
             [255, 255, 255],
             [255, 255, 255]]], dtype=uint8), 
     array([[[  0,   0,  60],
             [255, 255, 255],
             [255, 255, 255],
             [255, 255, 255],
             [255, 255, 255]],

            [[255, 255, 255],
             [255, 255, 255],
             [255, 255, 255],
             [255, 255, 255],
             [255, 255, 255]],

            [[255, 255, 255],
             [255, 255, 255],
             [255, 255, 255],
             [255, 255, 255],
             [255, 255, 255]],

            [[255, 255, 255],
             [255, 255, 255],
             [255, 255, 255],
             [255, 255, 255],
             [255, 255, 255]],

            [[255, 255, 255],
             [255, 255, 255],
             [255, 255, 255],
             [255, 255, 255],
             [255, 255, 255]]], dtype=uint8)]

推荐阅读