s26

FLARToolkitの作り方(その1)

今回は、画像を認識させるまで。を行いたいと思います。

最初に

http://gihyo.jp/design/feature/01/flartoolkit/0001

でsaqooshaさんのファイルをダウンロードしましょう。(四角が出るやつね)
カメラで立方体のサンプルを楽しみおわったら、ここに戻ってきてねー。




でははじめますー


内容は
1、カメラの情報とマークの情報を取得
2、ウェブカムの起動
3、マークとカメラの関連付け

くらいですね。

では、はじめます。(一番↓にまとめたものをおいておきます。)
まずは、中のasファイルが入っているフォルダの中にflaファイルを作成します。

次にasファイルを作成します。
今回はflar_originalとつけます。

public class flar_original extends Sprite {
}

次にコンストラクタです。外部情報になっている為にカメラの情報とマークの情報をロードします。
ロードに関しては、大変ですが2回に分けます。

//カメラを読み込む
public function flar_original() {
	_cameraloader= new URLLoader();
	_cameraloader.dataFormat = URLLoaderDataFormat.BINARY;
	_cameraloader.addEventListener(Event.COMPLETE, mark_loading);
	_cameraloader.load(new URLRequest("Data/camera_para.dat"));
}
		
//マークを読み込む
private function mark_loading(e:Event):void {
	e.target.removeEventListener(Event.COMPLETE, mark_loading);
	_markloader = new URLLoader();
	_markloader.dataFormat = URLLoaderDataFormat.TEXT;
	_markloader.addEventListener(Event.COMPLETE, _onLoadMark);
	_markloader.load(new URLRequest("Data/flarlogo.pat"));
}

読み込みが終わったらデータを整理します。(5つのファンクションだけで作成できますー)

private function _onLoadMark(e:Event):void {
	e.target.removeEventListener(Event.COMPLETE, _onLoadMark);
	//マークのセットを行う①
	mark_set();
	//カメラの情報せっと②
	camera_set();
	//ウェブカムセット③
	web_cam();
	//ビデオの情報を投影するスクリーンを作ります。④
	capture_set();
    //マークの検出⑤
	var timer = new Timer(33, 0);
	timer.addEventListener(TimerEvent.TIMER, _check);
	timer.start();			
}

マークのセットは16×16で作成されています。(patファイルもこの大きさで作ってあります。)(1つめー)

private function mark_set():void {
	_markcode = new FLARCode(16, 16);
	_markcode.loadARPatt(_markloader.data);
}

カメラのレンズなどの情報をいれると精度があがるらしい(書き方わからないからデフォルト使用)(2つめー)

private function camera_set():void {
	_cameraparam = new FLARParam();
	_cameraparam.loadARParam(_cameraloader.data);
}

ウェブカムの情報をビデオにくっつけてビデオを表示させる(3つめー)

private function web_cam():void {
	_video = new Video(640, 480);
	_camera = Camera.getCamera();
	_camera.setMode(640, 480, 30);
	_video.attachCamera(_camera);
	addChild(_video);
}


キャプチャという箱を用意してその中で検証ができる状態にします。(4つめー)

private function capture_set():void {
	//ビットマップを作成します。
	_capture = new BitmapData(640, 480);
	//軌跡図
	raster = new FLARRgbRaster_BitmapData(_capture);
	//観測者
	detector = new FLARSingleMarkerDetector(_cameraparam, _markcode, 80);
}

以上で準備が整っているので、マークの検出を行います。(5つめー)
ここでの値を詳しくしりたければソースを読みましょう、めんどうくさければこのままで。

private function _check(e:TimerEvent):void {
	
	//これは検証と重ね合わせるように書き記す形
	_capture.draw(_video);
			
	if(detector.detectMarkerLite(raster, 80) && detector.getConfidence() > 0.5){
		//マークを発見する事ができたなら、トレースを行う。
		trace("hell!world");
	}
}

マークを感知すると「hello.world」が出ます。ぜんぜんARの要素がなくてすいません。
基礎まで掘り下げて行く事で本質が見えてきたりするのでー今回はかなーり基礎からやりましたー。
自分でサンプルを配布してもいいんですが、saqooshaさんのデータ丸パクリを配布するのは気が引けたので、
参照させてもらっての記述です。では、変数定義も含めたおさらいですー
こんな事を気づきました。
→検証に使う映像と表示の映像は異なるものを使用できるので、検証用の映像だけをコントラストがっつし画像とか、明るくしたり暗くしたりできる。


flar_original.as

package {
	import flash.display.Sprite;
	import flash.display.BitmapData
	import flash.net.URLLoader;
	import flash.net.URLLoaderDataFormat;
	import flash.events.Event;
	import flash.net.URLRequest;
	import flash.utils.Timer;
	import flash.events.TimerEvent;
	
	import flash.media.Camera;
	import flash.media.Video;
	
	import org.libspark.flartoolkit.core.FLARCode;
	import org.libspark.flartoolkit.core.param.FLARParam;
	import org.libspark.flartoolkit.core.raster.rgb.FLARRgbRaster_BitmapData;
	import org.libspark.flartoolkit.detector.FLARSingleMarkerDetector;
	/**
	 * ...
	 * @author s26
	 */
	public class flar_original extends Sprite {
		
		var _markloader:URLLoader;
		var _cameraloader:URLLoader;
		var _cameraparam:FLARParam;
		var _markcode:FLARCode;
		var _camera:Camera;
		var _video:Video;
		var _capture:BitmapData;
		
		var raster:FLARRgbRaster_BitmapData;
		var detector:FLARSingleMarkerDetector;
		
		public function flar_original() {
			_cameraloader= new URLLoader();
			_cameraloader.dataFormat = URLLoaderDataFormat.BINARY;
			_cameraloader.addEventListener(Event.COMPLETE, mark_loading);
			_cameraloader.load(new URLRequest("Data/camera_para.dat"));
		}
		
		//マークを読み込む
		private function mark_loading(e:Event):void {
			e.target.removeEventListener(Event.COMPLETE, mark_loading);
			_markloader = new URLLoader();
			_markloader.dataFormat = URLLoaderDataFormat.TEXT;
			_markloader.addEventListener(Event.COMPLETE, _onLoadMark);
			_markloader.load(new URLRequest("Data/flarlogo.pat"));
		}
		
		private function _onLoadMark(e:Event):void {
			e.target.removeEventListener(Event.COMPLETE, _onLoadMark);
			//マークのセットを行う
			mark_set();
			//カメラの情報せっと
			camera_set();
			//ウェブカムセット
			web_cam();
			//ビデオの情報を投影するスクリーンを作ります。
			capture_set();
			var timer = new Timer(100, 0);
			timer.addEventListener(TimerEvent.TIMER, _check);
			timer.start();
			
		}
		

		private function mark_set():void {
			_markcode = new FLARCode(16, 16);
			_markcode.loadARPatt(_markloader.data);
		}
		private function camera_set():void {
			_cameraparam = new FLARParam();
			_cameraparam.loadARParam(_cameraloader.data);
		}
		private function web_cam():void {
			_video = new Video(640, 480);
			_camera = Camera.getCamera();
			_camera.setMode(640, 480, 30);
			_video.attachCamera(_camera);
			addChild(_video);
		}
		private function capture_set():void {
			//ビットマップを作成します。
			_capture = new BitmapData(640, 480);
			//軌跡図
			raster = new FLARRgbRaster_BitmapData(_capture);
			//観測者
			detector = new FLARSingleMarkerDetector(_cameraparam, _markcode, 80);
		}
		private function _check(e:TimerEvent):void {
			
			//これは検証と重ね合わせるように書き記す形
			_capture.draw(_video);
			
			if(detector.detectMarkerLite(raster, 80) && detector.getConfidence() > 0.5){
				//マークを発見する事ができたなら、レンダリングを行う。
				trace("hell!world");
			}
		}
	}
	
}