仮想世界と現実世界を融合する技術は,拡張現実感(Augmented Reality:AR)と呼ばれています.

おおげさな言い方をするとARは現実の世界に情報を「上書き」することができる技術です. アニメや映画にでてくる「電脳」を想像してみてください.手のひらの上に3Dキャラクタを表示したり, 現実の世界でデジタル・データに触れてみたり… そんな魔法のような技術です.

ARToolKit はARアプリケーションの実装を手助けするC言語用のライブラリです. ARToolKitを使うと,紙に印刷されたパターンをカメラで読み取り, その上に3Dオブジェクトをオーバーレイ表示するアプリケーションが簡単に作れます. 本来は非常に敷居の高い技術なのですが,このライブラリは「難しい部分」の処理を全てやってくれます.

…というわけで今回はARToolKitを使って近未来の技術 「拡張現実感」 を体験してましょう.


橋本 直 (公開:2007年06月01日/最終更新:2014年11月5日)

目次

    

この記事を読んで最終的に何が作れるのか知りたい人は,先に 「ARToolKitでフィクションの世界を体験しよう」に飛んでください. USBカメラさえあれば,プログラミングの話をすっとばしていきなり拡張現実感ソフトで遊べます!

はじめに

これを読んで得られるもの

ここに書いてある内容をそのままやれば,

はずです.


用意するもの


実験を行った基本ソフトウェア環境

今回のコラム執筆にあたり,実験を行った環境は以下のとおりです.

他のプログラミング環境でも大差はないと思いますので適当に読み替えてください. Visual C++ 6.0 は開発環境としてはかなり古いです. マイクロソフトからVisual C++ 2008 Express Edition(無償版)が配布されていますのでそちらを利用してください. VC2008でのインストールについては以下のページを参考にしてください.
ゼロからはじめるARToolKit on VisualC++ 2008 Express Edition

ARToolKit と GLUT の入手

ARToolKitのダウンロード

ARToolKitは加藤博一先生(現在,奈良先端科学技術大学院大学 教授)とワシントン大学HITL(Human Interface Technology Lab)によって開発されました. ARToolKitはフリーで提供されており,ARToolKit Home Page よりダウンロードすることができます.


ダウンロードページ から以下の3つのファイルをダウンロードしてください.
【ページの辿り方】

最初のページ

その次のページ

ここからダウンロードする

GLUTのダウンロード

ARToolKitの3Dグラフィックス処理の部分にはOpenGLおよびGLUTが使われています. OpenGLはDirectXと並んで有名な3Dグラフィックス・プログラミングライブラリです. そしてGLUTはその補助ライブラリです.OpenGLは標準のライブラリとしてVCの中に含まれていますが, GLUTについては別途ダウンロードする必要があります.


GLUT for Win32のページ から以下のファイルをダウンロードしてください.

ARToolKit と GLUT のインストール

GLUTをインストールしてからARToolKitをインストールしてください.


GLUTのインストール

以下の手順で進めてください.

  1. まず,glut-3.7.6-bin.zipを解凍してください.
  2. 「glut32.dll」を「C:\windows\system32」に入れてください.
  3. 「glut.h」を自分の開発環境の「include\GL」フォルダに入れてください.
     <VisualC++6.0の場合>
      C:\Program Files\Microsoft Visual Studio\VC98\Include\GL

  4. 「glut32.lib」を自分の開発環境の「Lib」フォルダに入れてください.
     <VisualC++6.0の場合>
      C:\Program Files\Microsoft Visual Studio\VC98\Lib

ARToolKitのインストール

以下の手順で進めてください.

【1】 ファイルの解凍とコピー

  1. ARToolkit-2.71.2.tgz,DSVL-0.0.8b.zip,OpenVRML-0.14.3-win32.zipをそれぞれ解凍してください.
    解凍すると「ARToolKit」「DSVL」「OpenVRML」という3つのフォルダができます.
  2. 「ARToolKit」の中に「DSVL」と「OpenVRML」を移してください.
  3. 「ARToolKit」を「C:\Program Files\」に移してください.
  4. 以下の3つのDLLファイルを「ARToolkit\bin\」にコピーしてください.
    • ARToolKit\DSVL\bin\DSVL.dll
    • ARToolKit\DSVL\bin\DSVLd.dll
    • ARToolKit\OpenVRML\bin\js32.dll
  5. ARToolKit\Configure.win32.bat」をダブルクリックして実行してください.
【2】 VisualC++の設定
  1. まずはインクルードファイルとライブラリのパスを通しておきましょう.これは開発環境にファイルの場所を教える作業です.
    VisualC++のメニューを「ツール>オプション」とたどり,出てきたダイアログの「ディレクトリ」タブをクリックします.
    まず「表示するディレクトリ」を「インクルードファイル」にした状態で,下の空白の横にある「...」ボタンをクリックして

       C:\PROGRAM FILES\ARTOOLKIT\INCLUDE

    を追加してください.
    次に「表示するディレクトリ」を「ライブラリファイル」にした状態で,同様にして

       C:\PROGRAM FILES\ARTOOLKIT\LIB

    を追加してください.できたらOKボタンを押します.




  2. 次にライブラリとサンプルプログラムを自分でコンパイルして作成します.
    ARToolKit\ARToolKit.dsw」をVisualC++で開いてください.

  3. VisualC++のメニューを「ビルド>バッチビルド」とたどり,「ビルド」をクリックしてください.



  4. ライブラリとサンプルプログラムのコンパイルが実行されます.終わるまで待ちましょう.
    これが終わればすべて終了です!

これでようやくARToolKitでプログラムを作る準備が整いました!


コンパイル済みのバイナリ

「コンパイルが面倒だ」あるいは「コンパイルがうまくいかない」という人のためにコンパイル済みのもの(バイナリ) が公式のダウンロードページで配布されています.ARToolKit-2.72.1-bin-win32.zip というファイルです.こちらを利用しても構いません.

とりあえずサンプルプログラムで遊んでみる

ライブラリを入れたあとの恒例行事「サンプルで遊ぼう」です. まずは手っ取り早く拡張現実感とやらを体験してみましょう!


マーカの印刷

ARToolKitで作るアプリケーションは「マーカをカメラで撮影すると,そこに3Dオブジェクトが現れる」アプリです. そこで,まずはマーカを用意しなくてはいけません. 「C:\Program Files\ARToolKit\patterns」の中にはマーカのパターン(図柄)がPDF形式で入っています. この中にある「pattHiro.pdf」を紙に印刷してください.


「Hiro」は開発者(加藤博一先生)の名前に由来?



サンプルプログラムを動かしてみよう

USBカメラをPCにセットしたら他のキャプチャプログラムが動いていないことを確認してください. サンプルプログラムは「C:\Program Files\ARToolKit\bin」の中に入っています. この中にある「simpleLite.exe」をダブルクリックで起動します.


起動するとこのような画面が表示されます.

  

そのままOKを押すと,ウィンドウがでてきてカメラ映像が表示されます.
この状態で,先ほど印刷したマーカを撮影してみましょう.



マーカに描かれたパターン全体が画面内に収まるように撮影すると…

立方体が表示されたぞ!!!

いかがでしょうか? 「こんな手軽に!?」と驚かれたかもしれません. マーカを回転させたり傾けたりするとそれにあわせて上にのっている3Dオブジェクトも動きます. ARToolKitの本当の凄さは,こんなプログラムを自分で簡単に組めるところにあります.


もし画面が真っ黒になる場合は,使用するカメラを直接指定

PCに複数のカメラ(USBカメラ,ソフトウェアカメラ,キャプチャカード,TVチューナなど)が接続されている場合, うまくいかないことがあります.これはデフォルトの設定で,最初に見つけたデバイスを使って処理をする仕様に なっているからです.

では使用するカメラの設定を変更してみましょう.サンプルプログラムが利用しているカメラ設定は 「C:\Program Files\ARToolKit\bin\Data」の中にある「WDM_camera_flipV.xml」 に記録されています.このファイルはメモ帳などのテキストエディタで開くことができます.


【WDM_camera_flipV.xmlの中身】
<?xml version="1.0" encoding="UTF-8"?>
<!--Sample XML file generated by XMLSpy v2005 rel. 3 U (http://www.altova.com)-->
<dsvl_input xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="省略">
	<camera show_format_dialog="true" friendly_name="PGR">
		<pixel_format>
			<RGB32 flip_h="false" flip_v="true"/>
		</pixel_format>
	</camera>
</dsvl_input>

このファイルの中の「friendly_name=」の部分を変更します. friendly name というのは製品名のことです. 「マイコンピュータ」を開くと「ローカルディスク」や「共有フォルダ」と並んで キャプチャデバイス(USBカメラ)の名前が表示されます. 接続したUSBポートによっては表示名に「#2」という感じの番号(おそらく挿してるUSBポートの番号) がつくことがありますが,この番号を除いたものを製品名としてください.



マイコンピュータから製品名をチェック

このようにして調べた製品名を使ってWDM_camera_flipV.xmlを変更します.

【変更後のWDM_camera_flipV.xml】
<?xml version="1.0" encoding="UTF-8"?>
<!--Sample XML file generated by XMLSpy v2005 rel. 3 U (http://www.altova.com)-->
<dsvl_input xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="省略">
	<camera show_format_dialog="true" friendly_name="Logicool Qcam Pro 4000">
		<pixel_format>
			<RGB32 flip_h="false" flip_v="true"/>
		</pixel_format>
	</camera>
</dsvl_input>

これで指定したカメラが選択されるはずです.


ARToolKitで使用するビデオデバイスの設定ファイルを自動生成するソフト

上の作業を自動でやるソフトを作りました. USBカメラなどのビデオキャプチャデバイスがPCに接続されている状態でこのソフトを起動すると, 自動的にデバイスの数だけ設定ファイルが作成されます.

カメラキャリブレーションをしよう

カメラキャリブレーションって何?

使用するカメラによって焦点距離やレンズ歪みなどの特性が異なります. このようなカメラの特性値(カメラパラメータ)は,画像からマーカの3次元位置姿勢を求める計算や, 3Dオブジェクトを正確に配置する処理に影響を及ぼします. より正確な計測を行うためには,事前にカメラパラメータを求める作業 (=カメラキャリブレーション)が必要になります.

公式サイト(英語)には2通りのキャリブレーション方法についての解説があります.

ARToolKit Documentation - Camera Calibration

ここでは簡単なほうの「1ステップキャリブレーション」について解説します.


キャリブレーション用のパターンを印刷する

一般的なカメラキャリブレーションでは,格子模様や等間隔ドットを印刷した紙(キャリブレーションボード) を使います.これをカメラで撮影し,画像中での格子点の位置を記録してちょっとした計算を行うことで, カメラパラメータを算出することができます. ARToolKitにはそのキャリブレーション用のパターンと,計算ツールが付属しています.

キャリブレーションで使うパターンは以下のPDFファイルです.

   C:\Program Files\ARToolKit\patterns\calib_dist.pdf

これを紙に印刷してください.(プリンタがない場合はPCのディスプレイにパターンを表示することでも代用できます)



キャリブレーション用のパターン(calib_dist.pdf)

印刷したら点と点の間の長さ(点の中心でとる)を定規で測ってください. このとき,ミリメートル単位で測ることに注意してください. A4の紙に印刷した場合,38mm〜40mmくらいになるはずです. この値は後で使います.


キャリブレーションのやり方

それではキャリブレーションをやってみましょう.1ステップキャリブレーションでは以下のプログラムを使います.
   C:\Program Files\ARToolKit\bin\calib_camera2.exe


【1】calib_camera2.exeをダブルクリックして起動します.すると,以下のような表示が出ます.
Input the distance between each marker dot, in millimeters: 
「ドット間の距離をミリメートル単位で入力してください」ということなので, ここで先ほど定規で測った値を入力してエンターを押します. するとキャプチャ設定のダイアログが表示されるのでそのままOKを押してください (※解像度を変更したい場合は「出力サイズ」の項目で変更します).

値を入力するとこのように表示され,画像ウィンドウが表示されます.
Input the distance between each marker dot, in millimeters: 38
Camera image size (x,y) = (320,240)

-----------
Press mouse button to grab first image,
or press right mouse button or [esc] to quit.
argl error: Your OpenGL implementation and/or hardware's texturing capabilities
are insufficient to support rectangle textures.

【2】次に,4×6個の全ての点が画面内に収まるように撮影し,その状態で画面を1回左クリックします. このとき,キャリブレーション用のパターンは必ず平らな場所においてください.

【3】クリックすると画面が静止して特徴点記録モードに入ります.
-----------
Press mouse button and drag mouse to rubber-bound features (6 x 4),
or press right mouse button or [esc] to cancel rubber-bounding & retry grabbing.
「マウスボタンを押してドラッグして6×4個(計24個)の特徴点を選択してください. 右クリックもしくは[esc]キーで作業をキャンセルして画像を撮り直します」 という意味のメッセージが表示されます. マウスのドラッグ操作で黒い点を1つ1つ範囲選択していきます. 範囲選択している領域はモノクロで表示されます.ドラッグしてマウスボタンを離すと, 範囲内にある点の中心に赤い十字線が表示されます.この作業を24個分やります. クリックする順番が決まっているので注意してください. 下図で青い文字で書いてある数字がクリックする順番です.


左クリックすると画面が静止する

順番に点の中心を記録していこう
作業中はこのように表示されます.
Marked feature position   1 of  24
Marked feature position   2 of  24
Marked feature position   3 of  24
Marked feature position   4 of  24
Marked feature position   5 of  24
【4】全ての点に対する作業を終えると以下のように表示されます. 「左クリックで特徴点を保存します.右クリックまたは[esc]キーでやり直しをします」 と言っているので,正しくポイントできていればもう一度画面を左クリックしてください.
Marked feature position  24 of  24

-----------
Press mouse button to save feature positions,
or press right mouse button or [esc] to discard feature positions & retry grabbi
ng.
【5】左クリックすると,先ほどの作業で指定した点の座標値が表示され,画面の静止状態が解除されます. 画面には「左クリックで次の画像を取り込みます.右クリックまたは[esc]キーで歪みパラメータを求めます」 と出ていますが,キャリブレーションには2枚以上の画像を必要とするため,ここでもう一度 【2】〜【4】の作業を繰り返します.
-----------
Press mouse button to grab next image,
or press right mouse button or [esc] to calculate distortion parameter.
【6】2回目の特徴点クリックが終わったら画面を右クリックします.すると計算が行われた後, 以下のメッセージと共に,点間を赤線で結んだ画像が表示されます.
-----------
Checking fit on image   1 of   2.
Press mouse button to check fit of next image.


この図のように,対角線と格子点が正しく交差している画像が表示されればOKです. 画面を左クリックすると,次の画像が表示されます.
-----------
Checking fit on image   2 of   2.
Press mouse button to calculate parameter.
2枚とも対角線と格子線が正しく表示されているのが確認できたら,画面を左クリックします.

【7】計算が行われた後,以下のメッセージが表示されたら成功です. 「キャリブレーションは成功しました.ファイル名を入力してカメラパラメータを保存してください」 と言っているので適当なファイル名(例えばmy_camera_para.dat)を入力し,エンターを押します.
Calibration succeeded. Enter filename to save camera parameter to below.
--------------------------------------
SIZE = 320, 240
Distortion factor = 105.000000 81.500000 -30.700000 0.986381
750.89434 0.00000 155.00000 0.00000
0.00000 1999.36684 32.50000 0.00000
0.00000 0.00000 1.00000 0.00000
--------------------------------------
Filename: 
【8】カメラパラメータファイルは「C:\Program Files\ARToolKit\bin」の中に生成されます. これでキャリブレーションは終了です.

サンプルプログラムが利用しているデフォルトのカメラパラメータファイルは以下のファイルです.
   C:\Program Files\ARToolKit\bin\Data\camera_para.dat

このファイルといま自分が作ったファイルを置き換えれば,自分の使っているカメラで 高精度なオーバーレイ表示ができます.

自分でマーカを作ってみよう

ARToolKitで作られたプログラムは,マーカのパターン情報を記録したファイル(以下パターンファイルと呼びます) を実行時にロードしています. 例えば,サンプルプログラムのsimpleLite.exeは,マーカ認識に「C:\Program Files\ARToolKit\bin\Data」の中にある 「patt.hiro」を使っています.このファイルは自分で作成することができます.ここではその手順について解説します.


パターンをデザインする

ARToolKitのマーカは,黒い正方形の太枠の中に,白黒または カラーの図案があるものを使用します. この条件さえ満たしていれば,自分で任意のパターンを作成することができます. ただし,カラーの図案は,カメラやプリンタの色再現性が認識性能に影響を及ぼすので注意してください. パターンは任意のペイントソフトで描けます. 印刷して使うのでファイル形式は問いません. また,紙にペンで手描きデザインしたものでもOKです.



MSペイントでもパターンは作れる.中に描くのは文字がオススメ.

パターンの大きさは任意です.黒い太枠の外側に少し白い領域があったほうがいいです. ちなみに四角の中に書く絵は,なるべく非対称で方向性のある絵・文字にしたほうがいいです (パターン認識時に座標系の方向が反転するのを防ぐためです). また,複数のパターンを用いるときは,回転させたときに同じ形が存在しないようにデザインする必要があります.


マーカの黒枠の太さについて

この記事を公開してから結構時間が経ってから知ったことなのですが,ARToolKitのマーカのパターンは 黒枠部分とコード部分の大きさに暗黙的な条件があるようです(情報源は開発者ご本人).

ソースコード上では「黒枠:白コード領域:黒枠」の比が「1:2:1」になることを前提にしています. コード認識処理の部分でその条件を前提に,コード領域を正規化して認識しているので, この条件から極端に離れたデザインになっていると認識がうまくいかない可能性があります (ちなみに四角形抽出処理は無関係).

公式的には「付属のブランクマーカ(ARToolKit\patterns\blankPatt.gif)をベースに作ってね」ということになっているようです. もちろんこの条件から外れるといきなりアウト,というわけではありませんが,精度の点で考えるとなるべくこの暗黙のルールに従うべきでしょう.



パターンファイル作成ツールの使い方

ARToolKitに付属しているパターンファイル作成ツールは優れものです. なんとカメラで直接撮影してパターンファイルが作成できます. 画像ファイルの形式に関係なく,手描きのパターンでも作れるのはこのためです.

パターンファイル作成ツールは以下のプログラムです.
   C:\Program Files\ARToolKit\bin\mkpatt.exe


【1】mkpatt.exeを起動すると以下のメッセージが表示されます.
Enter camera parameter filename(Data/camera_para.dat): 
ここで使用するカメラパラメータファイルを入力します. そのままエンターを押せばデフォルトの「Data/camera_para.dat」が選択されます.

【2】キャプチャの設定ダイアログが表示されたら「OK」を押します.すると画像ウィンドウが表示されます.
【3】カメラで物体を撮影したときに,画面内にパターンの条件を満たす矩形領域があれば, 赤と緑の線で囲まれます.


ディスプレイに表示されているパターンをカメラで撮影しているところ
(作成したパターンが赤と緑の線で囲まれています)

自分で作ったパターンを紙に印刷するか,PCのディスプレイ上に表示するかして,それをカメラで撮影します. パターンの左上隅が赤,右下隅が緑の線で囲まれている状態のときに画面上を左クリックします.

【4】クリックすると画面が静止して,以下のメッセージが表示されるので, 任意のファイル名(例えばpatt.kougaku)を入力します.
Enter filename: 
これでパターンファイルが作成されます. ファイルは「C:\Program Files\ARToolKit\bin」の中に保存されます.

サンプルプログラムのsimpleLite.exeは,パターン認識に「C:\Program Files\ARToolKit\bin\Data」の中にある 「patt.hiro」を使っています.このファイルといま作成したファイルを置き換えれば, 自作したマーカがちゃんと認識されるか確かめられます.

ここまでの話のまとめ

プログラミングの話に入る前に,ここまでの話を整理しておきましょう.


次は,いよいよARToolKitを使ったプログラミングの解説です!

ARToolKitによるプログラムの全体像

ARToolKitによるプログラムの全体像を下図に示します.水色の枠囲みがひとつの大きな関数だと思ってください. いろいろな処理が並んでいてさも複雑そうに見えますが,プログラマが実際につくる部分は黄色で示した部分だけです!  つまりほとんどの処理はARToolKitがやってくれる(=そういう関数が用意されている)わけです.



プログラマが作るのは黄色い部分だけ!

具体的な話をすると,main()関数の中で,初期化処理を行い,メインループ関数を起動します. その後は延々メインループが繰り返されます. メインループの中では,取得した画像からマーカを検出し, マーカの3次元位置姿勢を計算して,マーカを原点とする座標系に変換してから3Dオブジェクトを描画します. メインループの動作中はキーボードやマウスの入力を受け付けることができます. キー入力によって終了処理を呼び出すのが一般的です.

白いブロックで示されている処理は,ほとんどお約束の処理なので,サンプルコードなどからそのまま 流用できます.プログラマが作るべきメインの箇所は「どのマーカがきたら,どのモデルをどういうふうにだすか」 という箇所です.

ここで重要なのが,ARToolKitでの3Dグラフィックス処理には「OpenGL」を用いるという点です. すなわち,3Dオブジェクトの描画や操作にはOpenGLの知識が必要になります. 基礎的な知識があれば,立方体を出したり球体を出したりするくらいはすぐにできます. OpenGLでゲームを作成した経験がある人は,どんどんハマって面白いものが作れるでしょう. 「OpenGLなんか初めてだよ!」という人は,ぜひこの機会に勉強されてみてください.

サンプルプログラム simpleTest.c を解読する

ARToolKitの中に入っているサンプルプログラムのソースコードを読んで,プログラミングの仕方を勉強しましょう. ここでは,
  C:\Program Files\ARToolKit\examples\simple
の中にあるsimpleTest.cを使って説明します.これの中身が理解できれば,自分でARToolKitを使ったプログラムが作れるようになります.


メイン関数 main()

int main(int argc, char **argv)
{
    glutInit(&argc, argv); // GLUTの初期化

    init();                // 初期化関数の実行

    arVideoCapStart();     // ビデオキャプチャの開始
    argMainLoop( NULL, keyEvent, mainLoop );   // メインループに入る
    return (0);
}

メイン関数のなかに記述するのは主に初期化処理とメインループの起動です. メインループの起動はargMainLoop()によって行われます. 第1引数にマウスイベント関数,第2引数にキーイベント関数,第3引数にメインループ関数を指定します. このプログラムでは,マウスイベント関数を指定しないのでNULLとしています. メインループに入るともうメイン関数には戻ってきません.

次は,ここで使われているinit()の中身を見てみましょう.


初期化関数 init()

static void init( void )
{
    ARParam  wparam;
	
    /* ビデオデバイスの設定 */
    if( arVideoOpen( vconf ) < 0 ) exit(0);  // カメラ設定ファイルをロード

    /* ウィンドウのサイズの取得 */
    if( arVideoInqSize(&xsize, &ysize) < 0 ) exit(0);
    printf("Image size (x,y) = (%d,%d)\n", xsize, ysize);

    /* カメラパラメータの初期化 */
    if( arParamLoad(cparam_name, 1, &wparam) < 0 ) { // カメラパラメータファイルをロード

        printf("Camera parameter load error !!\n");
        exit(0);
    }
    arParamChangeSize( &wparam, xsize, ysize, &cparam ); // 解像度にあわせてパラメータを変更
    arInitCparam( &cparam );                             // カメラパラメータの設定
    printf("*** Camera Parameter ***\n");
    arParamDisp( &cparam );                              // カメラパラメータの表示

    if( (patt_id=arLoadPatt(patt_name)) < 0 ) {  // パターンファイルをロードする
        printf("pattern load error !!\n");
        exit(0);
    }

    /* グラフィックウィンドウを開く */
    argInit( &cparam, 1.0, 0, 0, 0, 0 );
}
名前が"ar"で始まるARToolKitの関数がたくさんありますね. ここでやっているのは以下の4つです. 複数のカメラを使う場合や,複数のマーカを使用する場合は多少の変更が必要ですが, 1カメラ,1マーカの簡単なアプリケーションを作る場合は,このまま流用できます. 3Dオブジェクトのロードなどはこの関数の中に追加すると良いでしょう.

メインループ関数 mainLoop()

static void mainLoop(void)
{
    ARUint8         *dataPtr;      // 画像データ

    ARMarkerInfo    *marker_info;  // 検出されたマーカの情報
    int             marker_num;    // 検出されたマーカの数
    int             j, k;

    /* カメラ画像の取得 */
    if( (dataPtr = (ARUint8 *)arVideoGetImage()) == NULL ) {
        arUtilSleep(2);   // 画像が取れなかったら2ミリ秒待って関数を出る
        return;
    }
    if( count == 0 ) arUtilTimerReset();  // タイマーのリセット

    count++;                              // 処理フレーム数のカウント
                                          // ↑これらはあとでFPSを計算するのに使う

    /* キャプチャした画像の表示 */
    argDrawMode2D();
    argDispImage( dataPtr, 0,0 );

    /* カメラ画像からのマーカの検出 */
    if( arDetectMarker(dataPtr, thresh, &marker_info, &marker_num) < 0 ) {
        cleanup(); // エラーが発生したら終了処理をしてプログラム終了

        exit(0);
    }

    arVideoCapNext();  // 次のカメラ画像を取得する

    /* 最も一致度の高いマーカを探す */
    k = -1;
    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;
        }
    }
    /* ここで,k番目のマーカが最も一致度の高いマーカとなる */

    if( k == -1 ) {        // 一致するマーカが見つからなかったら
        argSwapBuffers();  // バッファの内容を画面に描画するだけ
        return;
    }

    /* マーカの3次元位置・姿勢(マーカ・カメラ間の座標変換行列)を求める */
    arGetTransMat(&marker_info[k], patt_center, patt_width, patt_trans);

    draw();  // 描画処理(ここで3Dオブジェクトの描画をやっている)

    argSwapBuffers();  // バッファの内容を画面に表示
}

メインループ関数は,終了処理が行われるまで延々と繰り返し実行されます. マーカの検出を行う関数arDetectMarker()は,検出されたマーカの識別IDや頂点,一致度などの情報を 含んだ構造体と検出されたマーカの数を返しますが, 検出されたマーカの中からもっとも高い一致度のものを探す処理は自分で書かないといけないので 注意してください. ここで,

 marker_info[j].id  // j番目に検出されたマーカに対応するマーカID
 marker_info[j].cf  // それにどれだけ近いかを示す一致度(0.0〜1.0の値)
となっています.

ARToolKit最大の仕掛けがarGetTransMat()という関数です.この関数では 検出されたマーカの情報から,カメラ視点に対するマーカの3次元位置姿勢を計算しています. 数学的になかなかすごいことをやっているので,興味のある人は公式サイトで公開されている 論文とあわせてプログラムのソースを眺めてみることをオススメします(なかなか勉強になりますよ). この関数から得られるpatt_transが座標変換行列です.




カメラとマーカの相対的な位置関係

ここではカメラに対するマーカの位置姿勢を求めていますが,この関係を逆変換してしまえば, マーカに対するカメラの位置姿勢の情報になります.これを利用してカメラの位置を表示する デモもARToolKitの中に収録されていますので興味のある方はそちらもご覧ください(exviewという名前のデモです).


次は,このメインループ関数内で呼ばれているdraw()の中身を見てみましょう.


描画処理関数 draw()

static void draw( void )
{
    double    gl_para[16];
    GLfloat   mat_ambient[]     = {0.0, 0.0, 1.0, 1.0};
    GLfloat   mat_flash[]       = {0.0, 0.0, 1.0, 1.0};
    GLfloat   mat_flash_shiny[] = {50.0};
    GLfloat   light_position[]  = {100.0,-200.0,200.0,0.0};
    GLfloat   ambi[]            = {0.1, 0.1, 0.1, 0.1};
    GLfloat   lightZeroColor[]  = {0.9, 0.9, 0.9, 0.1};
    
    // 3D空間を描画するための設定
    argDrawMode3D();
    argDraw3dCamera( 0, 0 );

    // 隠面処理に関する記述
    glClearDepth( 1.0 );
    glClear(GL_DEPTH_BUFFER_BIT);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);
    
    /* 座標変換行列をロード */
    argConvGlpara(patt_trans, gl_para);
    glMatrixMode(GL_MODELVIEW);
    glLoadMatrixd( gl_para );

    // ライティング(照明)に関する記述
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glLightfv(GL_LIGHT0, GL_POSITION, light_position);
    glLightfv(GL_LIGHT0, GL_AMBIENT, ambi);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, lightZeroColor);
    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_flash);
    glMaterialfv(GL_FRONT, GL_SHININESS, mat_flash_shiny);	
    glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);

    // 実質,3Dオブジェクトを作っているのはこの3行!

    glMatrixMode(GL_MODELVIEW);
    glTranslatef( 0.0, 0.0, 25.0 );  // マーカ上に乗せるためにZ方向に25.0[mm]浮かす
    glutSolidCube(50.0);             // 50.0[mm]の立方体を描画

    glDisable( GL_LIGHTING );
    glDisable( GL_DEPTH_TEST );
}

ここが主にプログラマが手を加える場所だと思います. 名前が"gl"で始まる関数はOpenGLの関数です. ペイントした箇所に注目してください. argDrawMode3D()はOpenGLのモデルビュー行列を初期化する関数です. argDraw3dCamera()は3D空間の視野範囲を設定する関数です. とりあえず「3D空間を描画する前にこの2つを呼ぶ」と理解してください.

argConvGlpara()という関数は,先ほど求めた座標変換行列patt_transをOpenGL形式(4×4行列の1次元配列) に変換しています.




最初,原点(0,0,0)は目ん玉の位置(=カメラの位置)にありますが,glLoadMatrixd()によって座標変換が行われ, この関数以降はマーカの中心を原点とする座標系での作業になります. 最大のポイントはOpenGL上の長さ単位をミリメートル単位で指定できることです!  例えば,幅50.0[mm]の立方体を出したければ, そのままglutSolidCube(50.0)と指定すれば良いのです. ただし,これを実現するには,マーカの大きさが正しく設定されている必要があるので注意してください.

double          patt_width     = 80.0;  // マーカの一辺の長さ[mm]
※patt_widthはソース上部でグローバル宣言されています.


ARToolKitのグラフィックス処理

ARToolKitにおいて,カメラ画像を表示したり,射影幾何の設定を行う処理系には 「gsub」と「gsub_lite」があります. 関数名の頭が「arg」で始まるのが gsub の関数で,「argl」で始まるのが gsub_lite の関数です.

gsubの関数リファレンス(英語)
gsub_liteの関数リファレンス(英語)

gsub には GLUT によるウィンドウ処理,コールバック管理が含まれますが, gsub_lite には含まれていません. 端的に言えば, gsub_lite の場合はウィンドウやコールバック関数の管理を自分で実装することになりますが, すでに OpenGL/GLUT に慣れ親しんでいる読者の方は gsub_lite の関数を使ってコーディングしたほうが好都合かもしれません. 特に,既存のOpenGLのコードをAR化しようとする場合は gsub_lite の関数でコーディングしたほうがやりやすいでしょう.

gsub を使う場合は gsub.h をインクルードします.一方,gsub_lite を使う場合は gsub_lite.h をインクルードします. ここで説明している simpleTest.c は gsub を利用しています.gsub_lite を使っているサンプルは simpleLite.c です. gsub_lite を使っているプログラムのほうが,雰囲気的にOpenGLのコードに近いです (OpenGLのコードの上にARToolKitのコードを載せているような感じ).

gsubとgsub_liteの違いについては公式サイトの以下のページに説明があります. 要は「GLUTによる処理が入っているかそうでないか」の違いですね.

ARToolKit Documentation (ARToolKit Framework)


キーイベント関数 keyEvent()

static void   keyEvent( unsigned char key, int x, int y)
{
    /* ESCキーが押されたら終了する */
    if( key == 0x1b ) {
        printf("*** %f (frame/sec)\n", (double)count/arUtilTimer()); // FPSの表示
        cleanup(); // 終了処理

        exit(0);
    }
}

キーイベント関数はプログラムの初期化時にargMainLoop()で設定します. そうすることで,実行中にキー入力があったときにこの関数が呼ばれるようになります.

変数keyには押されたキーのキーコードが入っています. このプログラムでは,ESCキーが入力されたらFPSを表示してプログラムを終了するようになっています. 変数countには処理したフレーム数が入っています.これを時間(arUtilTimer())で割ると 1秒当たりの処理フレーム数(FPS)が求められます.

次は,ここで使われているcleanup()の中身を見てみましょう.


終了処理関数 cleanup()

static void cleanup(void)
{
    arVideoCapStop(); // キャプチャのストップ

    arVideoClose();   // ビデオデバイスを閉じる
    argCleanup();     // ARToolKitの終了処理
}

実にシンプルですね.「キャプチャを止めて終わる」それだけのようです. プログラムの処理途中にエラーが起きたときは, この関数を実行してから終わる(exit(0)する)ようにしてください.


このサンプルプログラムの仕組みが理解できれば,自分でオリジナルのARアプリケーションを 作ることができるでしょう.

自分で3Dモデルを作って現実の世界に表示させてみよう

ARToolKitプログラミングの基本的なことがわかったところで,今度は本格的に面白いことをやっていきましょう!  ここでは,フリーの3Dモデリングソフト「メタセコイア」で作ったモデルをARToolKitプログラムで 現実世界にオーバーレイ表示させる方法を紹介します.


メタセコイアを使ってモデリング

メタセコイア公式サイト

メタセコイア(通称メタセコ)は3Dのポリゴンモデルを作るためのソフトウェアです. 初心者でも扱いやすいインタフェースがうけて,多くのファンがいます. 解説本も複数出てますし,メタセコイアで作ったモデルを公開している人達もいるので 興味のある人はぜひハマってください.

メタセコイアにはフリー版とシェアウェア版があります. シェアウェア版はお金を払わないと,MQO形式以外で出力できない,プラグインが使えないなどの 制限がありますが,ほとんど不自由なく使えます. 初心者が使う分にはフリー版で十分ですが,とりあえず好きなほうをダウンロードしてください.



メタセコイアを使った3Dモデリング

※メタセコイアの使い方の解説はここではしないので,初めての人は,マニュアルを読んだり, 付属のサンプルファイルをいじったりして,使い方を覚えてください.


GLMetaseq : OpenGLでMQOファイルを表示するためのライブラリ

メタセコイアで作成された3Dモデルは「*.mqo」という形式のファイルで保存されます. このMQOファイルを読み込んで,OpenGLで表示することができるC/C++用のライブラリ「GLMetaseq」を作りましたのでぜひ使ってみてください. これを使えば,自作の3Dモデルを現実世界にオーバーレイ表示するプログラムを非常に簡単に作れます.



OpenGLで使えるメタセコイアモデルローダ
サンプルプログラム(古いGLMetaseqを同梱していますので、必要に応じて↑の新しいものに差し替えてください)

sample_GLの実行結果
(マウスでグリグリ動かせます)

sample_ARの実行結果
(マーカ「Hiro」でグリグリ動かせます)
GLMetaseqのライセンス

2009年6月16日付けで,GLMetaseqに対してMITライセンスを 適用しました.GLMetaseqを使ったプログラムを公開・販売する場合はライセンスに従ってください.

旧バージョンのGLMetaseq.h

以前配布していたものも置いておきます. 複雑になる前のコードなので,多少読みやすいかもしれません. こちらは関数本体をヘッダファイルの中に記述しているため,ソースファイルはありません. 新しいバージョンとごちゃまぜで使わないようにしてください. 関数名も異なるので注意してください.説明はファイル内に記述しています.


GLMetaseq の使い方

本ライブラリはヘッダとソースで配布しています. あなたが作成しているプログラムのプロジェクトに GLMetaseq.h と GLMetaseq.c を追加し, プログラム中で GLMetaseq.h をインクルードしてください. C++で使う場合,GLMetaseq.c の拡張子を.cppに変更する必要はありません. 以下に関数の使い方を示します.


【1】 初期化

最初に初期化を行います.初期化を行うタイミングはウィンドウを生成した後です. ARToolKitのプログラムであればargInit()より後です.

mqoInit();
【2】 ファイルからのモデルの読み込み

MQOファイルをロードします.ロードされるとMQO_MODEL型の変数にモデルの情報が記録されます. 引数はモデルのファイル名とスケールです. スケールは1.0で当倍です.スケールを0.5とすると半分のサイズで表示されます.

MQO_MODEL model;
model = mqoCreateModel( "ninja.mqo", 1.0 );
【3】 モデルの呼び出し

MQO_MODEL型の変数を指定するとそのモデルがシーンに呼び出されます. この関数は描画処理のところで使います.メタセコイア上ではY軸が上を向いてますが, ARToolKitのマーカではZ軸が上を向いていますので,適宜X軸回りに90度回転させてください.

mqoCallModel( model );
【4】 モデルの消去

プログラム終了時など,モデルが不要になった時点でモデルを削除してください.

mqoDeleteModel( model );
【5】 終了処理

プログラム終了時にはmqoCleanup()関数によってGLMetaseqの終了処理を行ってください.

mqoCleanup();

テクスチャのフォーマットについて

テクスチャ画像のサイズは「一辺が2のn乗サイズ(64,128,256…)の正方形」に限ります. テクスチャ画像の形式は,bmp,tga,jpeg,pngに対応していますが, jpegの読み込みにはlibjpegが,pngの読み込みにはlibpngがそれぞれ必要になります. また,それらを有効にするにはヘッダ内のパラメータを変更する必要があります.詳しい説明は ヘッダファイル(GLMetaseq.h)の中に書いてありますのでそちらを参照してください.

GLMetaseq を使ったプログラムでエラーが出る場合は…

そんなときは GLMetaseq.c の 205行目 のコメントアウト(//)を外してからコンパイルしなおしてみてください.

//  g_isVBOSupported = 0;

このフラグは,vertex_buffer_object(使用する頂点情報をあらかじめグラフィックカードに渡して高速化する仕組み) をサポートしているかどうかのフラグなのですが,グラフィックカードのドライバの問題で正常にチェックできないことがあるようです. また,Windows XP Service Pack 3 にアップデートした後でこの問題が生じることもあるようです.



忍者くんのモデルデータ

当サイトのマスコットキャラの忍者くんのモデルデータを以下のページで配布します.


メタセコイア形式(*.mqo)と,モーション作成ツールRokDeBone2用の形状ファイル(*.sig), モーションファイル(*.qua)を置いています. 歩くやジャンプ,刀で斬りつけるなど数種類のモーションがあります. OpenGL上でアニメーション表示をやりたいときは,RokDeBone2で連番MQO出力して, それをGLMetaseqを使ってパラパラ漫画的に表示させるのが一手です.

ARToolKitでフィクションの世界を体験しよう

ARToolKitを使ったネタをいろいろ考えてみました.今回紹介したテクニックで同じものが作れます. 実行ファイルとモデルとマーカのセットを配布しますので,プログラムが苦手な人もぜひ遊んでみてください!  もちろんソースコードも同梱しています.


「攻殻機動隊」の世界をARToolKitで!

攻殻機動隊の世界では,脳みそにマイクロマシンが注入され,文字通り「電脳化」されているので, 特別な装置なしに視界に情報をオーバーレイ表示できます.そんな彼らが見ている世界を再現してみましょう.



マークを撮影すると…

電脳空間からコンニチワ!


キーボード入力で動き回れます

光学迷彩機能もついてます

ぶっちゃけると,攻殻機動隊の世界はARよりもVR(Virtual Reality)のほうが比重が大きいんですよね.ま,いいか.


「電脳コイル」の世界をARToolKitで!

電脳コイルの世界では,電脳メガネというHMD(ヘッドマウントディスプレイ)に似たデバイスが普及しています. このデバイスを通して見ることで,電脳世界の情報を可視化することができます. まさに拡張現実感技術を実用化したような世界観です. 舞台となる大黒市では現実世界と同じ大きさのサイバースペースが構築され,現実世界と融合しています. そして,そこをうろついているのは…



『郵』の文字が反転したマーカを置くと…

『ぼくサッチーよろしくね!』


神社マークの中は郵政局の管轄じゃないので…

管理外ドメインになってしまいます


先生,そこは管轄が違うので入れません

シェーディングをOffにするとなんだかアニメ塗りに

以前配布していたバージョンでは,「サッチー」と「管理外ドメイン」は別々のプログラムだったんですが, 今回のバージョンではそれらを融合させて「サッチーは管理外ドメインに入れない」を再現してみました. キーボード操作でサッチーを動かすことができます.もちろん管理外ドメインとの当たり判定もやっています. 「シェーディングOffでなんだかアニメ塗り」と言い張るのはいささか無理があるんですが, トゥーンレンダリングを本気でやろうとするとちょっと面倒です(でも「それっぽい」でしょう?).

物理エンジンのBulletを使って,サッチーをSoftBody(やわらかいオブジェクト)で作ってあげれば, あのムニュっと感を再現できると思います.マーカを2つ使って2点間ワープさせるのも面白いですね. マーカを作中に登場する「メタタグ」に見立てると,信号機を無理やり青にするメタタグとかも実現できそうです.




サッチーのライバル,2.0 も作ってみました.こちらはVRMLを使ってアニメーションさせています. アニメーション付きのVRMLはCyberdeliaというソフトを使ってMQOファイルから作成しました. VRMLの表示にはARToolKitのAPIを使っています.ARToolKitでVRMLを表示させるサンプルは simpleVRML.c です.






本物さながらに変形します (実際のそれとは若干動きが違いますが)


動画

実際の動作風景はこんな感じです.

おわりに

今回の特集はいかがでしたでしょうか? 拡張現実感は未来を感じさせてくれる凄い技術です. 今後は携帯電話などへの応用が期待されています.ゲームに応用するといろいろと面白いものが作れますね. みなさんもARToolKitを使って面白いものをジャンジャン作ってみてください.ぜひ!


おまけ : OpenGLの参考書

ARToolKitでの3Dグラフィック処理はOpenGLで記述する仕組みになっていますが, 「OpenGLなんか使ったことない!」なんて人もいるでしょう.そんな人のためにいい参考書を ご紹介します.

OpenGLによる3次元CGプログラミング
OpenGLによる3次元CGプログラミング

入門書に最適な一冊です.非常にわかりやす書かれているのでオススメです. 書かれている通りやっていけば,誰でもOpenGLのプログラムが組めます. 難しい処理についてはそこまで詳しく書かれていませんが,これ一冊でグラフィックスプログラミングの基礎を だいたい学ぶことができます.この本を読めば,円錐,円柱,立方体などを組み合わせて簡単な3Dオブジェクトを 作ったり,簡単な光源操作くらいはできるようになります.

OpenGLプログラミングガイド 原著第5版
OpenGLプログラミングガイド 原著第5版

赤いので「赤本」と呼ばれています(青本もある).おそらくOpenGLについて最も詳しい和書です. OpenGLの仕様や,関数の解説,サンプルプログラムなど詳しい情報が網羅されています. 壁にぶつかったときは,この本とネットの情報があればたいてい解決します. OpenGLをやるなら必須な一冊なのですが,難点はお値段が高いこと?


おまけ2 : この技術についてもっと詳しく知りたい人は

拡張現実感技術(Augmented Reality : AR)は複合現実感技術(Mixed Reality : MR)とも呼ばれています. こうした技術は主に大学のバーチャルリアリティ系の研究室で研究されています. また,「タンジブルインタフェース」あるいは「実世界指向インタフェース」という分野の中で研究している グループもあります.リンク集を作ったのでそちらも参考にされてください.

  バーチャルリアリティ関連リンク集

最近はアート表現の方法として使う人たちも増えてきましたのでいろいろな角度から調べてみると 面白いと思います.


おまけ3 : ARToolKitの派生版や他の拡張現実感ライブラリ

  ARToolKitとその周辺技術のまとめ - 毛の生えたようなもの

かえるさんのブログにいい感じのまとめがありますのでそちらもご参照ください.
あまりにも良くまとまっているので丸投げさせていただきました :D


おまけ4 : AR技術やCV技術にに関する勉強会

  コンピュータビジョン・拡張現実感に関する普通じゃない勉強会

ARToolKitやOpenCVに関する楽しい勉強会を主催しています.記念すべき第1回は2008年9月に東京で開催しました.


おまけ5 : 当記事が本になりました!

3Dキャラクターが現実世界に誕生! ARToolKit拡張現実感プログラミング入門
3Dキャラクターが現実世界に誕生! ARToolKit拡張現実感プログラミング入門
アスキー・メディアワークス 2008-09-17


Amazonで詳しく見る

本書は加藤先生公認のARToolKitの入門書です. この記事がベースになっていますが,初心者〜中級者向けの情報を満載しました. 初心者向けの情報として,導入方法やプログラミング方法について,さらに優しく解説しています. また,ARToolKitプログラミングのためのOpenGL入門や3Dモデルの表示のさせ方の説明も載っています. 本のほうではVRMLの表示方法についてもサポートしています.

中級者向けのアドバンスな情報として,マルチマーカの使い方や,exviewのようなプログラムの作り方, クリックした場所にモデルを表示する方法,そしてOpenCVとの連携などいろいろな情報を詰め込みました. また,気になるARToolKitのアルゴリズムについての解説も載ってます. 是非手にとってみてください.

更新情報