Microsoft Word - 卒業論文 docx

Similar documents
ARToolKit プログラムの仕組み 1: ヘッダファイルのインクルード 2: Main 関数 3: Main Loop 関数 4: マウス入力処理関数 5: キーボード入力処理関数 6: 終了処理関数 3: Main Loop 関数 1カメラ画像の取得 2カメラ画像の描画 3マーカの検出と認識

Tekutama AR ~ 拡張現実感によるオーバーレイ表示と動作 ~ 情報物理研究室 渡部 修平 1

2 2 2 OpenGL Linux Linux Video for Linux(Video4Linux, v4l ) API Video4Linux USB IEEE1394 API Linux Video for Linux 2(Video4Linux2, v4l2 ) OpenCV API U

卒業研究報告書 題目 3DCG と Web カメラの合成を表現するプログラムの制作 指導教員 綿森道夫准教授 報告者 学籍番号 : 氏名 : 尾川景子 平成 23 年 2 月 8 日 高知工科大学電子 光システム工学科 1

コンピュータグラフィックスS 演習資料

AR技術を用いたグリーティングカード作成ソフトの開発

memo

プログラミングI第10回

C プログラミング演習 1( 再 ) 2 講義では C プログラミングの基本を学び 演習では やや実践的なプログラミングを通して学ぶ

画像ファイルを扱う これまでに学んだ条件分岐, 繰り返し, 配列, ファイル入出力を使って, 画像を扱うプログラムにチャレンジしてみよう

スライド 1

ic3_cf_p1-70_1018.indd

問 1 図 1 の図形を作るプログラムを作成せよ 但し ウィンドウの大きさは と し 座標の関係は図 2 に示すものとする 図 1 作成する図形 原点 (0,0) (280,0) (80,0) (180,0) (260,0) (380,0) (0,160) 図 2 座標関係 問 2

プログラミング基礎

/*Source.cpp*/ #include<stdio.h> //printf はここでインクルードして初めて使えるようになる // ここで関数 average を定義 3 つの整数の平均値を返す double 型の関数です double average(int a,int b,int c){

Microsoft PowerPoint - kougi2.ppt

PowerPoint プレゼンテーション

C#の基本

Microsoft PowerPoint - [150421] CMP実習Ⅰ(2015) 橋本 CG編 第1回 幾何変換.pptx

バイオプログラミング第 1 榊原康文 佐藤健吾 慶應義塾大学理工学部生命情報学科

PowerPoint プレゼンテーション

PowerPoint プレゼンテーション

コンピューターグラフィックスS

CubePDF ユーザーズマニュアル

アクション講座 第1回目

02: 変数と標準入出力

ファイル入出力

PowerPoint プレゼンテーション

Microsoft PowerPoint - CproNt02.ppt [互換モード]

コンピュータグラフィックス第6回

コンピューターグラフィックスS

PowerPoint Template

円筒面で利用可能なARマーカ

Mapmakerfor の手順下絵を準備 作者の設定した大きさで作成する場合 下絵にする地図を挿入 トリミングと大きさの調整 大きさを調整した画像を保存 下絵を背景に設定 作成画面の大きさを調整 1 自分で用意した下絵を背景にする場合 下絵を背景に設定 作成画面の大きさを調整 画像が大きい場合シート

コマンドラインから受け取った文字列の大文字と小文字を変換するプログラムを作成せよ 入力は 1 バイトの表示文字とし アルファベット文字以外は変換しない 1. #include <stdio.h> 2. #include <ctype.h> /*troupper,islower,isupper,tol

第 8 回の内容 クライアントサイド処理 JavaScript の基礎

cp-7. 配列

コンピュータグラフィックス第8回

HP Primeバーチャル電卓

コンピュータグラフィックス基礎              No

Field Logic, Inc. 標準モード 3D モデル作成 配置編 Field Logic, Inc. 第 1 版

2. 印刷対象のサイズの確認 大判印刷を行う場合 まず 印刷をする文書のサイズを確認する必要があります サイズの確認の方法はアプリケーションによって異なるので ここでは PowerPoint(2010/2013) と Adobe Acrobat を例に説明します PowerPoint2010 の場合

プログラミング基礎I(再)

プログラミング実習I

関数の定義域を制限する 関数のコマンドを入力バーに打つことにより 関数の定義域を制限することが出来ます Function[ < 関数 >, <x の開始値 >, <x の終了値 > ] 例えば f(x) = x 2 2x + 1 ( 1 < x < 4) のグラフを描くには Function[ x^

Wordの学習

PowerPoint2003基礎編

Microsoft PowerPoint ppt

char int float double の変数型はそれぞれ 文字あるいは小さな整数 整数 実数 より精度の高い ( 数値のより大きい より小さい ) 実数 を扱う時に用いる 備考 : 基本型の説明に示した 浮動小数点 とは数値を指数表現で表す方法である 例えば は指数表現で 3 書く

演算増幅器

ファクス送信用変換ソフト 操作説明書_UA

Microsoft Word - SKY操作マニュアル.doc

基本作図・編集

UMLプロファイル 機能ガイド

Transcription:

- ARToolKit によるマルチマーカの考察 日付 2011 年 1 月 24 日 阪南大学経営情報学部経営情報学科 5107171 筒井亮 5107283 山岡大介 1

目次 第 1 章拡張現実感 (AR: Augmented reality)~はじめに~... 3 第 2 章関連研究... 4 第 3 章 ARToolKit の概要... 6 第 4 章プログラムの構成... 7 第 1 節メイン関数 Main()... 7 第 2 節メインループ関数 MainLoop()... 10 第 3 節オブジェクト描画関数 DrawObject()... 14 第 4 節キーボード入力処理関数 KeyEvent()... 16 第 5 節マウス入力処理関数 MouseEvent()... 16 第 6 節終了処理関数 Cleanup()... 17 第 5 章作成した 3DCG モデルの応用... 18 第 1 節 3DCG モデルの作成 Metasequoia... 18 第 2 節 GLMetaseq の関数... 18 第 3 節モーションの連番 MQO 出力... 20 第 6 章複数のマーカを利用した AR アプリケーション.....22 第 1 節構造体... 22 第 2 節パターンファイルのロード... 23 第 3 節マーカの信頼度の比較... 23 第 4 節 3DCG とマーカの役割... 24 第 7 章まとめ... 28 参考文献... 29 謝辞... 29 2

第 1 章拡張現実感 (AR:Augmented reality) ~ はじめに ~ 2007 年前後から 拡張現実感技術を利用した新たなサービスに大きな注目が集まっている 拡張現実感技術はディジタル情報を現実の世界に融合させることにより 新しいユーザインタフェースを構築し 作業支援や情報提示に役立てることを目的としている 現在 拡張現実感を利用した技術が医療 教育 建築 観光 エンタテイメントなどのさまざまな分野での応用が期待されている まず AR とは 実環境の上にバーチャル環境を重畳する概念である AR は実環境に対し空間的整合性を保ちつつ 実時間でシームレスに情報を重畳提示する点が従来の位置情報システムとの違いとなっている 拡張現実感 (Augmented reality) とは 仮想現実感 (virtual reality) から派生した比較的新しい研究領域で 実世界の映像に仮想的な物体の映像を重ね合わせるという発想に由来している カーナビゲーションシステムは 実世界における現在位置と地図上の現在位置の間に常に関連を持たせ 現在位置とユーザーの目的に関連のある情報を提示することができる このようなシステムは 実世界を情報的に拡張しているという意味で一種の拡張現実と言える 拡張現実感をアプリケーションの側面からみると その最も一般的な適用場面はユーザの実世界でのタスク遂行を支援するというものである 例えば 仮想物体を実物体上に重畳表示することによって組み立て作業 医療活動 メンテナンス作業を支援するシステムをあげることができる 本論文では ARToolKit を使ったアプリケーションを開発するために ARToolKit Home page[1] で配布されているC 言語ライブラリ郡を扱うこととする また 3DCG 作成ソフトで自作のモデルを作り 技術的に応用した物の作成を試みる 図 1-1 拡張現実モデル 3

第 2 章関連研究 まず, 拡張現実の実際の利用例を示す 自動車メーカーの BMW ( Bayerische Motoren Werke AG) は 広告 販促活動の一環としてマーカの描かれたパンフレットなどをカメラにかざすと 車両の CG モデルを描画するウェブサイトを提供している [2] 単にウェブコンテンツとして AR ネタを見せるだけでなく 実際の BMW が 走り でペイントする TV -CM( 図 2-1 参照 ) の放映もしている TOYOTA UK も IQ の広告 販促活動の一環として マーカ上に車両の3D モデルを重畳させるアプリケーション Toyota IQ MagicSymbol を配布している マーカの傾きを変化させることで走行状態の制御や 車両の内臓構造の確認を行うことが可能となっている [3] 図 2-1 BMW プロモーション映像. さらに 拡張現実の発展として カメラと位置 姿勢センサーを搭載した携帯電話の普及により 携帯型情報端末を用いた AR サービスの可能性が注目されている 2009 年 9 月から 頓智ドット が実環境の地理情報に対応したタグをカメラ映像に重畳する セカイカメラ が提供されている [4] iphone のカメラ機能を使って撮影した場所の位置情報を取得し ディスプレイに表示された対象にエアタグと呼ばれる付加情報を重ねて表示させるアプリケーションである エアタグはユーザが自由に貼り付けることができ コンビニやファストフード店もエアタグで見れる セカイカメラは米国で開催されたネット サービスのビジネス コンテスト TechCrunch50 で発表され 米アップルの iphone と AR を組み合わせたサービス像が話題を集めた iphone アプリで最も注目されている AR アプリである 図 2-2 セカイカメラ起動画面 4

そして iphone などのスマートフォン以外でも国内 3キャリアの携帯電話で楽しめる AR アプリ AR3DPlayer が登場した[5] マーカの中に QR コードが含まれており マーカを読み取るだけでプロモーションのコンテンツのダウンロードができる そのためマーカに対応した AR コンテンツをダウンロードする必要がなく利用できるので雑誌などで配布されている QR コード入りのマーカを読み込むことでスムーズに利用出来るのが特徴である これは プロモーション媒体として活用が注目されている 図 2-3 AR3DPlayer のマーカと動作例 [6] 5

第 3 章 ARToolKit の概要 拡張現実感技術とは Myron Krueger 氏が 1973 年に提唱した概念であり 現実の環境から受ける知覚情報にコンピュータによって作り出された情報を重ね合わせることによって 現実世界の情報を強化する技術である 日常私たちが感じている現実感とは 目や耳 鼻 口などの感覚器に与えられる刺激を脳の中で処理し感じ取っている つまり その刺激を擬似的に作り出して知覚器に与えることによって 存在しないものをあたかもそこにあるかのように実感し 体験することが出来るのである 本章で扱う ARToolKit とは 奈良先端科学技術大学院大学の加藤博一教授が開発した C/C++ 言語用のプログラミングライブラリである ARToolKit を使うことで 紙に印刷されたマーカをカメラで読み込み 位置 姿勢 座標などを計算してその上に3Dオブジェクトを描画する ( 図 3-1 参照 ) ためのライブラリである ARToolKit が提供している主な機能は カメラからの画像取得 マーカの検出とパターンの認識 マーカの3 次元位置と姿勢の計測 実写画像の3 次元 CGの合成表示である また カメラ画像の描画や仮想空間における視点の設定には GLUT(OpenGL Utility Toolkit) を用いている これは 1994 年にSGI( シリコングラフィックス ) 社のマーク ギルガード氏によって開発 OpenGL の補助ライブラリであり OSをシステムレベルで I/O を制御しているため OSに依存せずに描画できることが特徴である nate@pobox.com[7] で配布されている補助ライブラリ郡を利用する 図 3-1 ARToolKit 起動画面 6

第 4 章 ARToolKit の内部構造 このプログラムは 登録しているマーカを Web カメラで撮影することでマーカの位置や姿勢を計算し あたかもそこにあるかのように3DCG を表示させるものである 本章では 青い立方体を表示させるプログラムの流れ ( 図 4-1 参照 ) を説明していく また ARToolKit のコマンドは arvideoopen や arvideoinqsize などの先頭に ar がついて始まる これらの先頭文字列から定義されているヘッダーファイルを推測することが可能である また OpenGL のコマンドも gl glut などの先頭文字列で始まるコマンドが用意されている 図 4-1 ARToolKit のプログラム全体像 [8] 第 1 節メイン関数 Main() メイン関数では ARToolKit を扱うための OpenGL やビデオデバイス ウィンドウ設定などの初期化処理とメインループ関数の呼び出しを行っている 初期化関数である Init() 7

関数を用いてコマンドを分けている場合もあるが 本プログラムでは Main() 関数ですべての初期化を行うことにする 以下にプログラムの説明を行う. int main( int argc, char **argv ) { ARParam cparam; // カメラパラメータ ARParam wparam; // カメラパラメータ ( 作業用変数 ) int xsize, ysize; // 画像サイズ // GLUT の初期化 (1) glutinit( &argc, argv ); // ビデオデバイスの設定 (2) if ( arvideoopen( vconf_name ) < 0 ) { printf(" ビデオデバイスのエラー "); return -1; // カメラパラメータの設定 (3) if ( arvideoinqsize( &xsize, &ysize ) < 0 ) { printf(" 画像サイズを取得できませんでした \n"); return -1; if ( arparamload( cparam_name, 1, &wparam ) < 0 ) { printf(" カメラパラメータの読み込みに失敗しました \n"); return -1; arparamchangesize( &wparam, xsize, ysize, &cparam ); arinitcparam( &cparam ); // パターンファイルのロード (4) if ( (patt_id = arloadpatt(patt_name)) < 0 ) { printf(" パターンファイルの読み込みに失敗しました \n"); return -1; // ウィンドウの設定 (5) arginit( &cparam, 1.0, 0, 2, 1, 0 ); // ビデオキャプチャの開始 (6) arvideocapstart(); // メインループの開始 argmainloop( MouseEvent, KeyEvent, MainLoop ); return 0; (1)GLUT の初期化 ARtoolKit ライブラリと このプログラムにおいて GLUT のコードを使用しているので最初に GLUT の初期化を行う必要があるので glutinit() 関数を実行する また この関数は初期化関数なので OpenGL や glut などの他の関数よりも先に呼び出すことが前提である (2) ビデオデバイスの設定 arvideoopen() 関数によってビデオデバイスなどの USB カメラを使える状態に設定する 引数には ビデオデバイスの設定ファイルの名前を指定する 本プログラ 8

ムでは 設定ファイルには WDM_camera_para_flipV.xml という xml ファイルから読み込んでいる この xml ファイルには ビデオデバイス名の設定を行うことが可能で初期の状態でエラーが発生した場合は名前を指定する ビデオデバイスの設定に失敗した場合は ARToolKit が起動できないのでプラグラムが終了する (3) カメラパラメータの設定ここでは以下の処理を行っている 1 画像サイズの取得 (arvideoinqsize()) 2カメラパラメータファイルの読み込み (arparmload()) 3 解像度に合わせてカメラパラメータの変更 (arparamchengesize()) 4カメラパラメータを内部の変数にロード (arinitcparam()) カメラパラメータの設定には使用するカメラの解像度によってカメラパラメータの変更が必要なため ファイルから値を読み込んで内部変数にセットする前に値の変更を行っている (4) パターンファイルのロードマーカの認識に用いるパターン情報をパターンファイル (.patt) から読み込んで パターンごとに ID を割り当てる これらの 80mm 80mm のマーカ ( 図 4-2 参照 ) を自作し それを USB カメラを通してコンピュータにパターンファイルとして記録させることでマーカを自由に変更することが可能である 図 4-2 [hiro] マーカ arloadpatt() 関数を使って ファイルから読み込んだパターン情報を ARtoolkit の内部変数に格納してから ID を生成する ここで設定された ID を使ってマーカを識別している (5) ウィンドウの設定 arginit() は ARToolKit のグラフィック処理機能の初期化を行う関数でウィンドウに関する設定も行っている arginit() 関数には cparam のカメラパラメータを格納した変数へのポインである zoom の入力画像のサイズ又は表示サイズの拡大率 fullflag のフルスクリーンモードの有無 xwin の横方向の表示領域の追加数 9

ywin の縦方向の表示領域の追加数 hmd_flag のステレオディスプレイモードの有無などの引数が用意されている フルスクリーン表示を行いたい場合は zoom と fullflag を変更する必要がある xwin と ywin は ウィンドウ内に複数の表示領域を設けたいときに使う 本プログラムでは zoom に 1.0 fullflag に0 xwin に2 ywin に1と設定している これはメインのウィンドウの下に2つ表示領域を設けることを表している (6) ビデオキャプチャの開始とメインループのスタート各種設定が済んだら arvideocapstart() 関数によってビデオキャプチャを開始させ argmainloop() 関数を呼ぶ argmainloop() 関数はマウス入力処理関数 キーボード入力処理関数 メインループ関数の登録を行い メインループをスタートさせる関数である 第 2 節メインループ関数 MainLoop() ここでは毎フレームに行う処理を書いている 1 秒間に表示するフレーム数を計算する処理も行う また 終了処理が実行するまでメインループ関数は延々と繰り返して実行される 以下にプログラムの説明をする void MainLoop(void) { ARUint8 *image; ARMarkerInfo *marker_info; int marker_num; int j, k; // カメラ画像の取得 (1) if ( (image = arvideogetimage()) == NULL ) { arutilsleep( 2 ); return; // カメラ画像の描画 (2) argdrawmode2d(); // 入力画像の描画 argdispimage( image, 0, 0 ); argdispimage( image, 1, 1 ); // 内部画像の描画 if (ardebug && arimage!= NULL ) { argdispimage( arimage, 2, 1 ); // マーカの検出と認識 (3) if ( ardetectmarker( image, thresh, &marker_info, &marker_num ) < 0 ) { Cleanup(); exit(0); // 次の画像のキャプチャ指示 (4) arvideocapnext(); // マーカの信頼度の比較 (5) k = -1; 10

for( j = 0; j < marker_num; j++ ) { if ( patt_id == marker_info[j].id ) { if ( k == -1 ) k = j; else if ( marker_info[k].cf < marker_info[j].cf ) k = j; if ( k!= -1 ) { // マーカの位置 姿勢 ( 座標変換行列 ) の計算 (6) argettransmat( &marker_info[k], patt_center, patt_width, patt_trans ); // 3D オブジェクトの描画 DrawObject(); // バッファの内容を画面に表示 (7) argswapbuffers(); (1) カメラ画像の取得 arvideogetimage() 関数によってビデオデバイスから画像を取得し 画像データへのポインタである image に返す ここで使う image は ARUint8 という unsigned char 型と同義のオリジナルのポインタ型を使っている 取得した画像は arvideocapnext() または ビデオデバイス終了処理が実行されるまでバッファに保持される もし 画像が準備されていなければ NULL を返して arutilsleep() を実行して休止時間をおいてから一度メインループを抜ける これは 画像データが準備できていないと以後の処理を行えないためである (2) カメラ画像の描画 AR アプリケーションでは カメラ画像を描画した後で3D オブジェクトを重ねて描画している カメラ画像を描画するには まず argdrawmode2d() という関数によって2 次元画像を描画するための準備をした後で argdispimage() 関数を使って画像を描画する これらの関数は3D オブジェクトを描画する前に実行する必要がある argdispimage() 関数の引数 xwin と ywin は メイン関数のウィンドウ設定の際に値を入れたものである ウィンドウ内に複数の表示領域を設けたい際に 描画する場所を指定するために使う メインの表示領域の下に2つ領域を設けたい場合は xwin に 2 ywin に 1 を入れることで表示することが可能である 本プログラムでは 右下にデバッグ用のモノクロでマーカをどのように表示しているかを確認する領域と左下にユーザー視点である 3DCG が見えない領域を用意する ( 図 4-3 を参照 ) 11

図 4-3 デバッグ画面 (3) マーカの検出と認識 ARToolkit では 画像をモノクロ化してからマーカの候補領域を探している 引数 thresh は画像をモノクロ化する際の閾値である ウィンドウの右下に表示しているのがこの結果である ardetectmarker() 関数はカメラ画像の中からマーカを見つけ そのマーカのパターンを認識する関数である キャプチャ画像に含まれるすべてのマーカらしき部分を取得し その情報を構造体である ARMarkerInfo 型に格納している marker_num は検出したマーカらしき部分の数を示している 以下に表示するメンバをもとに一致度を比較することになる typedef struct{ int area; // マーカのピクセル数 int id; // マーカID int dir; // マーカの回転方向 (3:, 2:, 1:, 0: ) double cf; // 相関係数 double pos[2]; // マーカの中心 double line[4][3]; // 枠線 double vertex[4][2]; // マーカの頂点座標 ARMarkerInfo; (4) 次の画像のキャプチャ指示取得した画像について 画像の描画とマーカの検出処理が終わったら 次の画像を出す必要があるので 次フレームのキャプチャを指示するために arvideocapnext() という関数を使う これは arvideoimage() 関数を実行してから arvideocapnext() 関数を実行するまで取得したデータが維持されるので それまでにマーカの検出処理を終了させる必要がある 12

(5) マーカの信頼度の比較マーカとして検出される領域の中にはマーカではない領域 ( 誤検出 ) も含まれる マーカごとに対応したオブジェクトを正しく表示するためには 検出されたマーカの中から 指定のパターン ID を持ち かつ最も高い信頼度を持つものを探し出す必要がある ここでは 検出したマーカらしき部分と以下に予め宣言してあるパターンファイルとの比較を行う char *patt_name = "Data\\patt.hiro"; // パターンファイル名 int patt_id; // パターンID double width = 80; // パターンの幅 (mm 単位 ) double center[2] = { 0.0, 0.0 ; // パターンの中心座標 double trans[3][4]; // 座標変換行列 (6) マーカの位置 姿勢の計算 ARToolKit 最大の仕掛けが argettransmat() という関数である この関数では 検出されたマーカの情報からマーカ カメラ間の座標変換行列を求めている patt_center はマーカ上のどこに原点を置くかを決めるパラメータの役割をする 値はミリメートル単位で指定し マーカの中央に原点を置きたい場合は 以下のように指定する double center[2] = {0.0,0.0; 原点をずらして右上を原点にして3DCG を表示させたい場合はそれぞれの座標を- 4.0 にパラメータを設定することで座標をずらして原点を置くことが可能である patt_width はマーカのサイズで マーカの一辺の長さをミリメートル単位で設定する この値を正しく設定しないと 実世界における長さの単位と 表示させた3DCG の長さの単位が一致しないので注意が必要である patt_trans[3][4] ではマーカ座標系からカメラ座標系への座標変換行列で計算された結果を格納している これらのマーカやカメラの位置 姿勢を計算してから3D オブジェクトを表示している 図 4-4 座標変換行列 [9] (Xc, Yc, Zc, 1) はカメラ座標系を (Xm, Ym, Zm, 1) にはマーカ座標系 R3*3 に回転要素 T3*1 に平行移動要素を示している ( 図 4-4 参照 ) これらのように ARToolKit で求められた座標変換行列を用いてマーカ座標にカメラ座標を変換 ( 図 13

4-5 参照 ) して マーカの上に仮想物体を現実世界の映像に融合させて表示させることが可能になるのである 図 4-5 カメラ座標とマーカ座標の関係 (7) バッファの内容を画面に表示 ARToolKit のグラフィックス処理系ではダブルバッファが使われており 画像や CG を連続で描画する際にちらつきが起きないようにするための仕組みがある 表画面と裏画面という2つのバッファを用意して表画面を表示している間に裏画面に描画し 表と裏を入れ替えることにより 描画の過程を表にださないようにするという考え方がダブルバッファである argswapbuffers() 関数が表画面と裏画面を入れ替える役割をしている 第 3 節オブジェクト描画関数 DrawObject() 以下にプログラムを示し 内容を説明する void DrawObject(void) { double gl_para[16]; // 3D オブジェクトを描画するための準備 (1) argdrawmode3d(); argdraw3dcamera( 0, 0 ); // 座標変換行列の適用 (2) argconvglpara( patt_trans, gl_para ); glmatrixmode( GL_MODELVIEW ); glloadmatrixd( gl_para ); // 3D オブジェクトの描画 (3) gltranslatef( dx, dy, dz ); // オブジェクトの移動 glrotatef( rot, 0.0, 0.0, 1.0 ); glrotatef( 90.0, 1.0, 0.0, 0.0 ); gltranslatef( 0.0, 0.0, 20.0 ); glcolor3f( 0.0, 1.0, 0.0 ); gllinewidth( 3.0 ); glutwireteapot( 40.0 ); (1) 3D オブジェクトを描画するための準備 14

3 D オブジェクトを描画する前に argdrawmode3d() 関数と argdraw3dcamera() 関数を実行する必要がある argdrawmode3d() は 3 次元空間における座標系の状態を保存している OpenGL の行列を初期化する関数である argdraw3dcamera() は カメラパラメータに基づいて仮想空間における視野の範囲を決めて撮影する仮想カメラの射影変換の設定を行う関数である (2) 座標変換行列の適用 AR アプリケーションでは 座標変換行列を ARToolKit 形式から OpenGL 形式にフォーマットさせる必要があるので argettransmat() によって得られた座標変換行列をモデルビュー行列に適応させて 以後の作業をマーカ座標系の上で行えるようにします argconvglpara( patt_trans, gl_para ) は ARToolKit 形式である argettransmat(&marker_info[k], patt_center, patt_width, patt_trans) で求めた座標変換行列を OpenGL 形式に変換し gl_para に格納する役割をしている glmatrixmode( GL_MODELVIEW ) 関数は 現在の座標変換行列をモデルビューに変換してから glloadmatrixd( gl_para ) 関数でマーカの中心を原点とする座標系にすることで 以後の 3D オブジェクトの描画と操作は OpenGL の関数によって行います OpenGL の特徴は長さの単位を 実世界と同じミリメートル単位で扱えることである ただし これを実現するためには 座標変換行列を計算する際にマーカの大きさが正しく設定されていることが前提である (3)3D オブジェクト描画ここでは オブジェクトの色や描画する図形の種類 線の太さなど様々な設定を OpenGL の命令を用いて行う glcolor3f( 1.0, 0.0, 0.0) では赤色の 3D オブジェクトを描画する色を指定する命令である パラメータは赤 緑 青の順に並んでいる gllinewidth() 関数は線の太さをピクセル単位で指定するものである また 初期値は 1.0 になっている これらの設定はオブジェクトを描画する前にあらかじめ行っておく必要がある OpenGL の補助ライブラリである GLUT には 立方体や球体 ティーポットやそれらのワイヤーフレームなどの3D オブジェクトがあらかじめ関数として用意されており その関数を用いることで簡単にオブジェクトを表示することが可能である 立方体の描画関数 (glutsolidcube() 球体の描画関数(glutSolidSphere()) ティーポットの描画関数 (glutsolidteapot()) など様々な関数が用意されている ( 図 4-6 参照 ) 他に平行移動関数(glTranslatef()) 回転関数(glRotatef()) 拡大 縮小 (glscalef()) などを使って 3D オブジェクトに動きや変化を付加することが可能である 15

図 4-6 3D オブジェクトの球体 第 4 節キーボード入力処理関数 KeyEvent() void KeyEvent( unsigned char key, int x, int y ) { // ESC キーを入力したらアプリケーション終了 if( key == 0x1b ){ Cleanup(); exit(0); // 初期値へ キーボード入力処理関数はプログラムの初期化時に argmainloop() 関数で登録している関数である 本プログラムでは ESC キーを押すとプログラムを終了するように設定している 第 5 節マウス入力処理関数 MouseEvent() void MouseEvent(int button, int state, int x, int y) { // 入力状態を表示 printf(" ボタン :%d 状態 :%d 座標 :(x,y)=(%d,%d) \n", button, state, x, y); マウス入力処理関数は画像を表示しているウィンドウをクリックしたときにこの関数が呼ば れる 引数 button には押されたボタンの種類 state にはボタンの状態 x,y にはマウスポインタの座標値が渡される クリック時のマウスポインタの x 座標と y 座標を表示させている例を図 4-7 に示す 16

第 6 節終了処理関数 Cleanup() void Cleanup(void) { arvideocapstop(); arvideoclose(); argcleanup(); 図 4-7 マウスポインタの座標 // ビデオキャプチャの停止 // ビデオデバイスの終了 // グラフィック処理の終了 終了処理関数では ビデオキャプチャを停止 終了させ グラフィック処理系の終了処理を行う arvideocapstop() 関数は arvideocapstart() 関数と対になっていてビデオキャプチャ処理はスタートさせたら必ずストップさせる必要がある また 同様に arvideoclse() 関数も arvideoopen() 関数と対になっており Open したビデオデバイスは必ず Close させる 17

第 5 章作成した 3DCG モデルの応用 ARToolKit では OpenGL の補助ライブラリである GLUT で用意されている 3D オブジェクトだけでなく 自ら作成した 3DCG モデルを表示することも可能である これを利用することにより 3DCG モデルに動きをつけてアニメーション表示させる 第 1 節 3D モデル描画 Metasequoia( メタセコイア ) でモデリングした MQO 形式の3DCG を ARToolKit 上で表示する まず Metasequoia とは Osamu Mizuno が開発した 3D ポリゴンモデラー ( 図 5-1 参照 ) である [10] ポリゴンメッシュによる3DCG 作成に特化したソフトウェアである データの可変性を重視しており 様々なファイル形式で出力することが特徴である ただし ARToolKit で利用するためには メタセコイアオブジェクト (*mqo) で保存する 図 5-1 メタセコイアの起動画面 第 2 節 GLMetaseq 関数 Metasequoia で作成した MQO 形式の 3D モデルを ARToolKit のプログラムで表示 ( 図 5-2 参照 ) させるために用いるのが GLMetaseq 関数である この GLMetaseq 関数は工学ナビ [11] で配布している OpenGL で MQO ファイルを表示するための C/C++ 言語用のライブラリである これを用いることで自作の 3DCG モデルを簡単に拡張現実世界で表示させることが可能である 18

図 5-2 ARToolKit で表示させた自作 3DCG モデル (1)GLMetaseq の初期化 mqoinit(); これはプログラム開始時に行なう必要がある 初期化を行なう関数は mqoinit() である また mqoinit() 関数はかならずウィンドウ設定の arginit() 関数より後に行なう (2) モデルの読み込み if ((model = mqocreatemodel( mqo_name, 1.0)) == NULL ){ printf(" モデル読み込み失敗 \n"); mqocreatemodel() 関数を使って MQO ファイルからモデルデータの読み込みを行なう モデル情報を読み込みメモリに格納し MQO_MODEL 型という GLMetaseq で定義されているオリジナルの型に値を返す この中にはモデル情報を格納している領域を保持しているのである 以後はこの値を使ってモデルの描画と削除を行なっている この関数の引数はモデルのファイル名と大きさを指しており 1.0 で当倍である (3) モデルの描画 glpushmatrix(); glrotatef( 90.0, 1.0, 0.0, 0.0 ); mqocallmodel( model ); glpopmatrix(); mqocallmodel() は読み込んだモデルを画面に描画する関数である 引数に MQO_MODEL 型の変数を指定している Metasequoia の作成画面とは異なっており Y 軸が上を向いているものを ARToolKit ではマーカが Z 軸が上を向いているため この関数を呼ぶ前に座標を X 軸まわりに90 度回転させる必要がある これは glrotatef() で軸を調整している (4) モデルの削除 19

mqodeletemodel( model ); 不要になったモデルを mqodeletemodel() 関数によって削除する プログラムの終了時に ファイル読み込みを行なった全ての変数に対してモデルの削除を行なう必要がある また モデルの削除を行なった変数に対して mqocreatemodel() 関数で新しいモデルを読み込むことも出来る (5) GLMetaseq の終了処理 mqocleanup(); プログラムの終了時に GLMetaseq の終了処理も行なう必要があり これを行なう関数が mqocleanup() である これは mqodeletemodel() でモデルの削除した後に実行する 第 3 節モーションの連番 MQO 出力 Metasequoia で作成した3D モデルをアニメーションにして ARToolKit で表示する まず3D モデルに動きをつけて連番にして出力するために RokDeBone2 () というモーション作成ソフト ( 図 5-3 参照 ) で生成する このソフトウェアは MQO ファイルに動きを付けてパラパラ漫画の要領でフレームごとに連番ファイルとして出力する 連番 MQO 出力 機能を利用してアニメーションを作ることが出来る GLMetaseq では MQO_SEQUENCE 型を使ってアニメーションを ARToolKit で表示出来る この型は モデルとフレーム数を格納している これは 1 節で作成した 3DCG の人形にモーションをつけて表示させる 人形にはその場で手足を交互に動かさせて歩行をしているように見せるモーションを付加することにする 図 5-3 RokDeBorn の起動画面 (1) シーケンスの作成 MQO_SEQUENCE mqo_seq mqo_seq = mqocreatesequence( seq_name, n_frame, 0.05 ); if( mqo_seq.n_frame <= 0 ){ printf(" シーケンス読み込み失敗 \n"); return -1; 20

mqo_seq.now_frame = 0; printf(" シーケンス作成完了 \n"); 連番 MQO アニメーションを作るために MQO ファイルから生成したアニメーションをシーケンスとして扱い mqocreatesequence() 関数を使って連番 MQO ファイルからシーケンスを作成する seq_name には連番アニメーションのファイル n_frame にはアニメーションのフレーム数がそれぞれ格納されている 0.05 は 3DCG モデルの大きさを表している (2) シーケンスの描画 Static int j = 0; mqocallsequence(mqo_seq,j); j++; if( j >= n_frame ) j = 0; mqocallsequence() 関数を使ってアニメーションを描画させます jには連番アニメーションのシーケンスから表示させたいフレーム番号を表しており順に描画させている フレームの上限に達した場合 jを0に戻して繰り返して 順番に描画する (3) シーケンスの削除 mqodeletsequence( mqo_seq ); MQO_MODEL の時とどうように MQO_SEQUENCE でも削除用の関数があり シーケンスを終了する場合には mqodeletesequence() 関数によってシーケンスの削除を行う 21

第 6 章マルチマーカの考察 本章では前述したプログラムを応用して複数の模様の違うマーカを使ってそれぞれのマーカに別々のコマンドとしての役割を与えて実験することが目的である まず 3DCG は前章で使用したものを使うこととする パターンファイルは図 6-1 から図 6-4 に示す 4 種類を使うこととする 図 6-1 hiro 図 6-2 kanji 図 6-3 sample1 図 6-4 sample2 これら4つにマーカには以下のコマンドを設定することにする 1 [hiro]: マーカの上に 3DCG を表示させる 2 [hito]: 表示している 3DCG をキューブに変える 3 [sample1]: 表示している 3D オブジェクトを回転させる 4 [sample2]:[hiro] マーカから [sample2] マーカ上まで 3D オブジェクトを移動させる 第 1 節構造体 これまでのマーカを1つだけ使う場合は 以下に記述してある5つの変数でパターンファイルを管理している [13] char *patt_name = "Data/patt.hiro"; int patt_id; // パターンID double patt_trans[3][4]; // 座標変換行列 double patt_center[2] ={ 0.0, 0.0 ; // パターン中心座標 double patt_width =80.0; // パターンサイズ しかし 複数のマーカを個別に識別して管理する必要があるため これらを 1 つにまとめて以下に記述する構造体として管理する define PTT_NUM 4 // マーカの数 define PTT1_MARK_ID 0 define PTT1_PATT_NAME "Data\\patt.hiro" define PTT1_SIZE 80.0 define PTT2_MARK_ID 1 define PTT2_PATT_NAME "Data\\patt.kanji define PTT2_SIZE 60.0 define PTT3_MARK_ID 2 define PTT3_PATT_NAME "Data\\patt.sample1" define PTT3_SIZE 60.0 // パターン.hiro // パターン.kanji // パターン sample1 22

define PTT4_MARK_ID 3 define PTT4_PATT_NAME "Data\\patt.sample2" define PTT4_SIZE 60.0 // パターン sample2 typedef struct { char *patt_name; // パターンファイル名 int patt_id; // パターンID int mark_id; // マーカID int visible; // 検出 double width; // パターンの幅 double center[2]; // パターンの中心座標 double trans[3][4]; // 座標変換行列 PTT_T; PTT_T object[ptt_num] = { {PTT1_PATT_NAME, -1, PTT1_MARK_ID, 0, PTT1_SIZE, {0.0,0.0, {PTT2_PATT_NAME, -1, PTT2_MARK_ID, 0, PTT2_SIZE, {0.0,0.0, {PTT3_PATT_NAME, -1, PTT3_MARK_ID, 0, PTT3_SIZE, {0.0,0.0, {PTT4_PATT_NAME, -1, PTT4_MARK_ID, 0, PTT4_SIZE, {0.0,0.0 ; 1つのマーカで処理していた5つの変数で管理していたものに mark_id と visible を追加した mark_id にはパターンファイルを識別するために PTT1_MARK_ID などに格納した番号をそれぞれに与えるためのものである visible は パターンファイルごとに見つかったマーカが一致するか一致しないかを表すために使う 第 2 節パターンファイルのロード マーカを複数個使うのでそれぞれのパターンファイルを PTT_NUM に登録された数だけ arloadpatt() を実行するように書き換える また パターンファイルのロードに失敗した場合はどのパターンファイルか特定するために読み込みに失敗したパターンファイルを表示させる for (i = 0; i < PTT_NUM; i++){ if ( (object[i].patt_id = arloadpatt(object[i].patt_name)) < 0 ) { printf(" パターンファイルの読み込みに失敗しました : %s\n",object[i].patt_name); return -1; 第 3 節マーカの信頼度の比較 これもパターンファイルのロードと同じで PTT_NUMの値だけ繰り返す Webカメラでキャプチャした画像に一致するパターンファイルが検出されなかった場合にはパターンファイルごとに用意されているobject[i].visibleに 0 を入れて前の処理を繰り返す for (i = 0; i < PTT_NUM; i++){ k = -1; for( j = 0; j < marker_num; j++ ) { if ( object[i].patt_id == marker_info[j].id ) { if ( k == -1 ) k = j; else if ( marker_info[k].cf < marker_info[j].cf ) k = j; 23

if ( k == -1 ) { // 3D オブジェクトの描画 object[i].visible = 0; continue; 第 4 節 3Dオブジェクトとマーカの役割本節では マーカにそれぞれの役割を与えることでマーカにコマンドとしての意味を持たせる 一致するパターンファイルがあった場合 argettransmat() が実行され object[i].visibleに1を入れる // 座標変換行列取得 else{ argettransmat(&marker_info[k], object[i].center, object[i].width, object[i].trans); object[i].visible = 1; if(object[1].visible == 1) cube = 1; else cube = 0; if(object[2].visible == 1) exrz = exrz + 5.0; if (object[3].visible == 1){ // マーカ 1 の座標でカメラの位置を取得 arutilmatinv(object[0].trans, wmat1); // マーカ 2 の座標でカメラの位置を取得 arutilmatmul(wmat1, object[3].trans, wmat2); extx = extx + (wmat2[0][3] * 0.01); exty = exty + (wmat2[1][3] * 0.01); else{ if(wmat2[0][3] > 0){ if(extx >= wmat2[0][3]){ extx = wmat2[0][3]; exty = wmat2[1][3]; else{ if(extx <= wmat2[0][3]){ extx = wmat2[0][3]; exty = wmat2[1][3]; extx = 0.0; exty = 0.0; // オブジェクトを描画 if (object[0].visible == 1){ draw(object[0].trans); 24

if (object[0].visible > 0 && object[3].visible > 0){ arutilmatinv(object[0].trans, wmat1); arutilmatmul(wmat1, object[3].trans, wmat2); printf("%5.3f %5.3f %5.3f\n", wmat2[0][3], wmat2[1][3], wmat2[2][3]); ここでは以下の処理を行っている object[0].visible == 1 [hiro] を検出した時 マーカが一つの時と同じようにマーカの上に 3DCGを表示する ( 図 6-5 参照 ) 図 6-5 object[0] visible == 1 object[1].visible == 1 [kanji] を検出した時 3DCGをキューブに切り替える もし visibleに 0 が入っていたら 3DCGを表示する ( 図 6-6 参照 ) 図 6-6 object[0] [1] visible == 1 object[2].visible == 1 [sample1] を検出した時 3DCG を回転させる ( 図 6-7 参照 ) 25

図 6-7 object[0] [2] visible == 1 object[3].visible == 1 [sample2] を検出した時 object[0].visibleでマーカの上に表示された 3DCGをobject[3] のマーカに移動させる マーカの上に着くと 3DCGはその位置で停止する ( 図 6-8 参照 ) 図 6-8 object[0] [3] visible == 1 また [sample2] マーカが表示されている間 [hiro] マーカから見た [sample2] マーカの位置情報 ( 図 6-9 参照 ) を表示する これは 3DCGの移動する向きと距離を出すために wmatの配列を利用する wmatから得た座標に近づけるための計算をしている 26

図 6-9 2 つのマーカ間の距離 上記 object[1] から [3] の動作は object[0] の [hiro] マーカを検出して 3DCG を表示させているときに限る また 役割を設定した全てのマーカを検出した場合には全ての動作を組み合わせた状態を表示する つまり object[0] で 3DCG が表示され object[1] で 3DCG がキューブとして表示され object[2] で 3DCG を回転 object[3] で sample2 マーカの位置まで 3DCG を平行移動させる ( 図 6-10 参照 ) 図 6-10 object[0] [1] [2] [3] visible == 1 27

第 7 章まとめ ARToolKit のライブラリを利用して AR アプリケーションの開発を行ってきた 3DCG やマーカを工夫して利用することで様々な複雑な動きや改良が可能であることが分かった 本論文では複数マーカを利用した AR アプリケーションの開発において構造体を使うことで簡単にマーカごとのコマンドを設定することが出来た また コマンドを設定するにあたって2つのマーカ間の位置関係を取得することで マーカからマーカへの 3DCG の平行移動を可能にした これを利用して マーカ間の位置関係を記録させて相対的な位置関係にある複数のマーカを1つのマーカとして扱うマルチマーカにすることも可能だと思われる また もっと多くのコマンドとマーカ 3DCG モデルを用いることでカードゲームなどへの利用も可能である これからの AR アプリケーションの開発において パソコンと Web カメラでは利用出来る場所が限られてしまうことで改良する幅が狭められてしまうことが問題である 今後の課題としては 利用する場所が限定されない iphone などのネットワークを利用した携帯端末用の AR アプリケーション開発を目指す 28

参考文献 [1]http://www.hitl.washington.edu/artoolkit/ [2]http://www.bmw.co.uk/bmwuk/augmented_reality/homepage?bcsource=vanity [3] http://www.iajapan.org/review/pdf/iajreviewvol9-3.pdf [4]http://sekaicamera.com/ [5]http://ar3d.jp/ [6] http://plusd.itmedia.co.jp/mobile/articles/1008/27/news027.html [7]http://www. xmission.com/~nate/glut.html [8] 橋本直 : ARToolKit 拡張現実感プログラミング入門 発行所 : 株式会社アスキー メディアワークス,2008. [9] http://www.metro-cit.ac.jp/~yamasho/pdf/2010surika.pdf [10] http://www.metaseq.net/metaseq/index.html [11]http://kougaku-navi.net/ARToolKit.html#MakeModel [12] http://www5d.biglobe.ne.jp/~ochikko/ [13] 谷尻豊寿 : ARToolKit プログラミングテクニック 発行所 : 株式会社カットシステム,2008. 謝辞 研究を進めるにあたりプログラムの作成や開発環境の設定などで助言をいただいた花川ゼミの高橋一氏に感謝します 本論文を作成するにあたりご指導をいただいた 花川典子先生に感謝します 29