はじめに
Zoomでバーチャル背景が流行っていますね。グリーンバックを必要とせずに一枚の背景画像から人物を切り抜き、ピクセルレベルで違和感なく合成できるBackground Mattingをやってみました。CPUでも動くよ。
システム環境
- Windows10(RTX2080 Max-Q、i7-8750H、RAM16GB)
- Anaconda 2020.02
- Python 3.6
- CUDA 10.0
- cuDNN
導入
Background-Mattingからクローンします。
back-matting環境を作ります。
$ cd Background-Matting-master
$ conda create -n back-matting python=3.6
$ conda activate back-matting
Pytorch(CUDA 10.0)をインストールします。
$ pip install torch==1.2.0 torchvision==0.4.0 -f https://download.pytorch.org/whl/torch_stable.html
必要なライブラリをインストールします。
$ pip install tensorflow-gpu==1.14.0
$ pip install -r requirements.txt
ここからモデルをダウンロードし、Modelsフォルダに置きます。
下記からCUDA 10.0をインストールします。
インストールできたら、Anacondaを再起動します。(システム環境変数にPATHが追加されるため)
cuDNNも必要なので、Download cuDNN v7.6.4 (September 27, 2019), for CUDA 10.0をダウンロードします。
ダウンロードしたら、cudnn-10.0-windows10-x64-v7.6.4.38\cuda\bin\cudnn64_7.dllをC:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.0\binに移動
cudnn-10.0-windows10-x64-v7.6.4.38\cuda\lib\x64\cudnn.libをC:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.0\lib\x64に移動
cudnn-10.0-windows10-x64-v7.6.4.38\cuda\include\cudnn.hをC:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.0\includeに移動します。
下記を実行し、画像から人物を切り抜いたマスク画像を生成します。
$ python test_segmentation_deeplab.py -i sample_data/input
sample_data\inputに_masksDL.pngの画像が生成されます。
下記を実行し、補正します。
$ python test_pre_process.py -i sample_data/input
Done: sample_data/input
と出力され、補正されたらしい。
test_background-matting_image.pyの20行目をコメントアウトし、19行目のコメントを外し、os.environ["CUDA_VISIBLE_DEVICES"]を"0"にします。
os.environ["CUDA_VISIBLE_DEVICES"]="0" # "4"
# print('CUDA Device: ' + os.environ["CUDA_VISIBLE_DEVICES"])
下記を実行します。
$ python test_background-matting_image.py -m real-hand-held -i sample_data/input/ -o sample_data/output/ -tb sample_data/background/0001.png
sample_data\outputに結果が表示されました!
CPUでやーる
test_background-matting_image.pyの19行目のos.environ["CUDA_VISIBLE_DEVICES"]を"-1"にします。
os.environ["CUDA_VISIBLE_DEVICES"]="-1"
57行目のtorch.load(model_name1)をtorch.load(model_name1,map_location='cpu')にします。
そして、cuda()の部分を取っ払います!
netM.load_state_dict(torch.load(model_name1, map_location='cpu'))
# netM.cuda();
netM.eval()
あとは156行目付近のcuda()を取り除けば、動くはず。
img,bg,rcnn_al,multi_fr=Variable(img),Variable(bg),Variable(rcnn_al),Variable(multi_fr)
input_im=torch.cat([img,bg,rcnn_al,multi_fr],dim=1)
alpha_pred,fg_pred_tmp=netM(img,bg,rcnn_al,multi_fr)
al_mask=(alpha_pred>0.95).type(torch.FloatTensor)
塩さん、ありがとうございます!
そのcuda()とほかcuda関連系のメソッド取っ払ってみてください!
— 塩 (@shiomasa1218) April 26, 2020
※test_segmentation_deeplab.py、test_pre_process_video.pyのCPU化が必要?
動画もやーる
動画もフレームにして処理した後、動画にするので、一緒ですね。
サンプルの動画をここからダウンロードし、sample_videoとsample_video_fixedをBackground-Mattingの下に置きます。
動画からフレームを抽出します。
sample_videoの下に、inputフォルダとbackgroundフォルダを作成します。
ffmpegをダウンロードします。
システム環境変数のPATHにC:\ffmpeg-20200424-a501947-win64-static\binを追加します。
システム環境変数を編集したらAnacondaを再起動します。
fountain.movをtarget_back.movに名前を変更し、下記コマンドを実行します。
$ cd sample_video
$ ffmpeg -i teaser.mov input/%04d_img.png -hide_banner
$ ffmpeg -i target_back.mov background/%04d.png -hide_banner
inputフォルダに対して、セグメンテーション(マスク画像生成)を行います。
$ cd ../
$ python test_segmentation_deeplab.py -i sample_video/input
下記を実行し、補正します。
$ python test_pre_process_video.py -i sample_video/input -v_name sample_video/teaser_back.png
下記を実行し、結果を見てみましょう。
$ python test_background-matting_image.py -m real-hand-held -i sample_video/input/ -o sample_video/output/ -tb sample_video/background/
結果のフレームをffmpegを用いて動画にします。
$ cd sample_video
$ ffmpeg -r 60 -f image2 -i output/%04d_matte.png -vcodec libx264 -crf 15 -s 1280x720 -pix_fmt yuv420p teaser_matte.mp4
$ ffmpeg -r 60 -f image2 -i output/%04d_compose.png -vcodec libx264 -crf 15 -s 1280x720 -pix_fmt yuv420p teaser_compose.mp4
teaser_matte.mp4 pic.twitter.com/PQCMWo5K1n
— 藤本賢志(ガチ本)@pixivFANBOXはじめました (@sotongshi) April 26, 2020
sample_video_fixedについても同様に行います。inputフォルダとbackgroundフォルダを作成、ffmpegでフレームを抽出します。
$ cd sample_video_fixed
$ ffmpeg -i teaser.mov input/%04d_img.png -hide_banner
$ ffmpeg -i target_back.mov background/%04d.png -hide_banner
inputフォルダに対して、セグメンテーション(マスク画像生成)を行います。
$ cd ../
$ python test_segmentation_deeplab.py -i sample_video_fixed/input
sample_video_fixedについては補正は必要ありません。
下記を実行し、結果を見てみましょう。
$ python test_background-matting_image.py -m real-fixed-cam -i sample_video_fixed/input/ -o sample_video_fixed/output/ -tb sample_video_fixed/background/ -b sample_video_fixed/teaser_back.png
結果のフレームをffmpegを用いて動画にします。
$ cd sample_video_fixed
$ ffmpeg -r 60 -f image2 -i output/%04d_matte.png -vcodec libx264 -crf 15 -s 1280x720 -pix_fmt yuv420p teaser_matte.mp4
$ ffmpeg -r 60 -f image2 -i output/%04d_compose.png -vcodec libx264 -crf 15 -s 1280x720 -pix_fmt yuv420p teaser_compose.mp4
sample_video_fixed teaser_matte.mp4 pic.twitter.com/HGRoMUhpQA
— 藤本賢志(ガチ本)@pixivFANBOXはじめました (@sotongshi) April 26, 2020
お疲れ様でした。