この記事はクソアプリ Advent Calendar 2020の12日目の記事です。
プロローグ
時は2020年、新型コロナウイルスが世界中で猛威を振るい、エンジニア達はリモートワークを余儀なくされた。
日々繰り返されるweb会議。
エンジニア達は疲弊し、会議画面には苦悶の表情が映されることが多くなった。
「このままではいけない…」
この惨状を打破すべく、ある一人の男が立ち上がったのだった。(※フィクションです)
今回作ったもの
前置きはこれくらいにして、今回作ったクソアプリをご紹介します。
このアプリできること
webカメラで撮影された自分の顔と予め用意した顔画像とを交換する、所謂Face Swap処理をした映像を作り、TeamsやZoomなどのWeb会議に流すことができます。
これを使うことにより、常に真顔や笑顔の映像を作り出し、お好みの会議の雰囲気を作ることが可能となります!
デモ
いかがでしょうか?真剣な表情で会議に参加している様子が伝わるかと思います。
また、使用する画像を変更することで、会議に終始にこやかな笑顔で参加することも可能です。
ときにはミスター・ビーンになりきり、参加メンバを笑わせるのも良いかもしれません。
使用した技術
今回このアプリには以下の技術を使用しました。
- Windows10
- C++(VisualStudio2019)
- OpenCV
- contribのfaceモジュールを使用
- ycapture
偉大な先人達の知恵をお借りしてそれらを適当に繋いでおります。
特にycaptureは素晴らしいプログラムで、これを使用することで、加工した画像を仮想カメラに流す事ができるようになります。
アプリのソースコードはこちらになります。
https://github.com/onushi-k/face-swap-yc-client
ycaptureに映像を流し込むクライアント部分のみになりますので、実行には別途ycaptureやOpenCVのビルド/インストールが必要となります。
処理の内容
下準備
- 静止顔画像から顔を抽出
- CascadeClassifier を使用して、顔領域を検出
- 検出器にはOpenCVに予め用意されているhaarcascade_frontalface_alt.xmlを使用しました。
- 検出した顔領域に対して、顔の特徴点を抽出
- 抽出にはOpenCVのFacemark APIを使用しました。
- CascadeClassifier を使用して、顔領域を検出
メイン処理
- カメラ画像をキャプチャ
- カメラ画像から顔を抽出
- 下準備で抽出した顔をカメラ画像に貼り付け
- 貼り付けについてはこちらの記事を参考にしています。
- 顔の特徴点の抽出までは下準備で行った処理と同じで、その後凸包を求め、ドロネー分割を行い、メッシュを貼り付け先にアフィン変換しseamlessCloneしています。(←ヨクワカッテナイ)
- 貼り付けについてはこちらの記事を参考にしています。
- ycaptureの仮想カメラに流し込む
処理の中で顔の検出に失敗した場合には、そのフレームでの処理をスキップするようにしたため、素顔が露出することはほぼありません。
("ほぼ"と書いたのは、たまに顔の検出位置が極端にずれて素顔が露出してしまうことがあるためです…)
反省
- Face Swapの位置がフレームごとにずれるので動画でみるとぐにゃぐにゃした顔になり不気味さを醸し出しています。
- 今回、FaceSwapはOpenCVで実現しているのですが、顔を傾けたりするとすぐに検出に失敗します。dlibの方がロバストだという情報があるため、そちらのほうが良かったかもしれません。
- もっと言えば、令和最新版としてはDeep Learningを使うべきだったかもしれません。機会があれば挑戦してみたいと思います。
- そもそも弊社ではweb会議でカメラをONにすることは滅多にないので、使い所がありませんでした。
まとめ
以上、WITHコロナ時代にweb会議で活躍する(?)クソアプリをご紹介しました。
明日は@sada_lp1さんが「今年最後のクソをひねり出します」とのことです!楽しみです!