見出し画像

WSL2でAniDocを試してみる

「アニメーション線画の自動着色を目的としたディープラーニングベースのシステム」「この技術は、アニメーション制作における着色作業を効率化し、特に手間のかかるフレーム単位の処理を軽減することを目指している」らしいAniDocを試してみます。

使用するPCはドスパラさんの「GALLERIA UL9C-R49」。スペックは
・CPU: Intel® Core™ i9-13900HX Processor
・Mem: 64 GB
・GPU: NVIDIA® GeForce RTX™ 4090 Laptop GPU(16GB)
・GPU: NVIDIA® GeForce RTX™ 4090 (24GB)
・OS: Ubuntu22.04 on WSL2(Windows 11)
です。


1. 準備

環境構築

venv環境構築。

python3 -m venv anidoc
cd $_
source bin/activate

リポジトリをクローン。

git clone https://github.com/yihao-meng/AniDoc
cd AniDoc

パッケージのインストールです。shell scriptが用意されているので、有り難くそれを使用します。が、いくつか不足しているので合わせてインストールしておきます。

bash ./install.sh
# 不足パッケージ
pip install moviepy==1.0.3 basicsr

モデルのダウンロード

# SVD
huggingface-cli download --repo-type model --local-dir pretrained_weights/stable-video-diffusion-img2vid-xt stabilityai/stable-video-diffusion-img2vid

# AniDoc Unet and ControlNet
huggingface-cli download --repo-type model --local-dir pretrained_weights/anidoc Yhmeng1106/anidoc

# co_tracker
wget -P ./pretrained_weights https://huggingface.co/facebook/cotracker/resolve/main/cotracker2.pth

anidocはanidoc/anidocをanidocにしなければならないので、以下のようにディレクトリを移動させておきます(お茶を濁します)。

cd pretrained_weights
mv anidoc anidoc.orig
mv anidoc.orig/anidoc .
cd ..

2. プログラムを確認する

(1) anidoc_inference.sh と anidoc_inference.py

anidoc_inference.shとanidoc_inference.pyは、アニメーションの線画シーケンスを特定のキャラクターデザインに基づいて着色するためのスクリプトです。

anidoc_inference.sh

このシェルスクリプトは、Pythonスクリプトであるanidoc_inference.pyを実行するためのコマンドを含んでいます。主な引数は以下です。

  • --control_image:線画シーケンス(カラー動画)を指定し、各フレームのスケッチを抽出して制御信号として使用する。

  • --ref_image:キャラクターデザインの参照画像を指定。

これらの引数を適切に設定することで、anidoc_inference.pyを実行し、指定した線画シーケンスが参照キャラクターデザインに基づいて着色されます。

anidoc_inference.py

このPythonスクリプトは、指定された線画シーケンスとキャラクターデザイン参照画像を入力として受け取り、機械学習モデルを使用して線画シーケンスを着色します。

処理の流れは以下です。

  1. 入力の読み込み:指定された線画シーケンスと参照画像を読み込む。

  2. 前処理:線画シーケンスから各フレームのスケッチを抽出し、モデルの入力形式に変換。

  3. モデル推論:事前学習済みのモデルを使用して、線画シーケンスを指定のキャラクターデザインに基づいて着色。

  4. 後処理と保存:生成された着色済みのフレームを動画として保存。

これらのスクリプトを使用することで、独自の線画シーケンスを特定のキャラクターデザインに基づいて自動的に着色することができるようです。たぶん。

(2) process_video_to_14frames.py

指定されたフォルダ内の動画ファイル(主にMP4形式)を読み込み、それぞれから14フレームを均等に抽出して新しい動画ファイルとして保存し、さらに各フレームを個別の画像ファイル(PNG形式)として保存するスクリプトです。

  1. 入力と出力のフォルダ設定

    • input_folderに処理対象の動画ファイルが含まれるフォルダパスを指定。

    • output_folderに処理結果を保存するフォルダのパスを指定。

  2. 動画ファイルの処理

    • input_folder内の全ファイルを取得し、.mp4ファイルを対象。

    • 各動画ファイルに対して、cv2.VideoCaptureを使用して動画を読み込み、以下の情報を取得。

      • 総フレーム数(cv2.CAP_PROP_FRAME_COUNT)

      • フレームレート(cv2.CAP_PROP_FPS)

      • フレームの幅(cv2.CAP_PROP_FRAME_WIDTH)

      • フレームの高さ(cv2.CAP_PROP_FRAME_HEIGHT)

  3. フレームの抽出

    • 動画の開始から終了までの間に均等に14個のフレームインデックスを計算。

    • 動画をフレームごとに読み込み、計算したインデックスに該当するフレームをsampled_framesリストに追加。

  4. 新しい動画ファイルの作成

    • 抽出した14フレームを使用して、新しい動画ファイルを作成し、output_folder内に保存。

    • cv2.VideoWriterを使用して、元の動画と同じフレームレート、幅、高さで新しい動画を作成。

  5. フレームの画像ファイルとしての保存

    • 各動画ファイルに対応するフォルダをoutput_folder内に作成し、抽出した各フレームをPNG形式で保存。

    • cv2.imwriteを使用して、各フレームをframe_XXX.pngという形式のファイル名で保存。

  6. 画像ファイルの処理

    • input_folder内の.pngのファイルは、そのままoutput_folderにコピー。

動画から特定のフレーム数を抽出し、新たな動画や画像として保存する際に有用なのかしら。

3. 試してみる - サンプルを

サンプルに従い試してみましょう

bash  scripts_infer/anidoc_inference.sh

するとこんな感じのログが出力され、

layers per block is 2
Loading pipeline components...: 100%|██████████████████████████████████████████████████████| 5/5 [00:05<00:00,  1.17s/it]
Downloading: "https://huggingface.co/lllyasviel/Annotators/resolve/main/sk_model.pth" to /mnt/data/shoji_noguchi/venv/anidoc/AniDoc/lineart_extractor/annotator/ckpts/sk_model.pth

100%|███████████████████████████████████████████████████████████████████████████████| 16.4M/16.4M [00:01<00:00, 10.9MB/s]
Downloading: "https://huggingface.co/lllyasviel/Annotators/resolve/main/sk_model2.pth" to /mnt/data/shoji_noguchi/venv/anidoc/AniDoc/lineart_extractor/annotator/ckpts/sk_model2.pth

100%|███████████████████████████████████████████████████████████████████████████████| 16.4M/16.4M [00:00<00:00, 32.5MB/s]
Downloading: "https://github.com/cvg/LightGlue/releases/download/v0.1_arxiv/superpoint_v1.pth" to ./LightGlue/ckpts/superpoint_v1.pth
100%|███████████████████████████████████████████████████████████████████████████████| 4.96M/4.96M [00:00<00:00, 25.2MB/s]
WARNING:py.warnings:/mnt/data/shoji_noguchi/venv/anidoc/AniDoc/./LightGlue/lightglue/lightglue.py:143: UserWarning: FlashAttention is not available. For optimal speed, consider installing torch >= 2.0 or flash-attn.
  self.inner_attn = Attention(flash)

Downloading: "https://github.com/cvg/LightGlue/releases/download/v0.1_arxiv/superpoint_lightglue.pth" to ./LightGlue/ckpts/superpoint_lightglue.pth
100%|███████████████████████████████████████████████████████████████████████████████| 45.3M/45.3M [00:02<00:00, 19.9MB/s]
100%|████████████████████████████████████████████████████████████████████████████████████| 25/25 [00:19<00:00,  1.27it/s]
Moviepy - Building video results/sample4_sample4.mp4.
Moviepy - Writing video results/sample4_sample4.mp4

Moviepy - Done !
Moviepy - video ready results/sample4_sample4.mp4

resultsディレクトリの下にファイルができあがりました。

$ find results/ -type f -ls
 31983519    168 -rw-rw-r--   1 user user   167988 Dec 22 23:27 results/sample4_sample4/frames/sample4_sample4_frame_0005.png
 31983516    160 -rw-rw-r--   1 user user   162606 Dec 22 23:27 results/sample4_sample4/frames/sample4_sample4_frame_0002.png
 31983514    160 -rw-rw-r--   1 user user   160373 Dec 22 23:27 results/sample4_sample4/frames/sample4_sample4_frame_0000.png
 31983522    164 -rw-rw-r--   1 user user   165770 Dec 22 23:27 results/sample4_sample4/frames/sample4_sample4_frame_0008.png
 31983517    164 -rw-rw-r--   1 user user   164210 Dec 22 23:27 results/sample4_sample4/frames/sample4_sample4_frame_0003.png
 31983524    164 -rw-rw-r--   1 user user   166568 Dec 22 23:27 results/sample4_sample4/frames/sample4_sample4_frame_0010.png
 31983521    164 -rw-rw-r--   1 user user   165390 Dec 22 23:27 results/sample4_sample4/frames/sample4_sample4_frame_0007.png
 31983526    164 -rw-rw-r--   1 user user   166564 Dec 22 23:27 results/sample4_sample4/frames/sample4_sample4_frame_0012.png
 31983527    164 -rw-rw-r--   1 user user   164181 Dec 22 23:27 results/sample4_sample4/frames/sample4_sample4_frame_0013.png
 31983518    164 -rw-rw-r--   1 user user   166043 Dec 22 23:27 results/sample4_sample4/frames/sample4_sample4_frame_0004.png
 31983520    168 -rw-rw-r--   1 user user   169600 Dec 22 23:27 results/sample4_sample4/frames/sample4_sample4_frame_0006.png
 31983523    168 -rw-rw-r--   1 user user   169098 Dec 22 23:27 results/sample4_sample4/frames/sample4_sample4_frame_0009.png
 31983515    160 -rw-rw-r--   1 user user   161359 Dec 22 23:27 results/sample4_sample4/frames/sample4_sample4_frame_0001.png
 31983525    164 -rw-rw-r--   1 user user   166628 Dec 22 23:27 results/sample4_sample4/frames/sample4_sample4_frame_0011.png
 31983509     12 -rw-rw-r--   1 user user     9685 Dec 22 23:27 results/sample4_sample4/sketches/sample4_sample4_sketch_0009.png
 31983500     12 -rw-rw-r--   1 user user    10732 Dec 22 23:27 results/sample4_sample4/sketches/sample4_sample4_sketch_0000.png
 31983504     12 -rw-rw-r--   1 user user    10439 Dec 22 23:27 results/sample4_sample4/sketches/sample4_sample4_sketch_0004.png
 31983505     12 -rw-rw-r--   1 user user    10285 Dec 22 23:27 results/sample4_sample4/sketches/sample4_sample4_sketch_0005.png
 31983506     12 -rw-rw-r--   1 user user    10305 Dec 22 23:27 results/sample4_sample4/sketches/sample4_sample4_sketch_0006.png
 31983501     12 -rw-rw-r--   1 user user    10695 Dec 22 23:27 results/sample4_sample4/sketches/sample4_sample4_sketch_0001.png
 31983512     12 -rw-rw-r--   1 user user     9854 Dec 22 23:27 results/sample4_sample4/sketches/sample4_sample4_sketch_0012.png
 31983511     12 -rw-rw-r--   1 user user     9706 Dec 22 23:27 results/sample4_sample4/sketches/sample4_sample4_sketch_0011.png
 31983507     12 -rw-rw-r--   1 user user     9925 Dec 22 23:27 results/sample4_sample4/sketches/sample4_sample4_sketch_0007.png
 31983503     12 -rw-rw-r--   1 user user    10635 Dec 22 23:27 results/sample4_sample4/sketches/sample4_sample4_sketch_0003.png
 31983508     12 -rw-rw-r--   1 user user     9672 Dec 22 23:27 results/sample4_sample4/sketches/sample4_sample4_sketch_0008.png
 31983510     12 -rw-rw-r--   1 user user     9679 Dec 22 23:27 results/sample4_sample4/sketches/sample4_sample4_sketch_0010.png
 31983502     12 -rw-rw-r--   1 user user    10659 Dec 22 23:27 results/sample4_sample4/sketches/sample4_sample4_sketch_0002.png
 31983513     12 -rw-rw-r--   1 user user     9898 Dec 22 23:27 results/sample4_sample4/sketches/sample4_sample4_sketch_0013.png
 31983528     60 -rw-rw-r--   1 user user    58472 Dec 22 23:27 results/sample4_sample4/sample4_sample4_reference.png
 31983530     68 -rw-rw-r--   1 user user    67204 Dec 22 23:27 results/sample4_sample4.mp4
 31983529   1436 -rw-rw-r--   1 user user  1467049 Dec 22 23:27 results/sample4_sample4.gif

VRAM使用量は、14.3GBほど。

実行時間は42秒ほどでした。

real    0m42.580s
user    1m5.710s
sys     0m8.785s

4. 試してみる - 指定した.mp4で

process_video_to_14frames.pyを使用して指定したmp4からフレームを抽出してみて、いろいろ試してみましょう。

取り急ぎ、mp4ファイルを格納するディレクトリを作成します。

mkdir input_video_folder

で、適当なmp4ファイル(IMG_1129.mp4)を格納して、

以下のコマンドを実行します。

python process_video_to_14frames.py

としたら、14フレームが抽出され、mp4ファイルも生成されました。

$ find preprocessed_video_folders/ -type f -ls
 31983531   1788 -rw-r--r--   1 user user  1827613 Dec 22 23:56 preprocessed_video_folders/IMG_1129.mp4
 31983544   3136 -rw-r--r--   1 user user  3208889 Dec 22 23:56 preprocessed_video_folders/IMG_1129/frame_012.png
 31983536   3324 -rw-r--r--   1 user user  3400491 Dec 22 23:56 preprocessed_video_folders/IMG_1129/frame_004.png
 31983539   3268 -rw-r--r--   1 user user  3343972 Dec 22 23:56 preprocessed_video_folders/IMG_1129/frame_007.png
 31983535   3184 -rw-r--r--   1 user user  3259855 Dec 22 23:56 preprocessed_video_folders/IMG_1129/frame_003.png
 31983542   3096 -rw-r--r--   1 user user  3168469 Dec 22 23:56 preprocessed_video_folders/IMG_1129/frame_010.png
 31983532   3116 -rw-r--r--   1 user user  3187698 Dec 22 23:56 preprocessed_video_folders/IMG_1129/frame_000.png
 31983534   3108 -rw-r--r--   1 user user  3178716 Dec 22 23:56 preprocessed_video_folders/IMG_1129/frame_002.png
 31983545   3432 -rw-r--r--   1 user user  3511952 Dec 22 23:56 preprocessed_video_folders/IMG_1129/frame_013.png
 31983533   3144 -rw-r--r--   1 user user  3215817 Dec 22 23:56 preprocessed_video_folders/IMG_1129/frame_001.png
 31983540   2984 -rw-r--r--   1 user user  3054778 Dec 22 23:56 preprocessed_video_folders/IMG_1129/frame_008.png
 31983538   3128 -rw-r--r--   1 user user  3201240 Dec 22 23:56 preprocessed_video_folders/IMG_1129/frame_006.png
 31983543   3136 -rw-r--r--   1 user user  3209698 Dec 22 23:56 preprocessed_video_folders/IMG_1129/frame_011.png
 31983537   3052 -rw-r--r--   1 user user  3123860 Dec 22 23:56 preprocessed_video_folders/IMG_1129/frame_005.png
 31983541   3000 -rw-r--r--   1 user user  3071961 Dec 22 23:56 preprocessed_video_folders/IMG_1129/frame_009.png
preprocessed_video_folders/IMG_1129

これに着色必要となる参照画像(ref_image)を指定・・・、ここは愛らしいイチゴに登場してもらいましょう。

ichigo.png

では、実行です。

CUDA_VISIBLE_DEVICES=0 python scripts_infer/anidoc_inference.py
    --all_sketch
    --matching
    --tracking
    --control_image preprocessed_video_folders/IMG_1129.mp4
    --ref_image ichigo.png
    --output_dir results.1129
    --max_point 10

生成されたものがこちら。

results.1129/ichigo_IMG_1129.mp4

results.1129/ichigo_IMG_1129.gif

生成されたスケッチ。

results.1129/ichigo_IMG_1129/sketches

生成されたフレーム。


results.1129/ichigo_IMG_1129/frames

うーん、だったので、参照画像(ref_image)を加工して試してみたのがこちら。

参照画像(一番左)を、店員さんだけプラム色へ
参照画像(一番左)を、店員さんをプラム色にして他真っ白


いいなと思ったら応援しよう!