概要
業務でWeb会議をする際に髭がきれいに剃ってあると清潔感が出て相手に好印象を与えます。
しかし、髭を剃り忘れることもありますし頻繁に剃ると肌に負担がかかります。
以前はSnap Cameraのフィルターで髭を除去していましたが2023年6月現在ではサービスが終了して使えません。
そこで、髭の除去をシェーバーではなくソフトウェアに任せるスクリプトのサンプルを作成しました。
作ったもの
ソースコードはGitHubで公開しています。
以下の様に顔の下半分をぼかすことで髭を目立たなくします。
※これは画像生成AIで生成された実在しない人物です。
動作環境
Windows 10
Python 3.9.13
使用ツール
-
MediaPipe
- 顔や手などを機械学習で検出できるライブラリ
- Googleが公開している
-
OpenCV
- 言わずとしれた画像処理ライブラリ
-
pyvirtualcam
- OBSの仮想カメラに映像を出力するためのpython用ライブラリ
工夫したこと
髭の生える領域だけをぼかす
OpenCVの画像をぼかす関数は領域を指定することができません。そこで、以下の手順で処理しました。
髭の生える領域はこちらの画像を見ながら手動で頂点インデックスの配列として定義しました。
beard_point_idxes = [
# 左もみあげ → 人中
132, 177, 147, 187, 207, 206, 203, 98, 97, 2,
# 人中 → 右もみあげ
326, 327, 423, 426, 427, 411, 376, 401, 361,
# 右もみあげ → あご中心
288, 397, 365, 379, 378, 400, 377, 152,
# あご中心 → 左もみあげ
148, 176, 149, 150, 136, 172, 58, 132,
]
mouse_point_idxes = [
# 上
61, 185, 40, 39, 37, 0, 267, 269, 270, 409,
# 下
291, 375, 321, 405, 314, 17, 84, 181, 91, 146,
]
口を開けた時に顎がはみ出すことを防止する
MediaPipeの検出した顔の領域をそのまま使用すると、口を大きく開けた時に顎の先が検出結果とズレてぼかし領域からはみ出しました。
そこで、ぼかし領域を中心から1.1倍拡大することではみ出さない様にできました。
解像度を低めに設定することでフレームレートを確保する
解像度を1280720に設定するとフレームレートが10程度に低下しました。
640360と低く設定することでフレームレートが30程度出るようになりました。
改善点
今回の手法は品質がよくありません。ぼかすだけだと髭が濃い場合には無意味だったり、ぼかし領域の境目に違和感があります。
今回の手法に加えて髭が生える領域を肌色に近づけるともっと良い結果になりそうです。
また、使用するデバイスをGPUに設定すると解像度をもっと上げられそうです。そのためには、MediaPipeのモデルをGPU向けにビルドする必要があるようです。
参考ページ