見出し画像

Generative Art with Python 〜静止画を結合して動画を生成する〜

TL;DR

Generative Artをやりたいのだが、本業ではProcessingやWebGLを一切触らないため、完全なる趣味になってしまう。

「せっかくのCreative Coding、もう少し仕事に繋げられないものか……?」

──ということで、Pythonでごりごりジェネってみたい今日この頃。

今回のMotivation

静止画はnumpy + matplotlib.pyplotで量産可能だが、動画を生成するのは難儀しそうである。(以前にpyplotでアニメーション表示しようとして苦労した。)

そこで「OpenCVを使ったほうが楽ではないか?」という仮説の元、まずは静止画から動画を生成する方法を試してみた。

How To Learn

0. pip install opencv
1. ググる
2. Jupyter notebookで動かしてみる
3. エラーが出たのでググる
4. Jupyter notebookで動かしてみる
5. エラーが出たのでググる
6. Jupyterで(以下繰り返し)

……とにかく手を動かす、というやつです。

コピペ用/とりあえず動くコード

 元はこちらのページにあるコードを修正しています。

ディレクトリ ~/Picture/images/tmp に、 frame_0001.png のようなファイル名の画像が連番で多数ある、という状態を想定。


[バージョン:Python 3.7.3, OpenCV 4.1.0.25]

import glob
import os

import cv2

output_dirpath = "~/Picture/images/tmp"

# VideoCapture を作成する。
img_path = os.path.join(output_dirpath, 'frame_%04d.png')  # 画像ファイルのパス
cap = cv2.VideoCapture(img_path)

# 画像の大きさを取得
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

# フレームレートを設定
fps = 60 
print('width: {}, height: {}, fps: {}'.format(width, height, fps))

# VideoWriter を作成する。
fourcc = cv2.VideoWriter_fourcc(*'X264')
writer = cv2.VideoWriter('output.mp4', fourcc, fps, (width, height))

while True:
   # 1フレームずつ取得する。
   ret, frame = cap.read()
   if not ret:
       break  # 映像取得に失敗
   
   writer.write(frame)  # フレームを書き込む。

writer.release()
cap.release()

元コードからの修正箇所

- output_dirpath が未定義だったため記述追加
- Video Codecを DIVXからX264に変更
- fps; フレームレートを 15 -->60に変更

補足

cv2.VideoWriter_fourcc に渡す文字列で、動画形式を指定するようです。公式リファレンスはこちら↓

ハマりポイント

fourccのVideo Codec指定で少々ハマりました。メモ。

- DIVX指定→生成されたファイル(.avi)を再生できず
- four cc のサイトからコーデックを探して幾つか試すものの、変換エラーとなる
- MJPG指定→生成されたファイル(.avi)は再生できたがTwitterに投稿できず
- X264指定→生成されたファイル(.mp4)は再生可能、Twitter投稿も可能

で、Twitterに投稿できたのがこちら↓↓

これでGenerative Artを描く準備ができました。筆者はPythonのnumpyやmatplotlibは普通に使えるので、WebGLやProcessingの学習コスト払わずに、こっちでしばらく試してみようと思います。


面白かった、ためになったと感じた方にサポートいただけると励みになります。いつか展示会やイベントをやるための積立金として、あるいは飢死直前金欠時のライフラインとして使わせていただきます。