pythonでgifの可視化/読み込み/書き込み + 高速化【OpenCV】


完全にメモです。。
職業柄よく使う気がして(?)

読み込み

scikit-video バージョン

  • 安全策ならこう
from skvideo.io import vread
gif = vread("sample.gif")
# print(gif.shape) # => (例): (21, 600, 600, 3)
  • でもこれは遅いので↓のほうがいいと思う

OpenCV バージョン

  • 速い
import cv2
import numpy as np

# faster than `vread` in `skvideo.io`
def vread(path, T=30):
    cap = cv2.VideoCapture(path)
    gif = [cap.read()[1][...,::-1] for i in range(T)]
    gif = np.array(gif)
    cap.release()
    return gif

gif = vread("sample.gif", T=21)
# print(gif.shape) # => (例): (21, 600, 600, 3)
  • フレーム数は与えてあげないといけないのだけが難点。

  • フレーム数与えない(リスト内容表記じゃない)普通の書き方の例↓

import cv2

filepath = "data/raw/GH010005-0.mp4"
cap = cv2.VideoCapture(filepath)

while(cap.isOpened()):
    ret, frame = cap.read()
    if ret:
        cv2.imshow("Frame", frame)
        cv2.waitKey(1)
    else:
        cap.release()
cv2.destroyAllWindows()

表示

ウィンドウ表示

import cv2
cv2.namedWindow("frame", cv2.WINDOW_NORMAL)

for t in range(len(gif)):
    cv2.imshow("frame", gif[t])
    cv2.waitKey(50) # 少しだけ待たないと表示されない

cv2.destroyAllWindows()

jupyter上での表示

import matplotlib.pyplot as plt
%matplotlib inline

plt.figure(figsize=(21,9))
for t in range(21):
    plt.subplot(3,7,t+1)
    plt.imshow(gif[t])
plt.show()

書き込み

import moviepy.editor as mpy
def npy_to_gif(npy, filename):
    clip = mpy.ImageSequenceClip(list(npy), fps=10)
    clip.write_gif(filename)

(読み込み時間の比較)

  • OpenCVの勝ち!

以上!

(gifはここから拝借しました https://miro.medium.com/max/1200/1*LnQ5sRu-tJmlvRWmDsdSvw.gif)