1.はじめに
今回ご紹介するのは、いくつかのアニメを元にポーズを指定することによってダンスビデオを作成する CoNR(Collaborative Neural Rendering)という技術です。
*この論文は、2022.6に提出されました。
2.CoNRとは?
下記がCoNRの概要図です。狙いとするポーズ(Itar)をコンパクトなランドマーク数値で表されるUDP表現(Ptar)に変換します。
一方、 いくつかのアニメ(Sref)をそれぞれU-Net形式のネットワークに入力してEncoderでエンコードし、UPD表現(Ptar)と共にDecoderでデコードします。このとき、複数のDecoderのD1〜D3の重みを共有することによって、狙いとするポーズのアニメを作成します。
3.コード
コードはGoogle Colabで動かす形にしてGithubに上げてありますので、それに沿って説明して行きます。自分で動かしてみたい方は、この「リンク」をクリックし表示されたノートブックの先頭にある「Colab on Web」ボタンをクリックすると動かせます。
まず、セットアップを行います。
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 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
#@title #**セットアップ** # githubからコードをコピー !git clone https://github.com/megvii-research/CoNR.git %cd CoNR !pip install -r requirements.txt # 学習済みパラメータのダウンロード !mkdir weights %cd weights !gdown https://drive.google.com/uc?id=1M1LEpx70tJ72AIV2TQKr6NE_7mJ7tLYx !gdown https://drive.google.com/uc?id=1YvZy3NHkJ6gC3pq_j8agcbEJymHCwJy0 !gdown https://drive.google.com/uc?id=1AOWZxBvTo9nUf2_9Y7Xe27ZFQuPrnx9i !gdown https://drive.google.com/uc?id=19jM1-GcqgGoE1bjmQycQw_vqD9C5e-Jm # リセット・フォルダ関数 import os import shutil def reset_folder(path): if os.path.isdir(path): shutil.rmtree(path) os.makedirs(path,exist_ok=True) # フォルダ・コピー関数 import os import glob def copy_dir(source_folder, dst_folder): files = sorted(glob.glob(source_folder+'/*')) for file in files: shutil.copy(file, dst_folder+'/'+os.path.basename(file)) # サンプルデータのダウンロード %cd /content/CoNR reset_folder('data') ! gdown https://drive.google.com/uc?id=11HMSaEkN__QiAZSnCuaM6GI143xo62KO ! unzip short_hair.zip ! mv short_hair/ data/ ! gdown https://drive.google.com/uc?id=1WNnGVuU0ZLyEn04HzRKzITXqib1wwM4Q ! unzip double_ponytail.zip ! mv double_ponytail/ data/ ! gdown https://drive.google.com/uc?id=1r-3hUlENSWj81ve2IUPkRKNB81o9WrwT ! unzip short_hair_images.zip ! mv short_hair_images/ data/ ! gdown https://drive.google.com/uc?id=1XMrJf9Lk_dWgXyTJhbEK2LZIXL9G3MWc ! unzip double_ponytail_images.zip ! mv double_ponytail_images/ data/ |
いくつかのアニメをまとめたキャラクターシートと狙いのポーズをまとめたUDPデータをセットします。style で ‘double_ponytail’ あるいは ‘short_hair’ を選択するとサンプルデータを使用し、‘self_defined’ を選択すると自分のデータを使用できます。
’self_defined’ を選択して実行した場合は、その後にcharacter_sheetフォルダとposesフォルダに必要なデータをアップロードして下さい。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#@title #**データ設定** #@markdown styleでself_definedを選択して実行した場合は、別途posesフォルダとcharacter_sheetフォルダに必要なデータをアップロードして下さい。 import shutil reset_folder('poses') reset_folder('character_sheet') style = 'double_ponytail' #@param ['double_ponytail', 'short_hair', 'self_defined'] if style == 'short_hair': copy_dir('data/short_hair', 'poses') copy_dir('data/short_hair_images', 'character_sheet') elif style == 'double_ponytail': copy_dir('data/double_ponytail', 'poses') copy_dir('data/double_ponytail_images', 'character_sheet') |
キャラクターシートの内容を表示させます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#@title #**キャラクターシートの表示** import cv2 import numpy as np import os path ='/content/CoNR/character_sheet/' files= os.listdir(path) imgs = [] for file in files: if not os.path.isdir(file): img = cv2.imread(path+"/"+file, cv2.IMREAD_UNCHANGED); imgs.append(img) print("Num of character sheets:", len(imgs)) imgs = np.concatenate(imgs, 1) cv2.imwrite('character_sheet.png', imgs) from IPython.display import Image Image(filename='character_sheet.png') |
それでは、アニメーションを作成してみましょう。作成したアニメーションデータは順次 resultsフォルダ に保存されます。
なお、サンプルデータ全体のアニメーション化(49秒)には1時間弱かかります。途中で再度実行ボタンを押して、ストップさせることも出来ます。
1 2 3 4 5 6 7 8 9 10 11 12 |
#@title #**アニメーションの作成** #@markdown サンプルデータのアニメーション化(49秒)には1時間弱かかります。途中で再度実行ボタンを押して、ストップさせることも出来ます。 reset_folder('results') !python3 -m torch.distributed.launch \ --nproc_per_node=1 train.py --mode=test \ --world_size=1 --dataloaders=2 \ --test_input_poses_images=./poses/ \ --test_input_person_images=./character_sheet/ \ --test_output_dir=./results/ \ --test_checkpoint_dir=./weights/ |
resultsフォルダに出力されたアニメーションデータ(*.png)を元に動画の作成と再生を行います。これは、冒頭の13秒です。
1 2 3 4 5 6 7 8 9 10 11 12 |
#@title #**動画の作成と再生** !ffmpeg -y -r 30 -y -i ./results/%d.png -r 30 -vcodec libx264 -pix_fmt yuv420p -loglevel error output.mp4 -r 30 from IPython.display import HTML from base64 import b64encode def show_video(video_path, video_width = 600): video_file = open(video_path, "r+b").read() video_url = f"data:video/mp4;base64,{b64encode(video_file).decode()}" return HTML(f"""<video width={video_width} controls><source src="{video_url}"></video>""") show_video('output.mp4') |
たった4枚のアニメからダンスビデオが作成できるのは面白いですね!
では、また。
(オリジナルgithub)https://github.com/megvii-research/CoNR
コメントを残す