実世界にある複数の物体を認識し,その位置や姿勢を計測するしくみを作るのはそれなりに面倒です. ARToolKitを使えば,Webカメラと紙に印刷したマーカを使って安価に位置計測システムを構築できますが, マーカを登録したり,それを認識できるようなコードを書くのにちょっと手間がかかります. ここで紹介する「QPToolkit」は,その「手間」を最小限にするために作られました. QPToolkitは,ARToolKitをベースに作られた位置計測フレームワークです. Webカメラを使ったID認識,2次元/3次元の位置姿勢計測をより簡単に行うことができます. 計測データはTCP/IP経由でやり取りされるしくみになっているので,あなたのメインプログラムは C/C++,Java,Flash,Processing,Python,Rubyなど,あなたがいちばん好きな言語で作ることができます. ここではQPToolkitを配布し,その機能と使い方を紹介します. (公開:2010年08月28日/最終更新:2011年1月5日)
|
目次
QPToolkitとは
QPToolkitは,Webカメラと紙に印刷されたマーカを使って,ID認識と2次元・3次元の位置姿勢計測が簡単に行えるフレームワークです. ARToolKitをベースに作られていますが,完全に位置計測に特化したもので,カメラ画像とCGの合成機能などはありません.
使うのはPC,Webカメラ,マーカの3つ!
QPToolkitは「Quick Position Toolkit」の略です. 「すぐに位置計測できるインフラを提供する」という意味がこめられています. もともと,私が自分の研究用(ロボットの位置計測)に作った道具なのですが,内輪の評判がよかったので公開することにしました. これを使うと,マーカ認識に関するコードで悩むことなく,本題に入れるので,特にプロトタイピングの 段階で威力を発揮します.そんなわけで,「QP」には「Quick Prototyping」という意味もこめられています.
QPToolkitの利用イメージ
QPToolkitでは,「QPServer」と呼ばれるサーバプログラムを使用します. QPServerは,カメラから得たリアルタイムのビデオ画像からマーカを認識し,そのIDや位置情報をTCP/IP経由で放流します. このQPServerと,それに関連するライブラリ(開発中)を含めた全体をQPToolkitと呼んでいます.
QPServerの使い方は簡単です.ネットワークに接続されたコンピュータを1台用意して,そこにWebカメラを挿し,そこでQPServerを起動するだけです. あとはネットワークに接続されたさまざまな機器がそのコンピュータにアクセスして,マーカの位置計測情報を得ることができます. データの受け手はTCP/IP通信ができるものならば何でもよく,スマートフォンやiPad,マイコン(例えばArduinoのイーサネットシールド)などでも 利用することができます.もちろん,QPServerを動作させているコンピュータとデータを受信するコンピュータを同じものにすることも可能です.
QPToolkitの利用イメージ
QPServerの外観と特徴
QPServerには以下のような特徴があります.
- カメラで撮影することによって簡単にマーカの登録が行えます(手描きマーカもOK)
- マーカはARToolKit互換
- マーカには英数字の名前をつけることができます
- マーカは個別に違うサイズを用いることができます
- マーカの登録と削除が簡単に行えます
- マーカ認識のする・しないをマーカごとに設定することができます
- 出力したいデータ項目を選択することができます
- データの放流の仕方は「完全自動」と「コマンド受け付けによる方法」の2種類が選べます
画面左側のエリアがマーカのパターンを登録したり,名前やサイズの情報を編集したりする場所です. 画面右側のエリアが,データを放流する“サーバ機能”に関するセッティング項目です. 画面中央にあるのは,放流するデータのフォーマットに関するセッティングです.名前や画像上の2次元の座標値, 空間中の3次元の座標値などいろいろありますが,好きなものを選ぶことができます.
QPToolkitで何が作れるか
QPToolkitを使えば,実世界にあるものにマーカを貼り付けて,そのIDや位置・方向を手軽に計測することができます. 移動物体やロボットの位置計測はもちろん,カード状のインタフェースやタンジブルインタフェースを作るときに役立ちます.
例えば,机の上にある箱や缶にマーカを貼り付けて,それをボリュームやスライダに見立ててみたり, マーカを並べてフェーダを作ってみたり,表にYES,裏にNOのマーカが描かれたカードを作り,それを コンピュータやロボットに見せて合図を出したり,という使い方が考えられます.
QPToolkitはシステム構築のプロトタイピング段階から最終段階まで活用することができます. 実際にQPToolkitを使用してシステムを作成した事例を以下でご紹介します.
AirSketcher
ユーザの意図通りに風の送り方をコントロールできるインタラクティブな扇風機のシステムです. 手持ちのマーカや据え置きのマーカを使って,送風ルートや場所ごとの風の強さを指示することができます. 扇風機にカメラが内蔵されており,指示用のマーカのIDと位置を認識する仕組みになっています.
- 渡邊恵太, 松田聖大, 稲見昌彦, 五十嵐健夫, AirSketcher: 風を使いやすくする手法の提案とその実装, WISS2010論文集, 2010.(図は論文より引用)
DrawerFinder
収納箱から物を出し入れをする様子を,棚の上に取り付けられたカメラで撮影し, その写真を使って物探しを支援するシステムです.撮影した写真はWebで閲覧することができます. 収納箱にはマーカが取り付けられており,撮影した写真と箱の番号および位置が関連付けられる 仕組みになっています.
- 小松崎 瑞穂,塚田 浩二,椎尾 一郎, DrawerFinder:収納箱用物探し支援システム, WISS2010論文集, 2010.(図は論文より引用)
QPServerのインストールと起動方法
QPServer ver.1.06(2.03MB,2011/1/4) |
QPServer ver.1.05(2.02MB,2010/11/29 安定版) |
QPServer ver.1.01(2.02MB,2010/8/28) |
上記のリンクからダウンロードしてください.現在Windows版のみです. ファイルを解凍したら出てきたフォルダを適当な場所(C:\Program Filesなど)に移動してください.デスクトップでも結構です. Webカメラをコンピュータに接続し,他のソフトウェアがWebカメラを使っていないことを確認したら,QPServer.exeを起動してください.
もしエラーが出たら
もし起動時に,「このアプリケーションが構成が正しくないため、アプリケーションを開始できませんでした」というエラーがでたら, 「Microsoft Visual C++ 2008 再頒布可能パッケージ (x86)」 のページにアクセスして,「ダウンロード」と書かれたボタンを押してソフトウェアをダウンロードし,インストールしてください.
マーカの登録
初期状態では,マーカは登録されていません.なので,最初にマーカを自分でデザインして,QPServerに登録する作業を 行います.QPToolkitで用いるマーカは,ARToolKitで使うマーカと互換性があります. マーカのデザインに関するルールは,このページの下のほうで説明しています.
パターンのキャプチャ
画面左側にある「Pattern Capture」というボタンを押してください.カメラ画像を表示するウィンドウが表示されます. カメラに認識したいマーカを見せると,マーカ(と思われる場所)に黄色い枠線が表示されます. このとき,マウスカーソルをその黄色い枠線の中に合わせると,その領域が選択され赤い枠線になります. この状態で,マウスを左クリックすると,リストにマーカが追加されます.
枠線とは別に,マーカの中央から飛び出ている線は,マーカの上方向を示しています. カメラを傾けると,この線が出る方向は変化します.自分が「上」と定義したい方向に この線が向いているときにクリックするようにしてください. マーカをテーブルなどの平らな場所において,カメラを正面右方向に少し傾けて撮影するとうまく撮れます. 撮影を終了するには,画像を表示しているウィンドウの×ボタンを押してください.
マーカの登録はマウスでクリック一発!
名前とサイズの変更
リストからマーカを選択すると,上にそのマーカの画像とパラメータが表示されます. 名前は英数字(または記号)で入力してください.サイズ(width)はマーカの外側の辺の長さです. これは実寸(ミリメートル単位)なので,実際に定規で測って値を入力してください. この値は3次元位置計測を行うときに必要なもので,それをしないときは適当でも問題ありません. 入力フォームにデータを入れて「Update」ボタンを押すとデータが更新されます.
マーカの情報の編集
マーカの削除と認識のOn/Off
マーカのデータを削除したいときは,リスト上で右クリックして「Remove this pattern」を選びます. マーカを個別に認識するかしないかを切り替えることもできます.リスト上でチェックマークが ついているものは認識がOnになっています.チェックをはずせばOffになります.
サーバ機能の使い方
サーバ動作の開始方法
Port番号とModeを設定したら「Start」ボタンを押します.止めたいときは「Stop」ボタンを押します. 「このプログラムをブロックし続けますか?」というWindowsの警告が出たら「ブロックを解除する」を選んでください. セキュリティソフトの警告が出た場合も,ブロックしない(通信を許可する)にしてください. 「Show preview window」にチェックを入れるとカメラ画像が表示されます. 画像を表示しているウィンドウを閉じてしまったときはこれを再度チェックしてください.
サーバ動作中のプレビューウィンドウ
「Automatic Mode」は完全自動でデータを放流するモードです.「Command Mode」は,クライアントからの コマンドが来たときに,それに応じてデータを返すモードです.通常は「Automatic Mode」で構いません. 出力結果は画面下のOutputのところに表示されます.
データの受信テスト
受け側のコンピュータで,telnetを使ってサーバからのデータを受信してみましょう. telnetはOSに標準搭載されています.Windowsであれば,スタートボタンから「ファイル名を指定して実行」を 選択して「telnet」と入力します.Macであれば,ターミナルを起動し,「telnet」と入力します. telnetが起動したら,サーバのIPアドレスとポート番号を入力してサーバに接続します. 「Num=」で始まるデータが流れてきたら成功です.
telnet> open 192.168.32.136 55555 Num= 0 Num= 0 Num= 0 Num= 1 P000,304,315
QPServerが放流するデータ
QPServerはカメラで撮影した毎フレームの画像の認識結果をテキストデータで放流します. 例えば,マーカの名前とカメラ画像上の2次元位置を出力しているときに, 2つのマーカを認識したならば,以下のようなデータが流れてきます.
Num= 2 P000,304,315 P001,220,342
1行目に「Num= ?」というフォーマットで検出されたマーカの数を出力します. それに続いて,1行ごとに1つのマーカのデータをコンマ区切りで出力します. 何のデータを出力するかはチェックボックスで選択できます.
QPServerで出力するデータのフォーマット
QPServerからデータを受信する方法 (Processingでのコーディング例)
データの受信と切り出し
QPServerが動いているサーバのIPとポート番号を指定してTCPソケットを繋ぎます. QPServerからデータを受信する際の基本的な戦略は,行単位でデータを受信し,それを解析するというものです. まず"Num="を含むデータかどうかを判定し,含んでいればマーカの検出数を取得します. その後,マーカの検出数の数だけ行単位でデータを受信します. データは「,」区切りになっているので,「,」をトークンとしてデータの切り出しを行います. Processingであればsplit()という関数でデータの切り出しが行えます.
Processingでのコーディング例
Processingでのコーディング例を紹介します. Processingはコンパイルなどを行うことなく,サクッと動かせるのでテストに適しています. 以下は検出したマーカの位置を,画面上に点で表示するだけの簡単なプログラムです.
import processing.net.*; Client myClient; void setup() { size(640, 480); frameRate(30); colorMode(HSB,100); myClient = new Client(this,"192.168.32.137",55555); // IPとポート番号 } void draw() { background(0); if (myClient.available() > 0) { String dataIn = myClient.readStringUntil('\n'); if ( dataIn != null ) { // "Num="を含むデータ列かどうかをチェックし,データ数を取得 if ( dataIn.indexOf("Num=")==0 ) { int num = int(split(trim(dataIn),' ' )[1]); // num個のマーカのデータを取得する for (int i=0; i<num; i++) { String marker_info = myClient.readStringUntil('\n'); if ( marker_info!= null ) { // 1行分のデータを切り分けて欲しいデータを取得する String[] data = split(trim(marker_info),','); // マーカの名前と2次元座標 String name = data[0]; int px = int(data[1]); int py = int(data[2]); // 結果を画面に円で表示する ellipse(px,py,10,10); } } } } myClient.clear(); } }
QPToolkitで用いるマーカについて
ARToolKitで用いられるマーカと同じ仕様です.以下の条件に当てはまるものをマーカとして認識します.
- 正方形をしている(大きさは任意)
- 黒枠がある
- 黒枠の太さとパターン領域の領域幅の比は1:2
- 黒枠内のパターンはカラーまたはモノクロ
- パターンは黒枠と接触していても良い
- パターンは回転させたときに同じデザインにならなければOK
(点対称図形でなければOK)
マーカ認識に関するTips
カラフルなマーカを作ることもできますが,環境の明るさによって色は変化しますので,認識精度が 悪くなりがちです.なるべく白黒で作ることをおすすめします. パターンのデザインに点対称がNGなのは,マーカの向きを正しく判別できないからです. マーカの向きの情報を使わないのであれば,この条件を無視することができます.
黒枠とパターン領域の比が1:2なのは,この性質を利用して,全体の輪郭からパターン領域の位置を 推定して切りだすためです.なので,黒枠が多少細くても認識されますが,本来黒枠であるはずの領域 に描かれているパターンの情報は無視されることになります.
テスト用のブランクマーカ
黒枠だけのマーカを描いたPDFを用意しました.テスト用に使ってください. A4用紙であれば,160mm×160mmのマーカが印刷されます. 黒いペンで自分で絵を描いて,オリジナルのマーカをデザインしてみてください. 自分で描いたマーカが認識されると結構テンションが上がりますよ.
blank_marker.pdf (220KB) |
QPToolkitで扱う座標系について
カメラ画像上の2次元座標
画像上の2次元位置を計測するときは,画像の左上隅を原点とするxy座標系での値になります. 頂点座標は,マーカの左上から時計回りの順で出力されます.
2次元の位置計測をやるときの座標系
空間上の3次元座標
空間上の3次元位置を計測するときは,カメラの光学中心を原点とするXYZ座標系での値になります.
3次元の位置計測をやるときの座標系
カメラとマーカの座標変換(回転+並進)
カメラとマーカの座標変換はOpenGLの4×4の行列で以下のように示されます. 回転行列+並進ベクトルなので,3次元の傾きのデータが必要なときはこれを利用してください.
カメラ座標系とマーカ座標系の関係
Command Modeのときのコマンド一覧
Command Modeでは,クライアント側からコマンドを送信して,それに応じたデータを取得することができます. データを垂れ流しにする必要がないときや,指定した名前のマーカがあるかどうかをサーバ(QPServer)に 問い合わせるようにしたいときなどはこちらのモードがおすすめです. 以下に最新版のコマンド一覧を示します.
コマンド名 | 実行内容 |
all | すべてのマーカの情報を取得します. |
get <name> | 指定された名前のマーカの情報を取得します. |
help | ヘルプを表示します. |
exit | 接続を終了します. |
quit | 接続を終了します. |
saveimage <filename> | カメラ画像をサーバPC内のディレクトリに保存します.形式はjpg,png,bmpのいずれか. サーバPC上で動作中のクライアントのみ実行可能(外部PCからでは実行不可). 例)saveimage test.jpg |
register <filename> | サーバPC内にある画像ファイルからマーカを登録します.形式はjpg,png,bmpのいずれか.
画像サイズが大きすぎると失敗する場合があります.800x600程度推奨. サーバPC上で動作中のクライアントのみ実行可能(外部PCからでは実行不可). 例)register test.jpg |
allfromimage <filename> | サーバPC内にある画像ファイルからすべてのマーカ情報を取得します 例)allfromimage test.jpg |
getfromimage <filename> <name> | サーバPC内にある画像ファイルから指定された名前のマーカ情報を取得します 例)getfromimage test.jpg Hiro |
QPServerのソースコード
QPServer ver.1.06(ソースコード)(40.7KB,2011/1/4:最新版) |
ネットワーク通信のライブラリにBoost(Ver.1.38), ビデオキャプチャのライブラリにOpenCV(Ver.2.0), マーカ計測のライブラリにARToolKit(Ver.2.72.1)をそれぞれ使用しています. ライブラリのバージョンが違うとコンパイルがうまくいかない可能性があります. 開発環境はVisualC++2008Professional Editionを使いました.
【おまけ】 QPServerの前身であるVisionServer ver.1.00(PointGray版)とそのソースコードを置いておきます. |
謝辞
QPServer(の前身VisionServer)を使ったワークショップに参加してくださったお茶の水女子大学・椎尾研究室の皆様に 心から感謝いたします.ソフトウェアの運用試験へのご協力とフィードバックをいただきありがとうございました.
QPServerのアイコンのデザインを「うろ覚えキューピー募集」と称してTwitterで一般公募しました. 最優秀作品投稿者の@apapababyさん, それをアイコン化してくださった@sokuzeさん, そして応募してくださった皆様に感謝いたします.ありがとうございました.