前回は、ラピロが自分で運転できる自動車を作った。自分で運転するなら、きちんとラピロのカメラで道路標識を認識して、自分で考えて運転すべきだ。今回も画像認識ライブラリOpenCVを使う。道路標識を認識するデータは、ダウンロードできるものだろうと思ってたけど、OpenCVのサンプルに入っている人の顔や目などの認識データ以外はあんまり無償公開されていない様子。じゃあ、適当に画像認識データを作ればいいんだな。と思って作業してみたんだけど、これが意外と大変だった。こことかのOpenCVの説明を読めばいいんだけど、右脳タイプの私はとりあえずやってみて覚える派。分からない事は後で調べる。ちらっと調べてみたところ、OpenCVの「Create Samples」プログラムで正解画像データを集めて、「Train Cascade」プログラムで機械学習して、その結果、カスケード識別器(haarcascade_xxxx.xmlの様なファイル)という画像を認識するための知識データファイルを出力するらしい。やってみよう。
ロボット頭部のカメラで画像を撮影して、例えばこの画像から「左折専用」とか「止まれ」とかの標識が存在することを検知させたい。
検知したい標識を様々な角度、距離から撮影した。この正解画像を「ポジティブ画像」と呼ぶ。
ロボットが運転しているときのカメラ画像を記録した。標識が無いのでこれをNGデータとした。「ネガティブ画像」と呼ぶ。
道路標識を検出するだけでは無く、この標識が「止まれ」、これが「右折専用」、こっちが「左折」という正解のポジティブ画像。そんでもって、これが道路標識が無い、不正解のネガティブ画像だよ。という具合に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(右折画像のフォルダ)
この正解画像は「左折」だよ。こっちの「右折画像」は不正解だからね。って感じで再度学習。
今度は「左折」と「右折」の標識をきちんと検出することが出来た。「止まれ」も教えたので検出して欲しかったが、検出できなかったので、あとでやり直しする。
次回は、作成した手順のプログラムを記録する