特定画像認識
Categories:
目的
前回の講義で扱ったARマーカー認識は,簡単かつ高精度にARマーカーを検出,さらには位置及び姿勢を認識できる便利なパッケージです. しかしながら,物体にARマーカーを貼ることができない場合には利用することができません. このような場合には,一般環境下で撮影した画像から認識したい物体を見つけるという処理が必要です. 今回はfind_object_2dパッケージを使用し,画像から所望の物体を検出します.
find_object_2dを用いた物体認識
find_object_2dパッケージでは,カメラで撮影した画像(入力画像)から予め用意した画像(テンプレート画像)を見つけることができる便利なパッケージです. 検出アルゴリズムは,入力画像及びテンプレート画像から注目画素周辺の領域に多くの濃淡情報を持つ特徴点(キーポイント)を検出し,特徴点周辺の領域から濃淡情報を数十から数百次元のベクトルとして数値化した記述子を抽出します. そして,2枚の画像から計算した記述子の類似度を求めることでキーポイントを対応づけます. これにより,入力画像中のどこに,どのぐらいの大きさでテンプレート画像が存在するかを認識できます. また,特長として画像の回転やスケール変化に不変,照明変化等にも頑健です.
SIFTに代表されるような特徴点の検出や記述の方法はSURF,FAST,BRIEF等があります. ここでは詳細なアルゴリズムの説明は省略します,気になる方は論文や解説記事を参考にしてください. find_object_2dパッケージでは画像処理ライブラリであるopencvに実装されているアルゴリズムを利用しています.
インストール
find_object_2dパッケージをインストールします.
|
|
実行
find_object_2dを実行する前にROS2でカメラを使えるようにします.
|
|
次に,find_object_2dパッケージのノードを起動します. こちらのノードでは画像データを/imageという名前で購読する必要があるため,ノードを起動する際にトピック名を変更します.
|
|
上記のコマンドを実行すると下記のようなウィンドウが起動します.
画面左がテンプレート画像(初期の状態では空です),右がカメラから取得した画像です. 画像中の黄色い点はキーポイントを表します. テクスチャ(模様)の情報が多いトランプの絵柄から多くのキーポイントが検出できていることが確認できます.
画像中からクローバの13のカードを検出するためにテンプレートを登録します.
画面左のObjects
と書かれた領域で右クリックすると,メニューが表示されます.
今回は画像に写ったトランプをテンプレートとするため,Add object from scene...
を選択します.
テンプレートを登録する小さなウィンドウが表示されます.
登録したいものが写った状態でTake picture
をクリックしてください.
映像が停止して,Take picture
をクリックした瞬間の画像が表示されます.
テンプレートとして登録した領域をドラッグし,Next
をクリックしましょう.
ドラッグした領域が表示されます.
ドラッグした領域に複数のキーポイントが含まれているか確認してください.
キーポイントの数が多ければ多いほど,安定した検出ができるようになります.
問題なければEnd
をクリックします.
画面左に登録したテンプレートが表示され,画面右の映像からテンプレート画像を検出します.
下記の画像の場合,
12
は物体のID,括弧内の100
はキーポイントの数,
68
はマッチングしたキーポイント数,109
マッチングしなかったキーポイント数を表しています.
マッチングしたキーポイント数が多いほど正確に検出できるため,画面右の検出枠が安定します.
初期の状態では,SIFTと呼ばれる特徴点検出,特徴量記述子を用いて画像を認識するように設定されています. SIFTは,画像の回転やスケール(大きさ),明るさの変化に対応できるため,トランプの位置を変えても安定した検出されます.
また,一部分が隠れても幾つかのキーポイントが検出されれば,画像を認識することが可能です. ただし,マッチングしたキーポイントの位置関係から位置と大きさを推定するため, マッチングしたキーポイントの数が少ないと認識結果が不安定となります.
ノードとトピックの確認
コマンドラインツールを利用してノードやトピック等の情報を確認しましょう. まずはノードを確認します.
|
|
カメラから画像を取得するノードが/usb_cam
,画像認識を行うノードが/find_object_2d
となります.
ノード名が分かったのでノードの情報を確認します.
|
|
/find_object_2d
はカメラから取得した画像トピック/image_raw:
を購読し,
複数のトピックを配信していることがわかります.
認識結果は/objects
という名前のトピックで配信されています.
トピック/objects
のメッセージ型を調べてみましょう.
|
|
このメッセージ型が配信する情報を調べます.
|
|
少し分かりにくいですが,認識結果はdata
に入ります.
最後にトピックをコマンドラインツールで購読します.
|
|
テンプレート画像を認識すると上記のようにトピックが確認できます. dataの中は順番に,物体のID,認識物体の横方向の大きさ(画素数),縦方向の大きさ,3x3のホモグラフィー行列となります. ホモグラフィー行列は平面を射影変換するための行列です. ホモグラフィー行列により認識した物体(認識した物体の矩形)の変形度合いを表すことができます.
コマンドラインツールで調べた情報を利用して,作成したシステムに組み込むことができます.
GUIを使わない方法
上記の方法で特定の画像を認識することが可能ですが,GUI操作を伴うとシステムに組み込むことが難しくなります.
find_object_2dでは,パラメータを設定することでGUIを使わずに動作させることができます.
GUI操作によるテンプレートの登録ができないため,事前に登録した状態のセッション情報をGUIで保存しておき,実行に引数でセッション情報を与えます.
具体的には,session_path
というパラメータにセッションファイル(今回はcard.bin),gui
というパラメータにfalse
を与えます.
|
|
ウィンドウにより認識結果を確認することができないため分かりにくいですが,先ほどと同様にtopic echo
により認識結果を確認することができます.