マーカを検知し、画像を重ねる
AR(Augmented Reality, 拡張現実)は、現実世界の映像に、コンピュータが生成したグラフィックスを重ねて表示する技術です。ProcessingのスケッチでARを実現するライブラリが、 nyar4psgライブラリです。C言語用に開発された、オープンソースの拡張現実ライブラリARToolkitが元になっています。ARToolkitを移植して、Java言語やC#の開発環境のためのARライブラリを開発するプロジェクトがNyARToolkitで、nyar4psgはそのprocessing版です。
カメラの映像を入力し、あらかじめ登録した特徴のある目印(マーカ)が映っていたら、そこにグラフィックスを重ねるのが、基本的なしくみです。 NyIdマーカ、ARToolKitマーカ、NFTターゲット(ARToolKit5仕様の自然特徴点トラッキング)を検知できます。
Augmented Reality ライブラリ nyar4psg
nyar4psgライブラリは、次のようにインポートします。メニュー[スケッチ][ライブラリをインポート][ライブラリ-を追加]で、nyar4psgを選択して、インストールします。インストールすると、サンプルのContribute Librariesの中にサンプルが入るので、サンプルを動かして、機能を実験することができます。詳しくは、 を参照。
MultiMarkerクラスが、マーカの検出・トラッキングを行うクラスで、同時に複数のマーカを取扱えます。PImage画像から、マーカの位置、向きを検出します。
ARToolKitマーカ
検知できるARToolKitマーカは左図のような枠内に描かれたパターンで、これをMultiMarkerオブジェクトに登録することで、検知します。- ・黒枠の正方形の中に白い領域、黒枠の周りに白い領域があるもの
- ・黒枠の太さ、内側の白い領域の1辺の長さは1対2
- ・黒枠線の外側に白い領域が必要
下のサンプルで使うマーカファイルは、画像ページからコピーできます。
ARToolKitマーカ上に画像が表示されるサンプル
マーカを検知して、その上に2枚の画像を1秒ごとに交互に表示するサンプルを下に示します。- (1) ライブラリのインポート
カメラの映像を取得(キャプチャ)する必要があるので、videoライブラリもインポートします。import processing.video.*; import jp.nyatla.nyar4psg.*;
- (2) Capture, MultiMarkerオブジェクト用変数の定義
Capture video; //Captureされたカメラ画像用変数 MultiMarker nya; //マーカ検知オブジェクト用変数
- (3) Processingの画面設定
描画画面のレンダリングには、P3Dを指定する。
size(640, 480, P3D);
- (4) カメラからの映像の取得(setup()の中)
外部カメラを接続して使う場合も考慮し、カメラ映像を選択して使用する方法を説明する。まず、利用可能なカメラ映像の一覧を配列に取得し、その配列の中から使用するカメラ映像を指定する。画面サイズやデータ取得頻度の違いにより1台のカメラに複数の項目が対応する。映像の一覧の中身をコンソールに一端表示して、使用するカメラ名がこの配列のどこにあるかのインデックスを知り、その中からsize=640x480,fps=30を選択する。String[] cameras = Capture.list(); //利用可能なカメラ映像の一覧 printArray(cameras); //カメラ映像の一覧のコンソールへの表示、後にコメントアウト video = new Capture(this, 640, 480, cameras[0]); //任意のインデックスを指定
デフォルトのカメラを使う場合は、Captureからリストを得る必要はなく、次のようにするだけでいい。video=new Capture(this, 640, 480);
そして、カメラからのデータの取得をはじめる。video.start();
- (5) MultiMarkerオブジェクトの生成(setup()の中)
MultiMarkerのコンストラクタの第4引数は、ARToolKitフォーマットのカメラパラメータファイルの名前で、nyar4psgサンプルスケッチからコピーできる。第5引数は検出方法を設定する定数で、Processingと互換性のあるNyAR4PsgConfig.CONFIG_PSGを指定する。マーカ座標系を左手座標系に、姿勢推定アルゴリズムとしてNyARToolkitを使用することを意味する。nya=new MultiMarker(this, width, height, "camera_para.dat", NyAR4PsgConfig.CONFIG_PSG);
- (6) MultiMarkerオブジェクトへのマーカの登録(setup()の中)
MultiMarkerクラスのaddARMarkerメソッドを使って、ARToolKitスタイルのマーカーを登録する。
第1引数:マーカデータのPImageオブジェクト
第2引数:作成するマーカパターンの解像度で、ARToolkitと同じ16(16X16)を指定する。
第3引数:エッジ幅の割合で、ARToolKit標準マーカと同じ25%を指定する。
第4引数:マーカの物理サイズをmm単位で指定する。
nya.addARMarker(loadImage("CharPe.png"), 16, 25, 80);
- (7) カメラ映像を読み、マーカを検知(draw()の中)
video.read(); nya.detect(video);
- (8) カメラ画像を背景に描画(draw()の中)
カメラ画像を画面の背景に描画するのが、drawBackgroundメソッド。単にPImageを画面に描画するだけなら、Processingのimage()あるいはbackground()関数でも同じだが、視錐台(Frustum、カメラの見える範囲)を考慮して描画する。nya.drawBackground(video);
- (9) マーカを検知した時の処理(draw()の中)
MultiMarkerクラスのisExistメソッドは、指定されたidのマーカが有効かを返す。今マーカはひとつだけなので、idは0。if (nya.isExist(0)) { ....... }
- (10) マーカ検知の位置に描画(draw()の中)
MultiMarkerクラスのbeginTransformメソッドは、引数で指定したidのマーカ平面にProcessingの描画用座標軸を設定する。描画終了部分には必ずendTransformメソッドを実行。nya.beginTransform(0); ....... //描画 nya.endTransform();
【リストA6-1】 import processing.video.*; //(1)インポート import jp.nyatla.nyar4psg.*; Capture video; //(2)カメラ画像用変数の定義 MultiMarker nya; //(2)マーカ検知用変数の定義 PImage penguin1, penguin2, drawImg; float ratio = 0.3; //画像小さく void setup() { size(640, 480, P3D); //(3)画面のレンダリングには、P3Dを指定 colorMode(RGB, 100); println(MultiMarker.VERSION); String[] cameras = Capture.list(); //(4)利用可能なカメラ一覧 //(4)配列のインデックスは自分の環境に合わせて変更する video = new Capture(this, width, height, cameras[0]); video.start(); //(4)カメラ映像取得開始 //(5)マーカ検知オブジェクトの生成 nya=new MultiMarker(this, width, height, "camera_para.dat", NyAR4PsgConfig.CONFIG_PSG); //(6)ARToolKitスタイルのマーカーを登録 nya.addARMarker(loadImage("CharPe.png"), 16, 25, 80); penguin1 = loadImage("Penguin1.png"); //2枚のペンギン画像 penguin2 = loadImage("Penguin2.png"); } void draw() { if (!video.available()) { // カメラ映像がなければ、何もしない return; } video.read(); nya.detect(video); //(7)引数の画像からマーカを検知 background(0); nya.drawBackground(video); //(8)カメラ画像をバックグラウンドへ描画 if (nya.isExist(0)) { //(9)マーカが検知された if (second()%2==0) { drawImg = penguin1; } //1秒ごとに描く画像を変える else { drawImg = penguin2; } nya.beginTransform(0); //(10)マーカの位置に描画 rotateY(PI); //マーカ平面を上下(y軸)反転 rotateX(PI/2); //左右(x軸)、3次元的に立って見えるように回転 image(drawImg, -penguin1.width*ratio/2, -penguin1.height*ratio, penguin1.width*ratio, penguin1.height*ratio); nya.endTransform(); } }
NFT(Natural Feature Tracking)ターゲット
ARToolKitマーカのように黒枠線内の白黒マーカではなく、写真やイラストをマーカとして認識できます。これが自然特徴点追跡(Natural Feature Tracking)です。写真やイラストの画像から特徴点ファイルを生成し、スケッチフォルダのdataフォルダの中に入れて使います。特徴点ファイルの生成は、nyar4psgライブラリのサンプルの中にあるnftFileGenを使います。- (1) メニュー[ファイル] [サンプル][Contributed Libraries][nyar4psg]の nftFileGen を開いて実行すると、NyAR NftFileGeneratorウィンドウが開く。
- (2) [Import]メニューから[Load image]をクリック、ダイアログからマーカとして使う画像ファイルを選択。
- (3) 右側設定欄の[Source DPI]に、画像のDPI値(解像度)を指定。
- (4) 右側設定欄の上部ボタン[Make Feature Set]をクリック。
- (5) 対象の画像上に、特徴的な部分(自然特徴点)が表示される。これらの特徴点がマーカとして働く。特徴点の数が少ない場合や位置が不適切だと検出が難しくなるので、その場合は別の画像を試す。
- (6) [Export]メニューの[Save FeatureSet Files]をクリック。特徴点データを保存する場所とその名前を指定。拡張子が.fset、.fset3、.isetの3つのファイルが生成される。この3つのファイルはスケッチのdataフォルダに入れる。
自然特徴点を使った検知を行う機能をもつのはMultiNftクラスで、上の【リストA6-1】サンプルではこの部分だけを変更すれば、同じように実行できる。
MultiNft nya; //マーカ検知オブジェクト用変数 //マーカ検知オブジェクトの生成 nya=new MultiNft(this, width, height, "camera_para.dat", NyAR4PsgConfig.CONFIG_PSG); //検知する画像を登録 (ファイル名, 画像の幅[mm]) nya.addNftTarget("PenguinOnBeach", 140);
演習問題
【問題A6-1】MultiMarkerクラスは複数のマーカを識別する機能をもちます。リストA6_1を修正し、マーカ「ぺ」の上にペンギンの画像が、マーカ「モ」の上にサルの画像が表示されるようにしよう。サルの画像、マーカ「モ」の画像は、画像ページからコピーできます。