※上記の広告は60日以上更新のないWIKIに表示されています。更新することで広告が下部へ移動します。

この中ではにたような言葉が使われますので、手元にダウンロードして違いを理解してから読んでください。
  • ARtoolkit(=ARTK=本家)→hp
  • ARtoolkitPlus(=Plus=発展系亜種)→hp
  • ofxARToolkitPlusExample(example=ofxをつかったxcodeのofサンプル)→hphp2
  • ofxARtoolkitPlus(ofx=openframeworksアドオン上のに入ってるやつ)
ちなみに環境はosx10.7,xcode3,openframeworks61です。



ARtoolkitの概念をまず勉強する。
ARtoolkitではまずカメラの補正と、マーカータグの登録を行います。
カメラの補正は動けばいいやってことで、適当にしがちですが、ディスプレイ環境とか複数マーカー環境ではやっておくべきでしょう。これって、web環境ではカメラデバイスの補正値を最初に取得させるんでしょうかね、、、。それともメーカーの型番とかから判定するのかな、、、。

ofでofxARToolkitPlus artk;というラッパークラスをつかって作ると、ofからPlusが使えるようになります。artkはofxARToolkitPlusオブジェクトです。artk.setup()で内部的にはカメラパラメーターを取得します。addon/ofxARToolkitPlus/ofxARToolkitPlus.cppとヘッダファイルをみると

void ofxARToolkitPlus::setup(int w, int h) {
// load std. ARToolKit camera file	
// These need to be in the data folder
setup(w, h, "LogitechPro4000.dat", "markerboard_480-499.cfg");
}
とあります。
ARToolKit camera fileとあるので、カメラ補正自体はARToolkitの付属ソフトで作れるはず(と思う)。
アドオンに入っているかと思えば、入っていないので、まあ自分で探せということでしょう。
http://www.hitl.washington.edu/artoolkit/download/
からダウンロードしておいてください。
ARToolkit/bin/calib_camera2.exe
がそれです。
この辺りで方法を学習してください。
たとえばLogitechPro4000.datというデータができたとしましょう。
できたらxcodeのアドオンサンプルの中のdataフォルダに入れておきます。
付属ソフトをつかって、カスタムタグの登録もできます。
ARToolkit/bin/mkpatt.exe
でできます。
おなじくこの辺りで学習して下さい。
例えばpatt.hiroとかいうデータができるはずです。
これでLogitechPro4000.datとpatt.hiroというカメラ設定とオリジナルマーカー設定の2つに必要なデータができました。
ARToolkitのソフトでつくったパラメータファイルがARToolkitPlusで動くのかどうか?これを次に検証します。

exampleのdataフォルダの中にデフォルトでおいてあるLogitechPro4000.datの内容をみてみます。すると、人の言葉でないので読めない。たぶんバイナリデータだと思うのですが、バイナリエディタで読んでみましたが意味は不明。さてどうしましょ。このデータができるプロセスをみてみることにします。

Plusの内部的には TrackerMultiMarkerImplというトラッカークラスを内部的に生成します。
トラッカークラスとマルチマーカーという新しい言葉がでてきました。

トラッカークラスは映像からマーカーを抽出するためにもうけられた抽象的なクラスと推測できますが、どうなんでしょう、、、。

マーカーはシングルマーカーとマルチマーカーの2つがあります。シングルマーカーはひとつのマーカーです。一方マルチマーカーとは一枚の紙に複数のマーカを印刷したものということで、複数のマーカーの相対的な距離まで登録されているので、ひとつだけ欠けたとしても、周りのマーカーから類推して表示することができるタイプのマーカーです。こちらを参照マーカーのサイズはいろいろあってもかまわないようですが、相対的な距離を指定して決めておかないといけません。

複数のマーカーをmkpatt.exeでつくっておいて、ARToolkit/bin/Data/multiフォルダにいれて、定義ファイルmarker.datとかいうをテキストファイルでつくって同じフォルダに入れておくというのが流れのようです。が、exampleにはAllBchThinMarkers.pngという画像ファイルと、markerboard_480-499.cfgという謎の拡張子(たぶんコンフィグ)のファイルしかありません。怪しいですね。これを開いてみると、バイナリではなく、テキストでした。おお、マルチマーカの定義ファイルのようです!発見。でも480番から499番までの20個しか定義されていません。さてどうしましょう?

ofで
setup(w, h, "LogitechPro4000.dat", "markerboard_480-499.cfg");
と記述したところは最終的にPlusのトラッカークラス内で
arMultiReadConfigFile(nMultiFile)
とかいう関数で処理されています。

マルチマーカーの定義ファイルの読み込みはARTK的にはarMulti.hに書いてあるとのことなのですが、Plus的にはarMultiReadConfigFile.cxxっぽいのでこれを読んでみます。(アドオンのソースにはいってる)

ARMultiEachMarkerInfoT *marker;っていうポインタアドレスに
arMalloc(marker,ARMultiEachMarkerInfoT,num);でマーカー個数分の構造体が入るためのメモリ領域を確保してるみたい。
arMallocはar.hで定義されてる。中をみると、構造体がARMarkerInfoとARMarkerInfo2の2タイプあるけど、どちらもマルチマーカー用ではないようです、、、。
   int     area;
   int     id;
   int     dir;
   ARFloat  cf;
   ARFloat  pos[2];
   ARFloat  line[4][3];
   ARFloat  vertex[4][2];
が定義されている。
これはARTKでいうとこのARMarkerInfo(マーカーひとつが持っている属性を束ねた構造体)という構造体と一緒ですね。

arMultiReadConfigFileをみると

marker[i].patt_id
marker[i].width
marker[i].center[0~1]
marker[i].trans[0~2][0~3]
marker[i].pos3d[0~3][0~2]

があるからmarker構造体がどっかにあるはず?とおもって探すと。

ARMultiEachMarkerInfoT *markerと
ARMultiMarkerInfoT *marker_info
構造体が定義されているのはarMulti.hだとわかりました。

typedef struct {
   int     patt_id;
   ARFloat  width;
   ARFloat  center[2];
   ARFloat  trans[3][4];
   ARFloat  itrans[3][4];
   ARFloat  pos3d[4][3];
   int     visible;
/*---*/
   int     visibleR;
} AR_EXPORT ARMultiEachMarkerInfoT;
つまりマーカー個別の情報ね

typedef struct {
   ARMultiEachMarkerInfoT  *marker;
   int                     marker_num;
   ARFloat                  trans[3][4];
   int                     prevF;
/*---*/
   ARFloat                  transR[3][4];
} AR_EXPORT ARMultiMarkerInfoT;
つまりマーカー個別の情報がいくつどっち向いてんの?みたいなやつね。

戻り値として、ARMultiMarkerInfoT構造体をリターンします。中には個別の情報も入ってる。便利。ポインタってnewしなくていいの楽だな。倉庫に適当においとけ、場所だけメモっとけってことだもんね。

でも,結局パターンファイルを読み込みんでいるだけで、コンフィグデータの内容まではわかりませんでしたね、、、。まあ、そんなもんです。

では今度は画像をどうやって読み込んでいるのかを検証してみます。
of的には
artk.update(grayImage.getPixels());
という記述です。
ofxCvGrayscaleImage grayImage;
このgrayImageというクラスはなんと、openCVアドオンのクラスです。
grayImage.allocate(width, height);
すると
unsigned char* 	pixels;
というchar型(0~255の値×画素数)が格納されているポインタアドレスを返してきます。
こりゃ便利。
grayImage.getPixels()メソッドは画素そのものをゲットするのではなく、画素をpixelsというポインタアドレス上に格納してそのアドレスだけ返してます。なんて効率的!C言語って感じですね〜。
artk.update(画像のポインタアドレスを渡す);
までわかりました。
これをPlusの内部的にはどう処理しているのかをみていきます。

int ofxARToolkitPlus::update(unsigned char *pixels) {
return tracker->calc(pixels);
}
calcに渡すだけ、、、。colcは何を返すのか、、、。TrackerMultiMarkerImpl.cxxをみてみます。

当然intなのですが内容はnumDetectedなので、認識したタグの個数ですね。
処理内容は認識した個数分のidとARMarkerInfo構造体を
TrackerMultiMarkerImpl.hで定義されている2つのプロテクト変数に格納します。

int				detectedMarkerIDs[AR_TEMPL_TRACKER::MAX_IMAGE_PATTERNS];
ARMarkerInfo	detectedMarkers[AR_TEMPL_TRACKER::MAX_IMAGE_PATTERNS];

それから、バトンしてofまでint型でマーカーの個数を返します。

では次
artk.draw(640, 0);
はどうでしょう。
ARToolKitPlus::ARMarkerInfo marker = tracker->getDetectedMarker(i);
でARMarkerInfoをごっそりゲットして
marker.vertex[0][0]
こんな感じでメンバ変数を使えちゃうということらしいですね。

うーん。なるほど〜。
でもやりたいポイントは、違うんよね〜。
では次こそは、オリジナルマーカーの登録を目指します!