本記事はこちらでも紹介しております。
https://cloud.flect.co.jp/entry/2020/04/02/114756#f-459f23dc
前回と前々回の投稿では、TeamsやZoomでカメラ画像を加工する方法をご紹介しました。これらの投稿では、笑顔や感情(表情)を検出してニコニコマークを表示するデモをご紹介しています。
https://qiita.com/wok/items/0a7c82c6f97f756bde65
https://qiita.com/wok/items/06bdc6b0a0a3f93eab91
今回、もう少し拡張して、画像をアニメ風に変換して表示する実験をしてみたので、ご紹介します。最初にネタバレしておくと、リアルタイムでアニメ風画像に変換するにはCPUだとちょっとラグが大きすぎて使いづらいかなと思います。
(GPUだとマシになるのかは試してない。)
➔ GPUで試してみた。15fpsくらいは出る。めちゃくちゃはやかった。
- top-left : CPU Intel 4770
- top-right : CPU Intel 9900KF
- bottom-left : CPU Intel 9900KF with GPU 2080ti
- bottom-right : CPU Intel 9900KF with GPU 2080ti throttling by skip_frame=3
それでは早速ご紹介いたします。
アニメ風画像変換
半年ほど前にニュースメディアにも取り上げられていたようなので、ご存知の方も多いかと思いますが、写真をアニメ風に変換する手法が下記のページで公開されています。
このUGATITでは、単純なimage2imageのスタイル変換とは違い、GeneratorとDiscriminatorを用いるいわゆるGANの技術をベースに、独自のAdaLINという機能を追加することで形状の変化にも対応ができるようになったようです。
In our work, we propose an Adaptive Layer-Instance Normalization (AdaLIN) function to adaptively select a proper ratio between IN and LN. Through the AdaLIN, our attention-guided model can flexibly control the amount of change in shape and texture.
詳細は、本論文1や解説記事2を見ていただくとして、上記ページに公開されているトレーニング済みのモデルを使って、実際に変換してみるとこんな感じになります。
被写体が遠いとあまりうまく変換してくれないようです。また、おじさんはあまりうまく対応できていないみたいです。トレーニングで用いられたデータセットも上記ページで公開されていますが、若い女性に偏っているようなので、これが原因かと思われます。(私はまだおじさんではない、、、というのは無理があるか。)
実装の概要
上記のとおり、被写体(人物の顔)に近い画像(≒顔が画面の大部分を占める)にする必要がありそうです。今回は、前々回までにご紹介した顔検出機能により顔の場所を特定し、その場所を切り出してUGATITで変換をかけるという手順でやってみました。
実装の詳細は、下記で言及するリポジトリをご参照ください。3
環境構築
前回までの記事を参考に、v4l2loopbackや、顔認識のモデルなどを準備しておいてください。
また、前回までと同様に、下記のリポジトリからスクリプトをcloneして、必要なモジュールをインストールしてください。
$ git clone https://github.com/dannadori/WebCamHooker.git
$ cd WebCamHooker/
$ pip3 install -r requirements.txt
UGATITのトレーニング済みモデルの配置
UGATITの公式ではTensorflow版とPyTorch版のソースコードが提供されていますが、トレーニング済みのモデルはTensorflow版しかないようです。これを取得して展開してください。
なお、WindowsやLinuxの通常のzip展開ツールだと展開に失敗するようです。Windowsを用いる場合は7zipだとうまく行くという報告がissueに上がっています。また、Macだと問題は発生しないようです。なお、Linuxは解決策は不明です・・・。4
一応、正常に動くモデルのハッシュ値(md5sum)を記載しておきます。(多分ここが一番のつまずきポイントなので。)
$ find . -type f |xargs -I{} md5sum {}
43a47eb34ad056427457b1f8452e3f79 ./UGATIT.model-1000000.data-00000-of-00001
388e18fe2d6cedab8b1dbaefdddab4da ./UGATIT.model-1000000.meta
a08353525ecf78c4b6b33b0b2ab2b75c ./UGATIT.model-1000000.index
f8c38782b22e3c4c61d4937316cd3493 ./checkpoint
これらのファイルを上記git からcloneしたフォルダの、UGATIT/checkpoint
に格納します。このような感じになっていればOKです。
$ ls UGATIT/checkpoint/ -1
UGATIT.model-1000000.data-00000-of-00001
UGATIT.model-1000000.index
UGATIT.model-1000000.meta
checkpoint
ビデオ会議をしてみよう!
実行は次のように行います。オプションが一つ追加されてます。
- input_video_num には実際のウェブカメラのデバイス番号を入れてください。/dev/video0なら末尾の0を入力します。
- output_video_dev には仮想ウェブカメラデバイスのデバイスファイルを指定してください。
- anime_mode はTrueにしてください。
なお、終了のさせ方はctrl+cでお願いします。
$ python3 webcamhooker.py --input_video_num 0 --output_video_dev /dev/video2 --anime_mode True
上のコマンドを実行するとffmpegが動き、仮想カメラデバイスに映像が配信されはじめます。
前回と同様に、ビデオ会議をするときにビデオデバイスの一覧にdummy〜〜というものが現れると思うのでそれを選択してください。
これはTeamsの例です。画面上右上にワイプで変換元の画像も表示しています。思ったよりちゃんとアニメ風に変換されて配信されますね。ただし、とても重く、ちょっと古めのPCだと1秒1コマとかそういうレベルです(Intel(R) Core(TM) i7-4770 CPU @ 3.40GHz, 32G RAM)。普通に運用するには厳しいかもしれません。いまのところは出落ち要員かな。いずれGPUでも試してみたいと思います。
最後に
在宅勤務が長引き、気軽なコミュニケーションがなかなか難しいかもしれませんが、こういった遊び心をビデオ会議に持ち込んで、会話を活性化させるのもいいのではないかと思っています。
もっといろいろできると思いますので、みなさんもいろいろ試してみてください。
-
https://www.slideshare.net/meownoisy/ugatit-195710494 ざくっと理解するにはこのスライドが良さそう。 ↩
-
2020/4/2現在、注ぎ足しつぎ足しで作っているので、ソースコードが汚い。どこかでリファクタリングします)) ↩
-
いずれも2020/4/2現在 ↩