◎使い方
ARToolKitLibの基本的な使い方をサンプルプログラムを元に説明します。
詳細は添付サンプルのSample_Simpleを参照してください。
Sample_SimpleはARToolKit付属サンプルのsimpleを移植したプログラムです。
基本構造は元と同じですが、VB用に若干改造し、日本語のコメントを追加してあります。
このサンプルはカメラ映像をウィンドウに表示し、
マーカー画像を見つけた場合、その位置に箱を描画します。
マーカーはARToolKitのpatternsフォルダ内にある「pattHiro.pdf」です。
このPDFファイルを印刷してカメラで撮影して下さい。
左:サンプルsample_simpleの画面 右:ただのカメラの画像(GraphEditで撮影)
カメラで 四角のHiro を撮影すると、その位置に青色のボックスが描画されます。
カメラを動かすマーカーの位置/角度に合わせてボックスも変化します。
○参照設定
'「ARToolKitLib.dll」と「OpenGLLib.dll」を参照設定してください。 Imports ManagedARToolKit Imports OpenGLLib |
まず、「参照の追加」で「ARToolKitLib.dll」と「OpenGLLib.dll」を追加します。
マーカー検出だけならARToolKitLib.dllだけで可能ですが、
検出箇所にボックスを描画するためにOpenGLLibが必要となります。
「ARToolKitLib.dll」と「OpenGLLib.dll」を参照設定することで
ManagedARToolKitとOpenGLLibが使用できるようになります。
ARToolKitでカメラで撮影したマーカーの上になにか物体を描くには
このサンプルは下記のような構造となってます。
GLUTの初期化
↓
カメラの準備
↓
カメラパラメタの読込/設定
↓
マーカーの登録
↓
表示ウィンドウの準備
↓
キャプチャ開始
↓
メインループ
1フレーム読み込み
↓
マーカー検索
↓
マーカー位置決定
↓
描画
○GLUTの初期化
'GLUT初期化処理(実は不要) Dim argc As Integer = 1 Dim argv() As String = {My.Application.Info.ProductName} glutInit(argc, argv) |
GLUTを初期化します。が、この処理は不要だったりします。
(引数に深い意味もありません。)
○カメラの準備
'カメラ設定情報が格納されているファイル名 Dim vconf As String = GetARToolKitInstallDirectory() + "\bin\data\WDM_camera_flipV.xml" |
'open the video path 'カメラの起動 If arVideoOpen(vconf) < 0 Then End End If |
カメラの属性を指定して、カメラを初期化します。
引数として入力ソースの情報が記述されているXMLファイルを指定します。
関数GetARToolKitInstallDirectory()は、
ARToolKitがインストールされている(であろう)フォルダを返します。
このサンプルではARToolKitに付属している設定ファイル"WDM_camera_flipV.xml"を指定しています。
カメラ情報XMLファイルの形式については、
DVSLフォルダ下にDsVideoLib.xsdというスキーマファイルがありますので
詳細についてはそちらを参照してください。
例)カメラ入力:上下反転、サイズ等はダイアログで選択(WDM_camera_flipV.xmlと同じ)
<?xml version="1.0" encoding="UTF-8"?> <dsvl_input> <camera show_format_dialog="true"> <pixel_format> <RGB32 flip_h="false" flip_v="true"/> </pixel_format> </camera> </dsvl_input> |
例)カメラ入力:上下反転、サイズは640x480でダイアログ表示なし
<?xml version="1.0" encoding="UTF-8"?> <dsvl_input> <camera frame_width="640" frame_height="480"> <pixel_format> <RGB32 flip_h="false" flip_v="true"/> </pixel_format> </camera> </dsvl_input> |
○カメラパラメタの読込/設定
Dim xsize, ysize As Integer '画像サイズ Dim thresh As Integer = 100 'マーカー認識時の二値化しきい値 Dim count As Integer = 0 'フレーム数 'カメラパラメタが格納されているファイル名 Dim cparam_name As String = GetARToolKitInstallDirectory() + "\bin\Data\camera_para.dat" Dim cparam As New ARParam 'カメラパラメタ |
'find the size of the window '画像サイズを取得 If arVideoInqSize(xsize, ysize) < 0 Then End End If Console.WriteLine("Image size (x,y) = ({0},{1})", xsize, ysize) 'set the initial camera parameters 'カメラパラメタを読み込む If arParamLoad(cparam_name, 1, wparam) < 0 Then Console.WriteLine("Camera parameter load error !!") End End If arParamChangeSize(wparam, xsize, ysize, cparam) '読み込んだカメラパラメタを画像サイズに合わせて調整 arInitCparam(cparam) 'カメラを初期化 Console.WriteLine("*** Camera Parameter ***") arParamDisp(cparam) 'カメラパラメタの表示 |
カメラパラメタとは、カメラのレンズ特製などから導き出される係数で
キャリブレーションを行うことでカメラ毎に用意します。
が、ARToolKitに添付されているサンプルデータでもそれなりの結果が出ます。
まず今回使う画像のサイズをarVideoInqSizeで取得し
ベースとなるカメラパラメタをarParamLoadで読み込み
arParamChangeSizeで画像サイズに合わせて
読み込んだカメラパラメタを調整します。
最後に調整が済んだカメラパラメタをarInitCparamで設定することにより、
以後の計算で使用されるようになります。
なおarParamDispは何も出力しません。(手抜き〜)
○マーカー登録
'マーカーパターンの読み込み/登録 patt_id = arLoadPatt(patt_name) If patt_id < 0 Then Console.WriteLine("pattern load error !!") ' End End If |
マーカーのパターンはarLoadPatt()で読み込みます。
戻り値としてパターンを認識するIDが返されます。
このIDは検索結果から目的のマーカーを探すために必要になります。
○表示ウィンドウの準備
'open the graphics window '描画ウィンドウの準備 argInit(cparam, 1.0, 0, 0, 0, 0) |
argInitで画像サイズにあったウィンドウなどが用意されます。
○キャプチャ開始
'キャプチャ開始 arVideoCapStart() |
arVideoCapStartでキャプチャを開始します。
○メインループ開始
'メインループ開始(復帰なし) argMainLoop(Nothing, keyEvent_Ptr, mainLoop_Ptr) |
argMainLoopではマウスイベント用関数、キーイベント用関数、メイン更新関数を指定します。
各関数のデリゲートを指定してください。(不要なところはNothingが指定できます。)
argMainLoopはGLUTのglMainLoopを使っています。
OpenGLのページでも触れてますが、
argMainLoop(glMainLoop)を呼び出すと戻ってきません。
使わない方法も面倒ですが一応ありますので、
アプリにするならそちらの方がいいかと思います。
argMainLoopを使わない方法はサンプルの「Sample_NotUseArgMainLoop」を参照してください。
○メインループ:1フレーム読み込み
'main loop 'メインループ処理(argMainLoopから繰り返し呼び出される) Sub mainLoop() Dim dataPtr As ARUPointer 'イメージデータのアドレス Dim marker_info As ARMarkerInfo = Nothing '発見したマーカー情報 Dim marker_num As Integer '発見したマーカーの数 Dim j, k As Integer 'grab a vide frame 'カメラから1フレーム読み込み dataPtr = arVideoGetImage() If dataPtr.IsNull Then arUtilSleep(2) '読み込み失敗時は2ms待機し、次のフレームへ Return End If If count = 0 Then arUtilTimerReset() 'フレームレート計算用のタイマーをリセット count += 1 'フレーム数加算 argDrawMode2D() '2D描画モードへ argDispImage(dataPtr, 0, 0) '読み込んだ画像を描画 |
arVideoGetImageにてカメラから1フレームを読み込みます。
失敗した場合(開始直後などまだカメラに画像が読み込まれてない場合など)はNullが返されるので
その場合は少しだけ待って、再度読み込みを試します。
countは終了時にフレームレートを表示するためのフレームカウンタです。
サンプルではargDispImageで読み込んだ画像を表示しています。
○メインループ:マーカー検索
'detect the markers in the video frame '画像からマーカーを検索 If arDetectMarker(dataPtr, thresh, marker_info, marker_num) < 0 Then cleanup() '検索に失敗した場合、終了 End End If arVideoCapNext() '次のフレームの準備 |
arDetectMarkerで画像中のマーカーを検索します。
検索した結果は配列としてメモリ内に格納され、
marker_infoに先頭(アドレス)が、marker_numに個数が返されます。
arVideoCapNextを呼び出すと次のフレームの読み込みに着手しますが、
描画が検索が終わった後に呼び出す必要があります。
○メインループ:マーカー位置決定
'check for object visibility '発見されたマーカー情報の中で、最もスコアが大きい位置を選出 Dim marker_info_arr() As ARMarkerInfo = marker_info.GetArray(marker_num) k = -1 For j = 0 To marker_num - 1 If patt_id = marker_info_arr(j).id Then If k = -1 Then k = j '初見のマーカー情報を仮選択 ElseIf marker_info_arr(k).cf < marker_info_arr(j).cf Then k = j 'よりスコアの大きいマーカー情報を選択 End If End If Next If k = -1 Then argSwapBuffers() '見つからなかった場合、何もしないで次のフレームへ Return End If |
まず、arDetectMarkerで取得した先頭マーカー情報から
marker_num個数分だけマーカー情報を配列に取り出します。(marker_infoのGetArrayメソッド)
取り出したARMarkerInfo配列の中から、
ターゲットのマーカーパターン(id)で最もスコア(cf)が高い情報を選出します。
ターゲットマーカーの情報がなければ検出できなかった事を意味します。
○メインループ:描画
'get the transformation between the marker and the real camera 'マーカーの位置情報(2D位置)から実際の位置情報(3D位置)へ変換する行列(マーカー変換行列)を取得 arGetTransMat(marker_info_arr(k), patt_center, patt_width, patt_trans) draw() 'マーカー上にボックスを描画 argSwapBuffers() 'バッファ切り替えを行い、画面を更新 |
マーカーが見つかった場合、その位置にボックスを描画します。
描画はOpenGL(GLUT)のglutSolidCubeでおこなってます。
OpenGLで描画するときに使用する変換行列は、
まずarGetTransMatで選出したマーカー情報から3×4の行列を取得し、
その行列をargConvGlparaでGL用の4×4行列に変換して取得します。
(この辺がARToolKitのキモというか、私的に一番面白い所ですね。)
以上がもっともシンプルなサンプルの説明になります。
◎サンプル
ARSampleで始まるサンプルはARToolKit付属サンプルを移植したものです。
○ARSample_Simple
ARToolKit付属サンプルsimpleを移植したサンプルです。
カメラ映像内のマーカーの上にボックスを描画します。
○ARSample_MultiTest
ARToolKit付属サンプルmultiTestを移植したサンプルです。
6個のマーカーを認識し、それぞれの上にボックスを描画します。
○Sample_DLLCheck
ARToolKitLib.dllが呼び出せるかどうかを確認するためのサンプルです。
ARToolKitのバージョンとインストールパスを表示します。
○Sample_NotUseArgMainLoop
argMainLoopを使用しないでsimpleと同等の動作を実現するサンプルです。
画像取り込みにOpenCV、検索にARToolKit、描画にOpenGLを使用しています。
ボックスじゃなくてティーポットにしてみました。