Stimulator

機械学習とか好きな技術話とかエンジニア的な話とかを書く

OpenCVとdlibとOpenFaceでの顔検出と知見まとめ

- はじめに -

色々あって顔検出をする機会があった。世の中、顔認識(Face Recognition,Facial Recognition)と顔検出(face detection)がごっちゃになってるじゃねえかと思いつつ、とにかく画像から人の顔を高精度で出したいんじゃという話。

先に結論を言うと、OpenCVよりはdlibの方がやっぱり精度良くて、OpenFaceも使って動かしたんだけどそんな変わらないし、でもまあ先はあるよって話。
OpenFaceで顔検出と言っても、実際にはdlib(もしくはOpenCV)の顔検出とTorch7のCNNを接続するフレームワークのようなもので何でこれが話題になった時期があったのかという感じがある。

環境はUbuntu 14.04を想定。

- インストールして動かすかれこれ -

まずは必要な物をインストールする。

厳しい環境に身を置いているので、最初WindowsOpenCVとdlibを動かした。Windowsでもインストーラとpipが使えれば出来るので奇跡的に出来た。時代は変わった。
OpenFaceはLinux, Unix環境しか対応してないとの事だったので、仕方なく仮想環境を作りインストールした。

環境は Ubuntu 16.04 LTS
必要なものは以下の通り

- python (Ubuntu デフォルトで可)
- python pip
- numpy
- scipy

- torch7 (機械学習, Deep Learningライブラリ)

- opencv
 - 必要な周辺ライブラリ沢山
 - cmake

- dlib
 - boost
 - boost-python
 - scikit-image

- openface

多い。OpenFaceの公式Setupには「Docker用意したから使ってくれよな」とあったけど、「"tested in Ubuntu 14.04 and OSX 10.10"」とも書いてあるし、OpenCVは先月3.x系が出てるしでダメそうだったので全部手動で入れた。インストール前にこの辺を読んで遺産感があるのに気付くべきだった。


- インストール作業 -

pythonUbuntuデフォルトで充分。一応バージョンを確認するけど大抵2.7系だと思う。

python -V

一応定番apt-getのアップデートをしておく

sudo apt-get update
sudo apt-get upgrade

パッケージ管理はやっぱりeasy_installとpip

sudo apt-get install python-setuptools
sudo apt-get install python-pip

pipを入れたらまずはこの三種の神器

pip install numpy
sudo apt-get install liblapack-dev libatlas-base-dev gfortran g++
pip install scipy
pip install matplotlib

先にOpenCVから導入。思い思いのディレクトリで。

wget http://downloads.sourceforge.net/project/opencvlibrary/opencv-unix/3.0.0/opencv-3.0.0.zip
sudo apt-get install unzip
unzip opencv-3.0.0.zip

必要な周辺ライブラリを全載せ

sudo apt-get install build-essential libgtk2.0-dev libjpeg-dev libtiff5-dev libjasper-dev libopenexr-dev cmake python-dev python-numpy python-tk libtbb-dev libeigen3-dev yasm libfaac-dev libopencore-amrnb-dev libopencore-amrwb-dev libtheora-dev libvorbis-dev libxvidcore-dev libx264-dev libqt4-dev libqt4-opengl-dev sphinx-common texlive-latex-extra libv4l-dev libdc1394-22-dev libavcodec-dev libavformat-dev libswscale-dev default-jdk ant libvtk5-qt4-dev

libtiffはUbuntu 14.04辺りからlibtiff5推奨になったらしいlibtiff4-devはエラーが出た。

cmakeを準備しつつコンパイル

sudo apt-get install cmake
cd opencv-3.0.0
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D WITH_TBB=ON -D BUILD_NEW_PYTHON_SUPPORT=ON -D WITH_V4L=ON -D WITH_FFMPEG=OFF -D BUILD_opencv_python2=ON .
make -j1
sudo make install

make -jの後は自分のコア数を入れる。
Linuxだと一番簡単なコマンドは多分 nproc と打つ事。
今回は仮想環境なので1。

python用の設定はopencvのlib内にあるcv2.soというファイルをsite-packages以下に入れるだけ。GUIでやってもOK。

cp ~/ path to opencv /opencv-3.0.0/lib/cv2.so /usr/local/lib/python2.7/site-packages/

Linux系だとcv2用にリンクを貼っておく必要がある。
でないと" libdc1394 error: Failed to initialize libdc1394 "といったErrorが出る、

sudo ln /dev/null /dev/raw1394

python起動してimportできるか確認しておく

python
>>> import cv2
>>> cv2.__version__
'3.0.0'
>>> exit()

次はdlib。
dlibは前提としてgitが要るので先にそちらを準備しておく。

sudo apt-get install git

加えて前提として必要なskimageとライブラリ

sudo pip install cython
sudo pip install scikit-image

確かdlibはpipで入れれば下記作業不要だけど、結局OpenFaceを入れる前にTorch7が必要で、その前提としてboostが必要みたいな感じで入れた気がする(曖昧)。
多分pipで入れても" Could NOT find Boost "なるエラーが出ると思うのでやったら吉。

sudo apt-get install python-dev python-numpy
sudo apt-get install libboost-dev
sudo apt-get install libboost-python-dev
sudo apt-get install libboost-system-dev

boost.numpyのインストールは他に作業が必要だけど今回は無用
一応やりたい人向け参考URL(http://ttlg.hateblo.jp/entry/2015/12/17/124747

多分これでdlibは入る(Windowsもboostインストーラとpipが動くのでここまではできる)

sudo pip install dlib

python起動してimportできるか確認しておく

python
>>> import dlib
>>> dlib.__version__
'18.17.100'
>>> exit()

次にTorch7を入れる。

git clone https://github.com/torch/distro.git ~/torch --recursive
cd ~/torch
sudo dpkg --configure -a
bash install-deps
./install.sh

インストールの文字が最後に
Do you want to automatically prepend the Torch install location to PATH and LD_LIBRARY_PATH
と聞いてくるので yes と入力するると .bashrcにexportが追記される。
一応 source ~/.bashrc するかbashを再起動しておく。

witch thでpathが出て来ればOK。出てこない場合はPathを設定する。
~/.bashrcを開いて

export PATH=~/torch/bin:$PATH;
export LD_LIBRARY_PATH=~/torch/lib:$LD_LIBRARY_PATH;

を追記する。

Torchにはluaのパッケージが幾つか用意されていて、今回のサンプルを動かすのに必要な物があるのでインストールしておく。

luarocks install nn
luarocks install dpnn
luacocks install optim
luarocks install csvigo

lualocks installでインストール推奨とされているのは以下があるけど、ディープラーニングのトレーニングやCUDAを使う場合のみなのでインストールしてない。
必要そうだと判断したらインストール
cutorch and cunn (only with CUDA)
fblualib (only for training a DNN)
tds (only for training a DNN)
torchx (only for training a DNN)
optnet (optional, only for training a DNN)

上のやつを全乗せしたい時

for NAME in dpnn nn optim optnet csvigo cutorch cunn fblualib torchx tds; do luarocks install $NAME; done

Torch7で使うluarocksだと、無難に以下をインストールしておくと良い。

luarocks install image
luarocks install nngraph

やっとOpenFace

git clone https://github.com/cmusatyalab/openface ~/openface --recursive
cd ~/openface
sudo python setup.py install

無事通れば終わり


- サンプルを動かす -

サンプルとして提示されてるのは以下のcompare.py
https://github.com/cmusatyalab/openface/blob/master/demos/compare.py

まず前提としてdlibの顔検出用のlandmarks.datファイルを用意する
自前で用意しなくても、modelsディレクトリにスクリプトが入っているので基本はそれで。

cd ~/openface/models
./get-models.sh

~/openface/の中に好きなsample.jpgとsample2.jpgを突っ込んで

python demos/compare.py ./sample.jpg ./sample2.jpg --verbose

って感じで入力して実行。--verboseでは動作詳細を見れる。

サンプルは「顔の場所を検出してcropして学習済みネットワークで特徴量化しそのベクトルのL2距離を比較する」というもの。
本家は「"OpenCV or dlib"」と言っているが、この推奨サンプルではcv2の画像読み込みでロードして顔検出精度が高いdlibで顔検出しているので「dlibもOpenCVも結局どっちも要るじゃねえか!」となる。

なんかそれっぽい数値が出たら終わり
正直もっと良いサンプルあるやろと思う。


- 感想 -

OpenFaceだけど、Deep Netなら他の便利なフレームワークがある印象が強い。dlibやOpenCVと簡易的に接続できると言っても、最近は他が簡易的になったし。
APIOpenFace API Documentation — OpenFace API Docs 0.1.1 documentation)を見てもそんな便利な機能があるわけではない。

Deep LearningライブラリとdlibやOpenCVが個別で扱える事のメリットの方が大きいかなと思った次第。

Torch7で顔の分類や回帰を行っている。その学習済ネットワークがある、または入手できる。といった状況以外ではあまり使わなそう。
海外だとTorch7結構流行ってるのかなと思ったところで終わり。正直chainerやkerasが良いと思うよ正直。

記事を書くなら精度検証しろよとも思うけど、やっぱ所感でdlibが良い程度しか言う事がない。
dlibはHoG+SVMを使っているらしく、OpenCVはHaar-Like+Adaboostを使った物体検出系のカスケードらしい。
どちらもデフォルトだとSliding Windowやってるみたいで、dlibの方はSelective Searchとかも使えるけど顔検出だと微妙なのではと思う。
dlibの方が精度が良いのは目視した感じ確かだけど、Window走査の時間設定のパラメータ(upsample_num_times)を最小の0以外にすると処理時間が長く、2以上だと+メモリが必要だった。適当な仮想環境では落ちる程度に重かった。あと2以上にしてもそんな大胆に精度改善が見込める訳ではない。
OpenCVの方が遥かに軽いし、OpenCVでググってると「ここに乗ってるAdaboostを使った検出器はクソ早いし最高なんだ!Viola & Johnsが作ったスゲーやつなんだ!」と書いてあったりする。OpenCVはデフォルトのカスケードファイルがいくつかあって、顔だけじゃなく、目や耳用があったりする(全て実験してる人の記事:OpenCV 使用可能なCascadeClassifierの種類と効果 - Symfoware)。その辺は有効活用できそう。追加での学習もできるっぽい。

顔認識本当にやるならOpenCVとdlibを組み合わせてある程度データを作り、ちゃんと特徴量と学習器作ったりDeep Netにぶち込むのが良いんじゃないかと思った。

もう少しdlib使ってみたら日本語の記事増やしたいので書くかも。後はGoogle Cloud APIの顔認識も気になってはいる。

あと、「顔検出」とかでググるとオタクがとりあえずアニメ画像認識やってみたって感じのブログが山のように出てくるので日本語でググるよりは英語を乗り越えて公式のドキュメント理解に努めたほうが良いかも。