サリーの顔を識別させる

ロボット用のcomputerであるraspberrypi3にインストールしたopencvには、人の顔や瞳を自動で認識する識別器がすでに付属している。それは大変便利で、raspberrypiに接続したカメラで、すぐに識別が可能になる。

もし、サリーの顔が識別できれば、ロボットはサリーに向けて自動で近づいたり離れたりできるようになる。これはとても便利だ。しかし、opencv付属の人の顔の識別器では、サリーの顔を識別できないことがわかった。だから、サリーの顔を識別する識別器を自作した。

参考にさせていただいたサイトは、こちらである。

今後、サリー以外の物体認識にも使いたいのでメモしておく。

(1)positive画像とnegative画像:検索画像のダウンロード
フリーのツールはたくさんあるので、なんでもいいと思うが、私は、こちらのを使わせていただいた。どのサイトか、使えないサイトもあったが、特に大きな問題はなかった。このダウンロードソフトを使って、ワードをrobot naoで検索して得られた画像、positive画像約650枚ほどを使った。ただし、gifは使えない、pngは使えるのかもしれないが、削除したので100枚ほど少なくなった。jpgは、jpegとしてもJPGと拡張子が違っていてもOKのようだ。
naoの顔が入っていないnegative画像も、このソフトで、確か「人形 部屋」とかいう検索をかけてダウンロードして、500ほどで打ち切った。

(2)顔画像の位置の指定
positive画像のそれぞれについて、naoの顔がある位置を指定するのがとても面倒だった。600枚ほどの位置指定に3,4時間かかったような気がする。TrainingAssistantというフリーのソフトを使わせていただいた。超便利だった。指示通りにアプリを組み込む。そして、先ほどダウンロードした画像を、上記サイトに指示されているフォルダーに放り込む。
% python views.py
で、自前のウェッブサーバーを立ち上げて、ブラウザで
http://localhost:5000
を表示させると、画像が順番に出てくるので、naoの顔の部分の座標をマウスをスライドさせて指定する。それらは、info.datファイルに次のような感じで自動的に保存される。
static/img/Nao_robot.jpg 1 434 2 316 271
static/img/29437446525_059b230e13_z.jpg 2 324 93 86 67 219 148 38 30
・・・・・・
最初が画像のパスで、次がその画像の中の顔の数、そして座標とサイズである。

(3)positive.datとnegative.datの作成
画像リストデータファイルを作成する。positive.datは、新しい場所に置き換えた場合も元々の場合も、そのフォルダーの絶対パスを冒頭のパスに全て書き換える。私の場合は、次のステップのvectorファイルの作成が、macではうまくいかず、raspberrypi に全部移したので、そちらのパスに書き換えた。negative.datは、単にその画像のある絶対パスのリストで良い。

(4)positiveベクトルの作成
Macのopencvでは、opencv_createsamplesがうまく機能しなかった。原因は不明。で、raspberrypiのopencvで作成することにした。linuxmintでもよかったかと思う。どのosのopencvでもいいのだ。
Raspberrypiのopencvは、cameraを使用する関係で、少し手の込んだインストールが必要で、。次のサイトに基づいている。
https://qiita.com/NaotakaSaito/items/f1f1548c8b760629cd26
あとは、positive.datが置いてあるフォルダでopencv_createsampleコマンドを実行すればいい。私の場合は次のようにした。
opencv_createsamples -info positive.dat -vec positive.vec -num 574 -w 40 -h 40
-numは、positive画像数である。-w 40 -h 40は、ベクトルサイズらしく、よくわからない。ただ、認識対象の映像の中で最小認識可能な画像サイズと考えればいいようだ。私の場合、画像サイズを、3320X240にしているので、その中で、顔が最小限どのくらいのサイズで映った時に認識して欲しいかという基準でやったが、もっと大きくてもいいかもしれない。(その後、60X60でやってみた。この60X60の方がnaoの顔を安定して識別しつずける可能性があるように思えた)

(5)学習器の作成
私の場合のコマンドは次のようになった。
opencv_traincascade -data /home/pi/Project/ObjectRecognition/data/model -vec /home/pi/Project/ObjectRecognition/src/positive.vec -bg /home/pi/Project/ObjectRecognition/src/negative.dat -numPos 450 -numNeg 400 -featureType HOG -maxFalseAlarmRate 0.1 -w 40 -h 40 -minHitRate 0.97 -numStages 17
絶対パスで指定しなくても良いかと思う。
途中までやったのは生かされる。

最終の出力は以下のようである。
---------------------------------------------
Training parameters are pre-loaded from the parameter file in data folder!
Please empty this folder if you want to use a NEW set of training parameters.
--------------------------------------------
PARAMETERS:
cascadeDirName: /home/pi/Project/ObjectRecognition/data/model
vecFileName: /home/pi/Project/ObjectRecognition/src/positive.vec
bgFileName: /home/pi/Project/ObjectRecognition/src/negative.dat
numPos: 450
numNeg: 400
numStages: 17
precalcValBufSize[Mb] : 1024
precalcIdxBufSize[Mb] : 1024
acceptanceRatioBreakValue : -1
stageType: BOOST
featureType: HOG
sampleWidth: 40
sampleHeight: 40
boostType: GAB
minHitRate: 0.97
maxFalseAlarmRate: 0.1
weightTrimRate: 0.95
maxDepth: 1
maxWeakCount: 100
Number of unique features given windowSize [40,40] : 100

Stages 0-4 are loaded

===== TRAINING 5-stage =====

Training until now has taken 0 days 0 hours 7 minutes 23 seconds.

===== TRAINING 6-stage =====
<BEGIN
POS count : consumed 450 : 522