TeamsやZoomでカメラ画像を加工する方法

` 本記事はこちらでも紹介しております。`
https://cloud.flect.co.jp/entry/2020/03/31/162537

みなさんこんにちは。

現在うちの会社では、都知事の要請を受け、新型コロナウイルス感染予防対策および拡散防止のため原則在宅勤務となっています。
同じような対応を取られている方も多く様々な困難があるかと思いますが、ぜひ力を合わせてこの難曲を乗り越えていきたいと考えています。

さて、原則在宅勤務が長引いてくると、日頃行われていた何気ない会話ができないなど、ストレスも溜まってくることも考えられます。
そんな状況で一つでもクスっと笑えて息抜きができる状況が作れればよいないった思いで、一つ小ネタをご紹介します。

内容は、マイクロソフトのTeamsやZoomなどのビデオ会議において、ウェブカメラをフックして加工して配信する方法です。
私がLinux使いのため、今回はLinuxでのご紹介となります。他のプラットフォームも何れ何処かで紹介されると思います。

なお、「一つでもクスっと笑えて息抜きができる状況」を作るのも時と場合を選びますので、そこは自己責任でお願いします(^_^)/。

![test.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365991/2f6478a6-4898-579c-c982-e9cba4831323.gif)




#### 前提
大抵のLinuxシステムで問題なく動くと思いますが、私が作業した環境はDebianのBusterです。

```
$ cat /etc/debian_version
10.3
```
また、python3が入っていないようでしたら、導入しておいてください。

```
$ python3 --version
Python 3.7.3
```

#### 関連ソフトウェアのインストール
##### 仮想ウェブカメラデバイス
今回はv4l2loopbackという仮想ウェブカメラデバイスを用います。
https://github.com/umlaeute/v4l2loopback

仮想ウェブカメラデバイスと、実際のウェブカメラを識別する必要があるので、まずは実際のウェブカメラのデバイスファイルを確認しておきます。
下記の例だと、video0とvideo1が実際のウェブカメラに割り当てられているようです。

```
$ ls /dev/video*
/dev/video0  /dev/video1
```
それでは、v4l2loopbackを導入しましょう。
まずはgit cloneしてmakeしてインストールしてください。

```
$ git clone https://github.com/umlaeute/v4l2loopback.git
$ cd v4l2loopback
$ make
$ sudo make install
```
次に、モジュールをロードします。このとき、特にchromeで認識させるためには、exclusive_caps=1をつけてあげる必要があるようです。[https://github.com/umlaeute/v4l2loopback/issues/78]

```
sudo modprobe v4l2loopback exclusive_caps=1
```
これでモジュールがロードされたと思いますので、デバイスファイルを確認しておきましょう。下記の例だとvideo2が追加されていますね。

```
$ ls /dev/video*
/dev/video0  /dev/video1  /dev/video2
```

##### ffmpeg
仮想ウェブカメラデバイスにデータを送り込むにはffmpegを用いるのが一番簡単です。
apt-getなどでさくっと導入しておいてください。

#### Webカメラのフックと映像の配信
今回は、笑顔を検出したら画像加工を施してみようと思います。
笑顔を検出したら、映像上に笑顔マークを表示します。

まず、次のリポジトリのファイルをcloneしてモジュールをインストールしてください。

```
$ git clone https://github.com/dannadori/WebCamHooker.git
$ cd WebCamHooker/
$ pip3 install -r requirements.txt
```

ここからcascadeファイルを入手します。cascadeファイルの詳細はopencvの公式でご確認ください。
https://github.com/opencv/opencv/tree/master/data/haarcascades

```
$ wget https://raw.githubusercontent.com/opencv/opencv/master/data/haarcascades/haarcascade_frontalface_default.xml -P models/
$ wget https://raw.githubusercontent.com/opencv/opencv/master/data/haarcascades/haarcascade_smile.xml -P models/
```

笑顔マークをいらすとやさんからお借りしましょう。

```
$ wget https://4.bp.blogspot.com/-QeM2lPMumuo/UNQrby-TEPI/AAAAAAAAI7E/cZIpq3TTyas/s160/mark_face_laugh.png -P images/
```

こんな感じのフォルダ構成になってるといいです。

```
$ ls -1
haarcascade_frontalface_default.xml
haarcascade_smile.xml
mark_face_laugh.png
webcamhooker.py
```

実行は次のように行います。
--input_video_num　には実際のウェブカメラのデバイス番号を入れてください。/dev/video0なら末尾の0を入力します。
--output_video_dev には仮想ウェブカメラデバイスのデバイスファイルを指定してください。
なお、終了のさせ方はctrl+cでお願いします。

```
$ python3 webcamhooker.py --input_video_num 1 --output_video_dev /dev/video2
```

上のコマンドを実行するとffmpegが動き、仮想カメラデバイスに映像が配信されはじめます。

#### ビデオチャットをしてみよう！
ビデオチャットをするときにビデオデバイスの一覧にdummy〜〜というものが現れると思うのでそれを選択してください。 これはTeamsの例。左右がそれぞれの参加者の画面だと思ってください。 左側が今回の仮想カメラデバイスを使っているユーザです。右側が受信側です。 ニッコリすると笑顔マークが出ますね。大成功(^_^)/。

![test.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365991/2f6478a6-4898-579c-c982-e9cba4831323.gif)


#### 最後に
対面のコミュニケーションが難しい今、ビデオチャットを使ってもっと楽しめたらいいですね。
今回は笑顔を検出して画像を加工する例で示しましたが、opencvやその他のツールを使って工夫次第でいろんな加工ができると思います。
ぜひいろいろ試してみてください！


#### 参考
opencvでの笑顔検出はこちらを参考にさせていただきました。
https://qiita.com/fujino-fpu/items/99ce52950f4554fbc17d

opencvでの画像貼り付けはこちらを参考にさせていただきました。
https://qiita.com/a2kiti/items/9672fae8e90c2da6f352