アニメキャラの動画切り抜き作業を楽にしたい

概要

  • 面倒な切り抜き作業を楽にするためのプログラムをColabで動かせるようにしました
  • AnimeSegmentationをつかった切り抜きなので二次元画像の人物切り抜き特化です
  • 中間ファイルも出力されるので手動での修正がやりやすいと思います

colab.research.google.com

はじめに


動画の切り抜き作業って面倒ですよね。動画から画像を連番で出力して1枚ずつ切り抜いて繋げて…
最近はremove.bgrunwayなどが出てきて画像の人物切り抜き作業はかなり楽になってきました。
Web上で動かせるデモも公開されているので、書き出した連番画像を1枚ずつ処理していけば透過映像素材も比較的楽に作ることができます。
ただ、そういったサービスはどうしても機能的な制限が気になります(画質が下げられたり○秒以下の動画しか処理できなかったり)
個人的には連番画像を1枚ずつ処理にかけていくのも面倒…ということで、動画の連番画像出力から背景除去・透過された映像のエンコードまでを自動化するプログラムを作りました。

今回公開したものはAnimeSegmentationの背景除去モデルを使ったプログラムです。
画像単体の切り抜きであれば以下のリンクから試しに使うことができます。

huggingface.co

このモデルは二次元画像の人物切り抜きに特化したものなので、実写映像や人物以外の切り抜きには適していません。
また、認識する対象の指定など細かい調整はできないようなので、以下のリンク先にあるような人物単体の切り抜きが向いているみたいです。

github.com

人物を認識して背景除去を行うので、例えば画面に人物が二人映っているときは両方ともが切り抜き対象になります。

以前公開した音声文字起こしと同様で、Google Colabで公開している都合上機能的な制限はありませんが、GPUリソース的な利用制限はあります。
制限に引っかかってしまったらPro版へ課金するか別アカウントを使うなどを試してみてください。

処理の流れ


1. 動画を連番画像で出力

AviUtl等の編集ソフトでも動画から連番画像での書き出しはできますが、ここでは切り抜きが必要な枚数の画像だけを出力します。
例えばアニメの映像は基本的に24fpsですが、必ず1秒間に24枚の絵があるわけではなく絵の枚数は動きに応じて2,3フレームに1枚だったりします。
同じ絵に対して毎回背景除去処理を行うと無駄に時間がかかってしまうので、動きのあるフレームを検出して必要最低限のフレームのみ書き出す処理を行っています。

ループしている映像だと完全に重複排除はできないですが、連続している同じフレームの部分は除去するようにしています。

2. 背景除去

出力した画像に対してAnimeSegmentationの処理をかけて、背景部分を透過した画像を出力します。
AIの切り抜きと言っても精度は完璧ではないので、手動で修正しやすいように連番画像も中間ファイルとして出力するようにしています。
背景除去がうまくいかなかったときにその画像だけ手動で編集して上書きすれば、その後の透過映像のエンコードに反映させることができます。

3. 透過映像としてエンコード

背景除去された画像ファイルをつなげてアルファ付き動画ファイルとしてエンコードします。1の処理で重複排除したので、エンコード前にフレームを複製して間を補完しています。
出力可能なアルファ付き動画ファイルの形式は3種類で、UT Video Codec/QT Animation/RGBA(無圧縮)です。
Lagarith Lossless Video Codecが使えれば理想的だったんですが、対応してなさそうだったので自分はUT Video Codecを使っています。

使い方


Colabのノートブックのリンクはこちらです。

colab.research.google.com

背景除去を行う動画は、処理したい部分だけ切り出してからGoogle Driveにアップするようにしてください。

1. 事前準備

自分のGoogle Driveのマウント、ランタイムへの接続、ライブラリのインストールを行います。
詳細はノートブック側の説明参照です。

2. パラメータの入力

「1.パラメータ指定」のセルの各欄に必要な情報を入力してセルを実行します。

  • 元動画ファイル:MOV_FILE

    • 切り抜きたい動画ファイル(.mp4形式)のパスを入力します。
  • 連番画像保存先フォルダ:IMG_FOLDER

    • 連番画像が出力されるフォルダのパスを入力します。フォルダが存在しない場合は新規に作成されます。
  • フレーム画像の重複排除:DEDUPE_IMG

    • 連番画像を出力するときに同じ画像を排除するかどうかを選択します。チェックを外すとすべてのフレームに対して背景除去処理を行うので時間がかかります。
  • 透過画像保存先フォルダ:RESULT_FOLDER

    • 背景除去した画像が保存されるフォルダのパスを入力します。フォルダが存在しない場合は新規に作成されます。
  • 出力動画ファイル名:OUTPUT_FILE

    • 出力するアルファ付き動画ファイルのパスを指定します。拡張子は.avi推奨です。
  • 動画フォーマット:RENDER_FORMAT

    • 出力するアルファ付き動画のフォーマットを選択します。
    • UTVideoとQT Animationは可逆圧縮コーデックです。基本的にはこのどちらかが推奨です。
    • RGBAを選択すると無圧縮aviファイルになります。上記の可逆コーデックが使えないとき用ですが、非常にサイズが大きくなるのでドライブの容量には注意です。
    • PNG Sequenceを指定した場合は動画ファイルは生成されずに連番PNGファイルが重複排除なしで保存されます。エンコードはせずにファイルをコピーするだけの処理です。
  • 動画ビットレート:VBITRATE

    • 可逆コーデックでエンコードする場合のビットレートを指定します。単位はkbpsです。
    • 無圧縮aviやPNG Sequenceで出力するときには関係ありません。
3. セルの実行

「2.連番画像の出力」「3.背景除去」「4.動画エンコード」と順番にセルを実行していきます。
処理中に次のセルを実行しても前の処理が終わってから次が始まるようになっているので、パラメータを入力したら1~4までまとめて順にクリックするというのでも問題ありません。

「2.連番画像の出力」を実行

inputフォルダに画像が出力
出力されるファイル名は<フレーム番号>.pngの形式になります。

「3.背景除去」を実行

resultフォルダに透過画像が出力
出力されるファイル名はIMG_FOLDERの中身と同じで<フレーム番号>.pngの形式です。

「4.動画エンコード」を実行

アルファ付き動画ファイルが出力

aviファイルはプレビューできるようになるまで少し時間がかかります。
手動で修正したい場合はRESULT_FOLDERの中身の画像ファイルを同じファイル名で更新して、再度「4.動画エンコード」を実行すれば修正が反映されます。

実行結果の例


元動画
実行結果
※容量の都合上GIFにしてリサイズしています。
元の映像がすごく細かく動いているのでこの素材は8.26秒で96枚もの絵があるんですが、自動化できたおかげで1~2分で切り抜きが終わりました。

比較的綺麗に抜けていますが、下の部分をよく見ると若干透過されていたり切り抜き残しがあるのが分かると思います。
汎用的なGB素材としてではなく動画の一部分で使うくらいであれば多少の切り抜きガバは目立たないので、用途に応じて適宜調整するのが良いと思います。
使用例(https://www.nicovideo.jp/watch/sm43725340
20240506182109 よくある文字を後ろに置く演出みたいなのだったらあまり気にならないかも

画像によってはこういう感じで中途半端に透過されたり背景部分が残ったりすることもよくあります。
途中の画像を手動で修正しても問題ないですが、動画編集ソフト側のアルファ閾値の調整を調整して元動画をマスクすることでなんとかなる場合もあります。
なんともならない場合は手動で頑張りましょう。

最後に


AnimeSegmentation自体はだいぶ前から公開されていてましたが、今はこれより精度が上がったCartoonSegmentationというモデルが公開されています。

github.com

当初はこっちのモデルで背景除去するようにしたかったんですが、ライブラリの依存関係の問題なのかまだColabで動作確認ができていないので、今回はAnimeSegmentationを使う形にしました。
いろいろな問題が解決でき次第使えるモデルは今後増やしていきたいなと思ってます。