ゴール設定(道路標識の画像認識データを作る)
前回は、ラピロが自分で運転できる自動車を作った。自分で運転するなら、きちんとラピロのカメラで道路標識を認識して、自分で考えて運転すべきだ。今回も画像認識ライブラリOpenCVを使う。道路標識を認識するデータは、ダウンロードできるものだろうと思ってたけど、OpenCVのサンプルに入っている人の顔や目などの認識データ以外はあんまり無償公開されていない様子。じゃあ、適当に画像認識データを作ればいいんだな。と思って作業してみたんだけど、これが意外と大変だった。こことかのOpenCVの説明を読めばいいんだけど、右脳タイプの私はとりあえずやってみて覚える派。分からない事は後で調べる。ちらっと調べてみたところ、OpenCVの「Create Samples」プログラムで正解画像データを集めて、「Train Cascade」プログラムで機械学習して、その結果、カスケード識別器(haarcascade_xxxx.xmlの様なファイル)という画像を認識するための知識データファイルを出力するらしい。やってみよう。
やりたい事
ロボット頭部のカメラで画像を撮影して、例えばこの画像から「左折専用」とか「止まれ」とかの標識が存在することを検知させたい。
事前準備(ラズパイにインストールしたもの)
- Python 2.7
- OpenCV 3.3
事前準備(道路標識の画像データ)
検知したい標識を様々な角度、距離から撮影した。この正解画像を「ポジティブ画像」と呼ぶ。
事前準備(道路標識じゃない画像データ)
ロボットが運転しているときのカメラ画像を記録した。標識が無いのでこれをNGデータとした。「ネガティブ画像」と呼ぶ。
実験(OpenCV機械学習)
道路標識を検出するだけでは無く、この標識が「止まれ」、これが「右折専用」、こっちが「左折」という正解のポジティブ画像。そんでもって、これが道路標識が無い、不正解のネガティブ画像だよ。という具合にOpenCVのプログラムに教えてあげる。
OpenCVに教えてあげるために、画像をそれぞれのファイルフォルダに分けて保存する。
+ model(学習結果が保存されるフォルダ)
+ neg(ネガティブ画像のフォルダ)
+ pos0(止まれ画像のフォルダ)
+ pos1(左折画像のフォルダ)
+ pos2(右折画像のフォルダ)
機械学習を実行してカスケード識別器を作る。の手順概要。
手順1.ネガティブ画像のファイル一覧を、ファイルに出力する(nglist.txtとか)。
手順2.ポジティブ画像のフォルダから、ポジティブサンプルファイルを出力する(positive0.vecとか)。
手順3.学習して、カスケード識別器を出力する(trafic_stop_cascade.xmlとか)。
手順4.画像認識できるか実験してみる。
実験(道路標識を画像認識できるか?)
人物顔認識やったときみたいに、知識データにさっき作った道路標識の「カスケード識別器」3つ「止まれ」「左折」「右折」を指定する。プログラムを実行すると。
反省(失敗した理由)
画像認識の結果、道路標識を検知することは出来た。しかし、検知した物体の判定は「左折」「右折」の両方。OpenCVで使ったカスケード識別器は、特徴で物体を検出するため、左折も右折も同じ矢印や丸い看板という特徴を正しく検知したのだと思われる。思えば不正解のネガティブ画像は、道路標識が無い画像だよって教え込んだだけだった。
実験(機械学習をやり直し)
今度は、これは違う標識だよというネガティブ画像も追加(下図★)して、機械学習をやり直しする。
+ model0(止まれの学習結果が保存されるフォルダ★)
+ model1(左折の学習結果が保存されるフォルダ★)
+ model2(右折の学習結果が保存されるフォルダ★)
+ neg0(止まれ以外の画像フォルダを追加★)
+ neg1(左折以外の画像フォルダを追加★)
+ neg2(右折以外の画像フォルダを追加★)
+ pos0(止まれ画像のフォルダ)
+ pos1(左折画像のフォルダ)
+ pos2(右折画像のフォルダ)
この正解画像は「左折」だよ。こっちの「右折画像」は不正解だからね。って感じで再度学習。
実験(道路標識の種類を検知する)
今度は「左折」と「右折」の標識をきちんと検出することが出来た。「止まれ」も教えたので検出して欲しかったが、検出できなかったので、あとでやり直しする。
まとめ(分かったこと)
- OpenCVで検知する画像物体は、カスケード識別器というデータファイルが必要。標準でインストールされるのは人物や顔など。
- カスケード識別器(xxx_cascade.xmlの様なファイル)は、インターネットを探してもあまり見つからない。みなさん、公開していない様だ。
- OpenCVでインストールされる「opencv_createsample」と「opencv_traincascade」のプログラムで、カスケード識別器を作成できる。
- 検知したい画像物探1つにつき、1個のカスケード検知器が必要。止まれ、左折、右折で、ファイル3つ。
- ネガティブ画像は、似ている画像の不正解画像も教えること。これは「左折」、これは似ているけれど「左折以外(右折や止まれ)」だよ。
- 用意する画像は数百個と言われている。私は面倒だったので10個程度だったが、大雑把には検知できた。認識精度を高めるにはもっと多くのサンプルが要るのだろう。
次回は、作成した手順のプログラムを記録する