OpenFaceを試しに触れてみる

# OpenFaceとは
顔の座標点や視線推定，頭の姿勢推定，Action Unitの強度やバイナリなどを抽出する顔解析ツール．

詳しい内容はこちらの論文を参照してください．
https://www.cl.cam.ac.uk/research/rainbow/projects/openface/wacv2016.pdf
# OpenFaceを試すための手順（概要）
OpenFaceを試すために，Dockerを用いたやり方について説明していきます．
※Dockerを用いなくてもできますが，環境設定がとても大変だと思います．

以下の手順で進めていきます．
※Dockerを既にインストールしている方は2から始めてもらって問題ないです．

1. Dockerをインストール
2. OpenFaceを試す

今回試した環境は以下の通りです．
OS: Ubuntu 18.04 LTS
CPU: i3-4130 3.40GHz
メモリ: 16GB
# 1. Dockerをインストール
Dockerのインストールはこちらの記事が分かりやすかったです．
https://qiita.com/myyasuda/items/cb8e076f4dba5c41afbc

Dockerをインストールして，versionが確認できたらおｋです．
# 2. OpenFaceを試す
まず，端末を開いて以下のコードでDockerを立ち上げます．

```:端末1
$ docker run -it --rm algebr/openface:latest
```

最初にこのコードを入力すると，DockerのimageをDownloadするので少し時間がかかると思います．

次にもう1つ端末を開いてDockerのCONTAINER IDを確認します．

```:端末2
$ docker ps
CONTAINER ID        IMAGE                    COMMAND             CREATED             STATUS              PORTS               NAMES
f5fb6414204f        algebr/openface:latest   "/bin/bash"         11 seconds ago      Up 10 seconds                           clever_taussig
```


確認できたら，適当なサンプルを用意して以下のコードを実行します．
※今回はOpenFaceのsamplesにあったsample1.jpgファイルを使用しています．必要があれば適宜こちらからDownloadしてください．
https://github.com/TadasBaltrusaitis/OpenFace

```:端末2
$ docker cp sample1.jpg f5fb6414204f:/home/openface-build
```
ここで大切なのが，自身のCONTAINER IDと対応付けを行うことを意識してください．

次にDockerを立ち上げた端末に戻って，以下のコードを実行します．

```:端末1
$ build/bin/FaceLandmarkImg -f sample1.jpg
```

成功したら，「processed」というディレクトリが出来ているので，もう1つの端末に戻ってcsvやjpgファイルを自身の環境にコピーしてやります．

```:端末2
$ docker cp f5fb6414204f:/home/openface-build/processed/sample1.csv .
$ docker cp f5fb6414204f:/home/openface-build/processed/sample1.jpg . 
```
※この状態だと元々のsample1.jpgが上書きされるので，必要があれば適宜名前を変更してください.

結果はこんな感じです.
sample1.jpg
![sample1-result.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472706/be8eaba2-9d1c-1418-e5c9-e5758b991557.jpeg)

# おまけ
先程は画像を取り上げましたが，動画でも動くようです.

```:端末1
$ build/bin/FaceLandmarkVidMulti -f multi_face.avi
```
※私が実行したときは「FaceLandmarkVid」ではうまく出来なかったので，「FaceLandmarkVidMulti」を取り上げています．1人だけでもマルチで問題なく出来たことを確認しました．

# 追記 2019/9/19
上記のやり方だといちいち「docker cp」をしないとファイルが送れない（厳密に言えばコピー）ので，dockerのマウントを利用するやり方を紹介します.
これをすると「ホスト側のディレクトリ」と「コンテナ側のディレクトリ」を繋ぐことができ，大変便利です．

```:端末1
$ docker run -v $PWD:/tmp -it --rm algebr/openface:latest
```
■説明
「-v」...マウントオプションのこと
「$PWD:/tmp」...ホスト側のディレクトリパス：コンテナ側のディレクトリパス

今回の場合だと、dockerを起動した[カレントディレクトリ]とコンテナ側の[tmp]を共有させています．

# おまけ2 2019/9/19
OpenFaceの場合に限りますが，以下のコードで共有フォルダをdocker上のカレントディレクトリに作成することが出来ます．

まずはホスト側のカレントディレクトリにあるものを確認します．

```:ホスト側
$ ls
Actor_01  sample.py  test10.csv
```
確認できたら，dockerを起動します．
共有ディレクトリは「mount」です．

```:ホスト側
$ docker run -v $PWD:/home/openface-build/mount/ -it --rm algebr/openface:latest
```

docker上でフォルダを確認します．

```:コンテナ側
$ ls
CMakeLists.txt  build  cmake  exe  lib  mount
```

mountディレクトリがあればおｋです．
一応中身を確認しておきます．

```:コンテナ側
$ cd mount/
$ ls
Actor_01  sample.py  test10.csv
```
最初にあったもの「Actor_01，sample.py，test10.csv」があったのでちゃんと共有できていました．

# 参考文献
https://qiita.com/nonbiri15/items/d9be1bd4baeaa2e8ab61
https://github.com/TadasBaltrusaitis/OpenFace/wiki#quickstart-usage-of-openface-with-docker-thanks-edgar-aroutiounian
https://github.com/TadasBaltrusaitis/OpenFace
https://qiita.com/nekkoneko/items/21784837a6434c160ebe
https://noumenon-th.net/programming/2019/03/30/docker-v/
https://webdesign-manga.com/docker_run_option/