1.はじめに
今回は、実写をアニメ画に変換できる White box Cartoonization を使って、実写動画をアニメ動画に変換してみたいと思います。
2.White box Cartoonizationとは?
White box Cartoonizations は、GANのフレームワークを使って実写をアニメ画像に変換するGeneratorを作る技術です。以下に、アーキテクチャーを示します。

Generator が静止画(Input)からアニメ画(Output)を生成した後に、Structure表現に関する損失、Texture表現に関する損失、Surface表現に関する損失を抽出します。生成した画像とこれら3つの損失を分類器へ入力し、損失の合計を小さくするように学習を行います。3つの表現について、詳しく見てみましょう。

1つ目の Surface 表現は、Guided filter を使ってエッジ情報を残しつつ平滑化処理を行い抽出します。これによって、アニメののっぺりとした平滑面を表現しています。
2つ目の Structure 表現は、superpixel アルゴリズムを使って距離・色が近い画素をひとまとめにし、Selective Search を使って領域ごとの類似性に基づきグルーピングしています。
3つ目の Texture 表現は、Random color shift アルゴリズムを使ってRGB画像から変換したグレースケール画像に対してランダムな割合でRGB値を加えています。これによって、色や輝度の情報をあえて落としています。
それでは、具体的にやってみましょう。
3.コード
コードはGoogle Colabで動かす形にしてGithubに上げてありますので、それに沿って説明して行きます。自分で動かしてみたい方は、この「リンク」をクリックし表示されたノートブックの先頭にある「Colab on Web」ボタンをクリックすると動かせます。
まず、セットアップを行います。
1 2 3 |
%tensorflow_version 1.x !git clone https://github.com/cedro3/White-box-Cartoonization.git %cd White-box-Cartoonization/test_code/ |
それでは、サンプル動画を確認してみましょう。
1 2 3 4 5 6 7 8 9 10 |
# mp4動画の再生 from IPython.display import HTML from base64 import b64encode mp4 = open('./test_video/sakura.mp4', 'rb').read() data_url = 'data:video/mp4;base64,' + b64encode(mp4).decode() HTML(f""" <video width="80%" height="80%" controls> <source src="{data_url}" type="video/mp4"> </video>""") |
満開の桜の中で和服の女性が歩いてゆく動画です。
最初に、cv2を使って元動画を静止画にバラし test_imagesフォルダーに保存します。既に test_images フォルダーがある場合は、削除してから実行します。
ご自分の動画をアニメ画に変換したい場合は、# ビデオの指定のところを変更して下さい。
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 31 32 33 34 35 |
import os import shutil import cv2 # 既に test_images フォルダーがあれば削除し、test_images フォルダーを作る if os.path.isdir('test_images'): shutil.rmtree('test_images') os.makedirs('test_images', exist_ok=True) def video_2_images(video_file= './test_video/sakura.mp4', # ビデオの指定 image_dir='./test_images/', image_file='%s.jpg'): # Initial setting i = 0 interval = 1 length = 3000 # 最大フレーム数 cap = cv2.VideoCapture(video_file) while(cap.isOpened()): flag, frame = cap.read() if flag == False: break if i == length*interval: break if i % interval == 0: cv2.imwrite(image_dir+image_file % str(int(i/interval)).zfill(6), frame) i += 1 cap.release() def main(): video_2_images() if __name__ == '__main__': main() |
次に、バラした静止画をアニメ画に変換し、cartoonized_images フォルダーに保存します。既に cartoonized_images フォルダーがある場合は、削除してから実行します。
1 2 3 4 5 6 |
# 既に cartoonized_imagesフォルダーがあれば削除 if os.path.isdir('cartoonized_images'): shutil.rmtree('cartoonized_images') # test_images フォルダー内にある静止画をアニメ画に変換し、cartoonized_images フォルダーに保存する !python cartoonize.py |
最後に、ffmpeg を使ってcartoonized_images フォルダーに保存されているアニメ画からmp4動画(output.mp4)を作成します。既に output.mp4 ファイルがある場合は、削除してから実行します。
1 2 3 4 5 6 |
# 既に output.mp4 があれば削除する if os.path.exists('./output.mp4'): os.remove('./output.mp4') # アニメ画をmp4動画(output.mp4)に変換する !ffmpeg -r 30 -i cartoonized_images/%06d.jpg -vcodec libx264 -pix_fmt yuv420p output.mp4 |
1 2 3 4 5 6 7 8 9 10 |
# mp4動画の再生 from IPython.display import HTML from base64 import b64encode mp4 = open('./output.mp4', 'rb').read() data_url = 'data:video/mp4;base64,' + b64encode(mp4).decode() HTML(f""" <video width="80%" height="80%" controls> <source src="{data_url}" type="video/mp4"> </video>""") |
アニメ動画の完成です!
では、また。
オリジナルgithub : https://github.com/SystemErrorWang/White-box-Cartoonization
(Twitterへの投稿)
コメントを残す