私的AI研究会 > GanFOMM2
同じカテゴリの静止画と動画を使って、静止画を動画のように動かす「First Order Motion Model」技術を使って静止画を動画にする
cd /anaconda_win/workspace_2 ← Windows の場合 cd ~/workspace_2 ← Linux の場合 git clone https://github.com/AliaksandrSiarohin/first-order-model
project_first-order-model ├─workspace_2 │ ├─first-order-model ← GitHub からクローンしたプロジェクトに上書きする │ │ ├─result │ │ ├─result_save │ │ └─sample │ │ ├─images │ │ └─videos │ └─mylib2 ← ローカル環境で実行するための汎用ライブラリ │ ├─mylib_test │ └─result └─workspace_py37 └─mylib ← 私的汎用ライブラリ・解凍してできる「project_first-order-model/」フォルダ内を次のフォルダの下に上書きコピーする
Windows の場合
echo $env:PYTHONPATH・パスが通っていない場合 → 環境変数を設定する
cd /anaconda_win/workspace_2/first-order-model
Linux の場合
printenv PYTHONPATH・パスが通っていない場合 → 環境変数を設定する
cd ~/workspace_2/first-order-model
(py38_learn) python demo2.py --config config/vox-256.yaml --driving_video './sample/videos/2.mp4' --source_image './sample/images/05.png' --checkpoint './sample/vox-cpk.pth.tar' --relative --adapt_scale --result_video result.gif --cpu FOMM Demo (demo2.py) Ver. 0.01: Starting application... - config : config/vox-256.yaml - checkpoint : ./sample/vox-cpk.pth.tar - source_image : ./sample/images/05.png - driving_video : ./sample/videos/2.mp4 - result_video : result.gif - relative : True - adapt_scale : True - find_best_frame : False - best_frame : None - cpu : True - audio : False 100%|████████████████████████████████████████████████████████████████████████████████| 211/211 [02:20<00:00, 1.50it/s]・GPU動作の場合(「--cpu」オプションなし)
100%|████████████████████████████████████████████████████████████████████████████████| 211/211 [00:02<00:00, 74.32it/s]
(py38_learn) python demo2.py --config config/vox-256.yaml --driving_video './sample/videos/2.mp4' --source_image './sample/images/05.png' --checkpoint './sample/vox-cpk.pth.tar' --adapt_scale --result_video result1.gif --cpu FOMM Demo (demo2.py) Ver. 0.01: Starting application... - config : config/vox-256.yaml - checkpoint : ./sample/vox-cpk.pth.tar - source_image : ./sample/images/05.png - driving_video : ./sample/videos/2.mp4 - result_video : result1.gif - relative : False - adapt_scale : True - find_best_frame : False - best_frame : None - cpu : True - audio : False 100%|████████████████████████████████████████████████████████████████████████████████| 211/211 [02:19<00:00, 1.51it/s]・GPU動作の場合(「--cpu」オプションなし)
100%|████████████████████████████████████████████████████████████████████████████████| 211/211 [00:02<00:00, 81.72it/s]
カテゴリー | --config | --checkpoint | --source_image | --driving_video | 出力例 |
顔 | config/ vox-256.yaml | ./sample/ vox-cpk.pth.tar | ./sample/images/ 05.png | ./sample/videos/ 2.mp4 | モナリザ → トランプ |
./sample/images/ pic6.png | ./sample/ videos/hinton.mp4 | 松嶋菜々子 → ヒントン教授 | |||
ファッション | config/ fashion-256.yaml | ./sample/ fashion.pth.tar | ./sample/images/ fashion003x.png | ./sample/videos/ fashion01x.mp4 | 波瑠 → モデル |
太極拳 | config/ taichi-256.yaml | ./sample/ taichi-cpk.pth.tar | ./sample/images/ taichi001x.jpg | ./sample/videos/ taichi2.mp4 | 石原さとみ → 太極拳 |
アニメーション | config/ mgif-256.yaml | ./sample/ mgif-cpk.pth.tar | ./sample/images/ anim02.png | ./sample/videos/ anim_00055x.mp4 | 馬のアニメーション |
カテゴリー | オプション | --config | --checkpoint | --source_image | --driving_video | 内容 |
顔 | -c 0 | 初期値 | 初期値 | 任意指定 | 任意指定 | 指定ソースで変換処理 |
-c 00 | 初期値 | 初期値 | 初期値 | 初期値 | モナリザ → トランプ | |
ファッション | -c 1 | 初期値 | 初期値 | 任意指定 | 任意指定 | 指定ソースで変換処理 |
-c 10 | 初期値 | 初期値 | 初期値 | 初期値 | 波瑠 → モデル | |
太極拳 | -c 2 | 初期値 | 初期値 | 任意指定 | 任意指定 | 指定ソースで変換処理 |
-c 20 | 初期値 | 初期値 | 初期値 | 初期値 | 石原さとみ → 太極拳 | |
アニメーション | -c 3 | 初期値 | 初期値 | 任意指定 | 任意指定 | 指定ソースで変換処理 |
-c 30 | 初期値 | 初期値 | 初期値 | 初期値 | 馬のアニメーション |
(py38_learn) python fomm.py -c 00 First Order Motion Model Ver. 0.01: Starting application... - Category : 00: ** Face ** - source_image : ./sample/images/05.png - driving_video : ./sample/videos/2.mp4 - result_video : ./result/face.mp4 - audio : True - cpu : True - log : 3 100%|████████████████████████████████████████████████████████████████████████████████| 211/211 [02:24<00:00, 1.46it/s] Saving... → './result/face_05_2.mp4' Saving... → './result/face_05_2_a.mp4' Finished.・GPU動作の場合
100%|████████████████████████████████████████████████████████████████████████████████| 211/211 [00:02<00:00, 81.20it/s]
コマンドオプション | 引数 | 初期値 | 意味 |
-c, --category | str | '0' | カテゴリー指定(必須) |
--config | str | 指定しなければ内部設定※ | 学習済みモデルの設定ファイル(.yaml) |
--checkpoint | str | 学習済みモデル・ファイル | |
--source_image | str | 静止画ファイルパス | |
--driving_video | str | 動画ファイルパス | |
--result_video | str | 出力保存ファイルパス | |
--relative | bool | True | use relative or absolute keypoint coordinates |
--adapt_scale | bool | True | adapt movement scale based on convex hull of keypoints |
--find_best_frame | bool | False | Generate from the frame that is the most alligned with source. (Only for faces, requires face_aligment lib |
--best_frame | int | None | Set frame to start from. |
--cpu | bool | False | cpu mode. |
--audio | bool | True | copy audio to output from the driving video |
--log | int | 3 | Log level(-1/0/1/2/3/4/5) |
コマンドオプション | -c 0 (顔) | -c 1 (ファッション) | -c 2 (太極拳) | -c 3 (アニメーション) |
--config | ./config/vox-256.yaml | ./config/fashion-256.yaml | ./config/taichi-256.yaml | ./config/mgif-256.yaml |
--checkpoint | ./sample/vox-cpk.pth.tar | ./sample/fashion.pth.tar | ./sample/taichi-cpk.pth.tar | ./sample/mgif-cpk.pth.tar |
--source_image | ダイアログによる静止画選択 | |||
--driving_video | ダイアログによる動画選択 | |||
--result_video | ./result/face.mp4 | ./result/fashion.mp4 | ./result/taich.mp4 | ./result/mgif.gif |
(py38_learn) python fomm_test.py First Order Motion Model Test Ver. 0.02: Starting application... - Category : 0: ** Face ** - source_image : ./sample/images/04.jpg - driving_video : ./sample/videos/2.mp4 - result_video : ./result/face.mp4 - audio : True - cpu : True - log : 3 100%|████████████████████████████████████████████████████████████████████████████████| 211/211 [02:17<00:00, 1.54it/s] Saving... → './result/face_04_2.mp4' Saving... → './result/face_04_2_a.mp4' Finished.・GPU動作の場合
100%|████████████████████████████████████████████████████████████████████████████████| 211/211 [00:03<00:00, 60.16it/s]
(py38_learn) python fomm_test.py -c 1 First Order Motion Model Test Ver. 0.02: Starting application... - Category : 1: ** Fashion ** - source_image : ./sample/images/fashion003x.png - driving_video : ./sample/videos/fashion01x.mp4 - result_video : ./result/fashion.mp4 - audio : True - cpu : True - log : 3 100%|████████████████████████████████████████████████████████████████████████████████| 395/395 [04:21<00:00, 1.51it/s] Saving... → './result/fashion_fashion003x_fashion01x.mp4' Saving... → './result/fashion_fashion003x_fashion01x_a.mp4' Finished.・GPU動作の場合
100%|████████████████████████████████████████████████████████████████████████████████| 395/395 [00:04<00:00, 79.97it/s]
(py38_learn) python fomm_test.py -c 2 First Order Motion Model Test Ver. 0.02: Starting application... - Category : 2: ** Tai chi ** - source_image : ./sample/images/fashion004x.png - driving_video : ./sample/videos/taichi2.mp4 - result_video : ./result/taich.mp4 - audio : True - cpu : True - log : 3 100%|████████████████████████████████████████████████████████████████████████████████| 365/365 [04:04<00:00, 1.49it/s] Saving... → './result/taich_taichi001x_taichi2.mp4' Saving... → './result/taich_taichi001x_taichi2_a.mp4' Finished.・GPU動作の場合
100%|████████████████████████████████████████████████████████████████████████████████| 365/365 [00:04<00:00, 76.69it/s]
(py38_learn) python fomm_test.py -c 3 First Order Motion Model Test Ver. 0.02: Starting application... - Category : 3: ** Moving GIF ** - source_image : ./sample/images/anim02.png - driving_video : ./sample/videos/anim_00055x.mp4 - result_video : ./result/mgif.gif - audio : True - cpu : True - log : 3 100%|██████████████████████████████████████████████████████████████████████████████████| 30/30 [00:20<00:00, 1.49it/s] Saving... → './result/mgif_anim02_anim_00055x.gif' Saving... → './result/mgif_anim02_anim_00055x_a.gif' Finished.・GPU動作の場合
100%|██████████████████████████████████████████████████████████████████████████████████| 30/30 [00:00<00:00, 66.94it/s]
機能 | プログラム | GPU | CPU | ||||
RTX 4070Ti | RTX 4060 | GTX 1050 | i9-13900 | i7-14700 | i7-1260P | ||
トランプのように話すモナリザ | demo2.py | 2秒 | 4秒 | 18秒 | 2分20秒 | 3分4秒 | 4分39秒 |
トランプ似のモナリザ | 2秒 | 5秒 | 18秒 | 2分19秒 | 3分5秒 | 4分35秒 | |
トランプのように話すモナリザ | fomm.py | 2秒 | 4秒 | 17秒 | 2分24秒 | 3分5秒 | 4分40秒 |
トランプのように話す北川景子 | fomm_test.py | 3秒 | 4秒 | 18秒 | 2分17秒 | 2分59秒 | 4分14秒 |
「ファッション」カテゴリー | fomm_test.py | 4秒 | 8秒 | 35秒 | 4分21秒 | 5分36秒 | 7分58秒 |
「アニメーション」カテゴリー | fomm_test.py | 0秒 | 0秒 | 2秒 | 20秒 | 25秒 | 36秒 |
「太極拳」カテゴリー | fomm_test.py | 4秒 | 8秒 | 32秒 | 4分4秒秒 | 5分10秒 | 7分22秒 |
import imageio.v2 as imageio # 2024/06/14 warning error 対応 import warnings warnings.simplefilter('ignore', UserWarning)
display_info(opt) # 2024/06/17 基本情報の表示 # ファイルの存在確認 if not os.path.isfile(opt.source_image): print(RED + f"File not found !! '{opt.source_image}' " + NOCOLOR) quit() if not os.path.isfile(opt.driving_video): print(RED + f"File not found !! '{opt.driving_video}' " + NOCOLOR) quit()
# 出力が GIFファイルの時はループする name, ext = splitext(opt.result_video) if ext == '.gif': imageio.mimsave(opt.result_video, [img_as_ubyte(frame) for frame in predictions], fps = fps, loop = 0) else: imageio.mimsave(opt.result_video, [img_as_ubyte(frame) for frame in predictions], fps = fps) if opt.audio: try: # 一時ファイル・エラー対応 2024/06/18 with tempfile.TemporaryDirectory() as str_temp_dir: tmpfile = f"{str_temp_dir}/temp.mp4" ffmpeg.output(ffmpeg.input(opt.result_video).video, ffmpeg.input(opt.driving_video).audio, tmpfile, c='copy').run(quiet=True) with open(opt.result_video, 'wb') as result: with open(tmpfile, 'rb') as output: copyfileobj(output, result) except ffmpeg.Error: print(RED + f"Failed to copy audio: the driving video may have no audio track or the audio format is invalid." + NOCOLOR)
Traceback (most recent call last): File "fomm.py", line 206, in <module> fomm_process(opt) File "fomm.py", line 132, in fomm_process predictions = make_animation(source_image, driving_video, generator, kp_detector, relative = opt.relative, cpu = opt.cpu) File "H:\anaconda_win\workspace_2\first-order-model\demo2.py", line 141, in make_animation predictions.append(np.transpose(out['prediction'].data.cpu().numpy(), [0, 2, 3, 1])[0]) RuntimeError: CUDA error: an illegal memory access was encountered CUDA kernel errors might be asynchronously reported at some other API call, so the stacktrace below might be incorrect. For debugging consider passing CUDA_LAUNCH_BLOCKING=1. Compile with `TORCH_USE_CUDA_DSA` to enable device-side assertions.
ALSA lib conf.c:4028:(snd_config_hooks_call) Cannot open shared library libasound_module_conf_pulse.so (/home/mizutu/anaconda3/envs/py38_learn/lib/alsa-lib/libasound_module_conf_pulse.so: cannot open shared object file: No such file or directory) : ALSA lib dlmisc.c:339:(snd_dlobj_cache_get0) Cannot open shared library libasound_module_rate_samplerate.so (/home/mizutu/anaconda3/envs/py38_learn/lib/alsa-lib/libasound_module_rate_samplerate.so: cannot open shared object file: No such file or directory) : ALSA lib conf.c:4028:(snd_config_hooks_call) Cannot open shared library libasound_module_conf_pulse.so (/home/mizutu/anaconda3/envs/py38_learn/lib/alsa-lib/libasound_module_conf_pulse.so: 共有オブジェクトファイルを開けません: そのようなファイルやディレクトリはありません) : ALSA lib dlmisc.c:339:(snd_dlobj_cache_get0) Cannot open shared library libasound_module_rate_samplerate.so (/home/mizutu/anaconda3/envs/py38_learn/lib/alsa-lib/libasound_module_rate_samplerate.so: 共有オブジェクトファイルを開けません: そのようなファイルやディレクトリはありません) :
pulseaudio --kill pulseaudio --start・次のようなシンボリック・リンクを貼ることで「ファイルが見つからない」エラーは抑制できる
cd /home/mizutu/anaconda3/envs/py38_learn/lib ln -s /usr/lib/x86_64-linux-gnu/alsa-lib alsa-lib・動作に支障はないのでそのほかのエラー出力については保留(調査中)