1.はじめに
今回ご紹介するのは、似通った2つの画像をモーフィングするような動画を作成するFILM(Frame Interpolation for Large Motion)という技術です。
2.FILMとは?
FILMとは、Frame Interpolation for Large Motion の略で、比較的大きな変化のある2つの画像の中間画像を推定する技術です。
下記は、FILMのフローです。大きく分けると、特徴抽出(Feature Extraction)、フロー予測(Flow Estimation)、融合(Fusion)の3つで構成されています。
特徴抽出では2つの画像をスケールを縮小しながら、それぞれ畳み込みで特徴量を抽出し、同じサイズの情報をまとめます。フロー予測ではサイズ毎に特徴量の差を元に中間画像の特徴量を予測します。そして、融合ではこれらの情報をU -Netのようなデコーダへ送り中間画像を出力します。
3.コード
コードはGoogle Colabで動かす形にしてGithubに上げてありますので、それに沿って説明して行きます。自分で動かしてみたい方は、この「リンク」をクリックし表示されたノートブックの先頭にある「Colab on Web」ボタンをクリックすると動かせます。
まず、セットアップを行います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#@title セットアップ # githubからコード取得 & ライブラリ・インストール ! git clone https://github.com/cedro3/frame-interpolation.git %cd frame-interpolation ! pip install -r requirements.txt # 学習済みパラメータ・ダウンロード ! pip install --upgrade gdown import gdown gdown.download('https://drive.google.com/uc?id=1rEABCoyQFkmHGieKDhHXW2ZYJi12lofI', 'pretrained_models.zip', quiet=False) ! unzip pretrained_models.zip # ライブラリ・インポート from function import * |
それでは、補間動画を作成してみましょう。サンプル・フォルダは3つ(photo_1〜photo_3)あり、それぞれ開始フレーム(frame1.jpg)と終了フレーム(frame2.jpg)が含まれています。
自分の用意した画像でやる場合は、開始フレームと終了フレームを含む新たなフォルダを追加して下さい。なお、このとき2つのフレームの縦横サイズは同じで偶数にして下さい。
select_folder でフォルダ、times_to_interpolate で補間回数(生成する画像数は補間回数の2の階乗−1)を指定します。ここでは、select_folder は ‘photo_2’、times_to_interpolate は 6 を設定し実行します。
1 2 3 4 5 6 7 8 9 |
#@title 補間動画の作成 select_folder = 'photo_2'#@param {type:"string"} times_to_interpolate = 6#@param {type:"integer"} ! python -m eval.interpolator_cli \ --pattern $select_folder\ --model_path pretrained_models/film_net/Style/saved_model \ --times_to_interpolate $times_to_interpolate \ --output_video |
1 2 |
#@title 動画の再生 display_mp4(select_folder+'/interpolated.mp4') |
せっかくですので、補間前・後の画像を付加した動画も作ってみましょう。補間前後の画像を上に付加したものと横に付加したものの2種類の動画を作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
#@title 前後付き動画に編集 import cv2 import glob reset_folder(select_folder+'/images_t') reset_folder(select_folder+'/images_y') files = sorted(glob.glob(select_folder+'/interpolated_frames/*.png')) img_1 = cv2.imread(select_folder+'/frame1.jpg') img_2 = cv2.imread(select_folder+'/frame2.jpg') img_1 = cv2.resize(img_1, dsize=None, fx=0.5, fy=0.5) img_2 = cv2.resize(img_2, dsize=None, fx=0.5, fy=0.5) for file in files: img = cv2.imread(file) # 縦長 up = cv2.hconcat([img_1, img_2]) image1 = cv2.vconcat([up, img]) name = os.path.basename(file) cv2.imwrite(select_folder+'/images_t/'+name, image1) # 横長 side = cv2.vconcat([img_1, img_2]) image2 = cv2.hconcat([side, img]) name = os.path.basename(file) cv2.imwrite(select_folder+'/images_y/'+name, image2) !ffmpeg -y -r 30 -i $select_folder/images_t/frame_%03d.png -vcodec libx264 -pix_fmt yuv420p -loglevel error output1.mp4 !ffmpeg -y -r 30 -i $select_folder/images_y/frame_%03d.png -vcodec libx264 -pix_fmt yuv420p -loglevel error output2.mp4 |
補間前・後の画像を横に付加した動画を再生します。これは、output2.mp4 に保存されています。
1 2 |
#@title 横に付加した動画の再生 display_mp4('output2.mp4') |
フォルダは photo_3 を使って、補間前・後の画像を上に付加した動画を再生します。これは、output1.mp4 に保存されています。
1 2 |
#@title 上に付加した動画の再生 display_mp4('output1.mp4') |
では、また。
(オリジナルgithub)https://github.com/google-research/frame-interpolation