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の学習コスト払わずに、こっちでしばらく試してみようと思います。