FLARToolkit Single & MultipleMarker Detection
Posted on March 23, 2009
Filed Under Actionscript 3.0, experiments, Opensource, Papervision | 15 Comments
What you will need:
1. Photoshop (any will do)
2. Papervision3D rev. 817 or later
3. FlarToolkit
4. ArToolkit Marker Generator (flash player 10)
5. webcam
6. Fash CS3 or Higher
There are allready some great sites experimenting and writing tutorials about Augmented reality in flash. This is nothing new, just my experience in writing the code to create a simple version so I can learn from the others who started it. So before I start credits go out to squidder.com for some amazing tutorials and examples and saqoosha.net for starting the FlarToolkit.
For creating the best markers go and see the tutorial at squidder.com
For the starters kit you can get flartoolkit via libspark repository or download the starterskit at saqoosha.net.
Example of a Single Marker Detection:
Code Single Marker detection:
-
package nl.wisman.codexperiments.augmented
-
{
-
// papervision
-
import org.papervision3d.materials.utils.MaterialsList;
-
import org.papervision3d.objects.primitives.Cube;
-
import org.papervision3d.lights.PointLight3D;
-
import org.papervision3d.materials.shadematerials.FlatShadeMaterial;
-
import org.papervision3d.render.LazyRenderEngine;
-
import org.papervision3d.scenes.Scene3D;
-
import org.papervision3d.view.Viewport3D;
-
-
// flash
-
import flash.display.PixelSnapping;
-
import flash.display.Bitmap;
-
import flash.net.URLRequest;
-
import flash.events.Event;
-
import flash.net.URLLoaderDataFormat;
-
import flash.net.URLLoader;
-
import flash.display.BitmapData;
-
import flash.media.Video;
-
import flash.media.Camera;
-
import flash.display.Sprite;
-
import org.papervision3d.objects.DisplayObject3D;
-
-
// libspark
-
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.core.transmat.FLARTransMatResult;
-
import org.libspark.flartoolkit.detector.FLARSingleMarkerDetector;
-
import org.libspark.flartoolkit.pv3d.FLARBaseNode;
-
import org.libspark.flartoolkit.pv3d.FLARCamera3D;
-
-
public class FlarSingleMarkerDemo extends Sprite
-
{
-
// flar properties
-
private var _camParameters:FLARParam;
-
private var _marker4Pattern:FLARCode;
-
private var _raster:FLARRgbRaster_BitmapData;
-
private var _detector:FLARSingleMarkerDetector;
-
private var _flarCam3D:FLARCamera3D;
-
private var _resultMat:FLARTransMatResult;
-
private var _baseNode:FLARBaseNode;
-
-
// flash properties
-
private var _cam:Camera;
-
private var _vid:Video;
-
private var _capture:Bitmap;
-
private var _loader:URLLoader;
-
-
// papervision3d
-
private var _vp:Viewport3D;
-
private var _scene:Scene3D;
-
private var _renderer:LazyRenderEngine;
-
private var _light:PointLight3D;
-
private var _cube:Cube;
-
-
public function FlarSingleMarkerDemo()
-
{
-
loadCamera();
-
}
-
-
private function loadCamera():void
-
{
-
_loader = new URLLoader();
-
_loader.dataFormat = URLLoaderDataFormat.BINARY;
-
_loader.addEventListener(Event.COMPLETE, onLoadCamParam);
-
_loader.load(new URLRequest("camera_para.dat"));
-
}
-
-
// camera parameters are loaded, load the marker you want to use
-
private function onLoadCamParam(event:Event):void
-
{
-
_loader.removeEventListener(Event.COMPLETE, onLoadCamParam);
-
_camParameters = new FLARParam();
-
_camParameters.loadARParam(_loader.data);
-
_camParameters.changeScreenSize(500, 500);
-
-
_loader.dataFormat = URLLoaderDataFormat.TEXT;
-
_loader.addEventListener(Event.COMPLETE, onLoadCode);
-
_loader.load(new URLRequest("yourmarker.pat"));
-
}
-
-
// marker now also loaded, so remove _loader and create a FlarCode
-
private function onLoadCode(event:Event):void
-
{
-
initWebcam();
-
-
_marker4Pattern = new FLARCode(4, 4, 65, 65);
-
_marker4Pattern.loadARPatt(_loader.data);
-
-
_loader.removeEventListener(Event.COMPLETE, onLoadCode);
-
_loader = null;
-
-
// create bitmap and bitmapdata where we can draw the webcam into
-
var bmd:BitmapData = new BitmapData(500, 500, false, 0);
-
_capture = new Bitmap(bmd, PixelSnapping.AUTO,false);
-
_capture.width = 500;
-
_capture.height = 500;
-
addChild(_capture);
-
-
_raster = new FLARRgbRaster_BitmapData(_capture.bitmapData);
-
_detector = new FLARSingleMarkerDetector(_camParameters, _marker4Pattern, 65);
-
-
initFlar();
-
initPV3D();
-
initListeners();
-
}
-
-
private function initWebcam():void
-
{
-
_cam = Camera.getCamera();
-
_cam.setMode(500, 500, 60);
-
_vid = new Video(500, 500);
-
_vid.attachCamera(_cam);
-
}
-
-
private function initFlar():void
-
{
-
_flarCam3D = new FLARCamera3D(_camParameters);
-
_resultMat = new FLARTransMatResult();
-
_baseNode = new FLARBaseNode();
-
}
-
-
private function initPV3D():void
-
{
-
_vp = new Viewport3D(500, 500);
-
addChild(_vp);
-
-
_scene = new Scene3D();
-
_scene.addChild(_baseNode);
-
-
_light = new PointLight3D();
-
-
// add a cube or whatever we want to show when pattern is recognised
-
// in the basenode (FLARBaseNode, which extends from a DisplayObject3D)
-
var fmat:FlatShadeMaterial = new FlatShadeMaterial(_light, 0x7DC202, 0xCCCCCC);
-
_cube = new Cube(new MaterialsList({all: fmat}), 40, 40, 80);
-
_cube.z = 20;
-
_cube.name = "cube";
-
_baseNode.addChild(_cube);
-
-
_renderer = new LazyRenderEngine(_scene, _flarCam3D, _vp);
-
}
-
-
private function initListeners():void
-
{
-
addEventListener(Event.ENTER_FRAME, render);
-
}
-
-
private function render(event:Event):void
-
{
-
_capture.bitmapData.draw(_vid);
-
-
if (_detector.detectMarkerLite(_raster, 65) && _detector.getConfidence() > 0.5)
-
{
-
// when deteactmarker finds the marker you created show the baseNode
-
_detector.getTransformMatrix(_resultMat);
-
_baseNode.setTransformMatrix(_resultMat);
-
_baseNode.visible = true;
-
}
-
else
-
{
-
_baseNode.visible = false;
-
}
-
-
if(_baseNode.visible)
-
{
-
Cube(_baseNode.getChildByName("cube")).roll(1);
-
}
-
-
_renderer.render();
-
}
-
}
-
}
Example of a Multiple Marker Detection: (its still a work in progress, still shifts cube from one pattern to another but he…)
Code Multiple Marker detection:
-
package
-
{
-
// bulkloader
-
import br.com.stimuli.loading.BulkLoader;
-
-
// papervision
-
import org.papervision3d.materials.utils.MaterialsList;
-
import org.papervision3d.objects.primitives.Cube;
-
import org.papervision3d.lights.PointLight3D;
-
import org.papervision3d.materials.shadematerials.FlatShadeMaterial;
-
import org.papervision3d.render.LazyRenderEngine;
-
import org.papervision3d.scenes.Scene3D;
-
import org.papervision3d.view.Viewport3D;
-
-
// flash
-
import flash.display.PixelSnapping;
-
import flash.display.Bitmap;
-
import flash.net.URLRequest;
-
import flash.events.Event;
-
import flash.net.URLLoaderDataFormat;
-
import flash.net.URLLoader;
-
import flash.display.BitmapData;
-
import flash.media.Video;
-
import flash.media.Camera;
-
import flash.display.Sprite;
-
import org.papervision3d.objects.DisplayObject3D;
-
-
// libspark
-
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.core.transmat.FLARTransMatResult;
-
import org.libspark.flartoolkit.detector.FLARMultiMarkerDetector;
-
import org.libspark.flartoolkit.pv3d.FLARBaseNode;
-
import org.libspark.flartoolkit.pv3d.FLARCamera3D;
-
-
public class FlarMultiMarkerDemo extends Sprite
-
{
-
// flar properties
-
private var _camParameters:FLARParam;
-
private var _raster:FLARRgbRaster_BitmapData;
-
private var _detector:FLARMultiMarkerDetector;
-
private var _flarCam3D:FLARCamera3D;
-
private var _resultMat:FLARTransMatResult;
-
-
// flash properties
-
private var _cam:Camera;
-
private var _vid:Video;
-
private var _capture:Bitmap;
-
private var _loader:URLLoader;
-
private var _allMarkers:Array;
-
-
// papervision3d
-
private var _vp:Viewport3D;
-
private var _scene:Scene3D;
-
private var _renderer:LazyRenderEngine;
-
private var _light:PointLight3D;
-
private var _bLoader:BulkLoader;
-
-
public function FlarMultiMarkerDemo()
-
{
-
_allMarkers = [
-
{markerSource: "path/your_first_marker.pat", segments: 4, size: 65},
-
{markerSource: "path/your_second_marker.pat", segments: 4, size: 65},
-
{markerSource: "path/your_third_marker.pat", segments: 4, size: 65},
-
];
-
-
loadCamera();
-
}
-
-
private function loadCamera():void
-
{
-
_loader = new URLLoader();
-
_loader.dataFormat = URLLoaderDataFormat.BINARY;
-
_loader.addEventListener(Event.COMPLETE, onLoadCamParam);
-
_loader.load(new URLRequest("camera_para.dat"));
-
}
-
-
// camera parameters are loaded, load the marker you want to use
-
// camera parameters are loaded, load the marker you want to use
-
private function onLoadCamParam(event:Event):void
-
{
-
_loader.removeEventListener(Event.COMPLETE, onLoadCamParam);
-
-
// setup camera parameters
-
_camParameters = new FLARParam();
-
_camParameters.loadARParam(_loader.data);
-
_camParameters.changeScreenSize(500, 500);
-
-
// reset loader
-
_loader = null;
-
-
_bLoader = new BulkLoader("markerLoader");
-
_bLoader.addEventListener(Event.COMPLETE, markersLoadedHandler);
-
// now load multiple markers (for now its 3)
-
for (var i:int = 0; i < _allMarkers.length; i++)
-
{
-
_bLoader.add(_allMarkers[i].markerSource, {id: "marker_" + i.toString() });
-
}
-
_bLoader.start();
-
}
-
-
private function markersLoadedHandler(event:Event):void
-
{
-
var codes:Array = new Array();
-
var sizes:Array = new Array();
-
for (var i:int = 0; i < _allMarkers.length; i++)
-
{
-
var code:FLARCode = new FLARCode(_allMarkers[i].segments, _allMarkers[i].segments, _allMarkers[i].size, _allMarkers[i].size);
-
code.loadARPatt(_bLoader.getContent( "marker_" + i.toString()));
-
codes.push(code);
-
sizes.push(_allMarkers[i].size);
-
}
-
-
initWebcam();
-
-
// create bitmap and bitmapdata where we can draw the webcam into
-
var bmd:BitmapData = new BitmapData(500, 500, false, 0);
-
_capture = new Bitmap(bmd, PixelSnapping.AUTO,false);
-
_capture.width = 500;
-
_capture.height = 500;
-
addChild(_capture);
-
-
_raster = new FLARRgbRaster_BitmapData(_capture.bitmapData);
-
_detector = new FLARMultiMarkerDetector(_camParameters, codes, sizes, codes.length);
-
-
initFlar();
-
initPV3D();
-
initListeners();
-
}
-
-
private function initWebcam():void
-
{
-
_cam = Camera.getCamera();
-
_cam.setMode(500, 500, 60);
-
_vid = new Video(500, 500);
-
_vid.attachCamera(_cam);
-
}
-
-
private function initFlar():void
-
{
-
_flarCam3D = new FLARCamera3D(_camParameters);
-
_resultMat = new FLARTransMatResult();
-
}
-
-
private function initPV3D():void
-
{
-
_vp = new Viewport3D(500, 500);
-
addChild(_vp);
-
-
_scene = new Scene3D();
-
-
_light = new PointLight3D();
-
-
// add a cube or whatever we want to show when pattern is recognised
-
// in the basenode (FLARBaseNode, which extends from a DisplayObject3D)
-
for (var i:int = 0; i < _allMarkers.length; i++)
-
{
-
var fmat:FlatShadeMaterial = new FlatShadeMaterial(_light, 0x7DC202 * Math.random(), 0xCCCCCC);
-
var cube:Cube = new Cube(new MaterialsList({all: fmat}), 40, 40, 80);
-
cube.z = 20;
-
cube.name = "cube_" + i.toString();
-
var baseNode:FLARBaseNode = new FLARBaseNode();
-
baseNode.name = "baseNode_" + i;
-
baseNode.addChild(cube);
-
_scene.addChild(baseNode);
-
}
-
-
_renderer = new LazyRenderEngine(_scene, _flarCam3D, _vp);
-
}
-
-
private function initListeners():void
-
{
-
addEventListener(Event.ENTER_FRAME, render);
-
}
-
-
private function render(event:Event):void
-
{
-
_capture.bitmapData.draw(_vid);
-
-
for (var i:int = 0; i< _allMarkers.length; i++)
-
{
-
if(_detector.detectMarkerLite(_raster, 65) && _detector.getConfidence(i) > .5)
-
{
-
_detector.getTransmationMatrix(i, _resultMat);
-
FLARBaseNode(_scene.getChildByName("baseNode_" + i)).setTransformMatrix(_resultMat);
-
_scene.getChildByName("baseNode_" + i).visible = true;
-
}
-
else
-
{
-
_scene.getChildByName("baseNode_" + i).visible = false;
-
}
-
}
-
-
_renderer.render();
-
}
-
}
-
}
And last but not least a flash version to play with:
Try it yourself, but don’t forget to download the patterns first.
Comments
15 Responses to “FLARToolkit Single & MultipleMarker Detection”
Pretty cool!!
I didn’t knew that FlarToolkit works with multiple markers
He Andre, definately checkout John Lindquist blog where he has some amazing freaky stuff going on!
wonder
thank u for the “MultipleMarker Detection”
Very good, but does not associate at the 3D object.
Example: Suppose that the application has 3 patterns. By pointing the pattern 3 to the camera will be displayed in the 3D object shown in the set panttern 1.
It not is equal to FLARManager linking pattern to object 3D.
But thanks for sharing!
Very nice. Is there a way to use collada models instead of cubes? I know you can use one collada model if your only using single marker detection but how about the multiple marker detection?
THanks for sharing. I still get errors but okay. What I was wondering: The bulkloader ( at the top ) what is that? And is that a class you have to download or is that comming with the flartoolkit?
Thanks,
Martijn
Sorry for the second message but the error’s are in line:
159
183
189
These are the messages:
1008: Attribute is invalid. Flex Problem
1083: Syntax error: else is unexpected. Flex Problem
1084: Syntax error: expecting identifier before 0xCCCCCC. Flex Problem
1084: Syntax error: expecting identifier before bitwiseand. Flex Problem
1084: Syntax error: expecting rightbrace before rightparen. Flex Problem
1084: Syntax error: expecting rightparen before 7. Flex Problem
1084: Syntax error: expecting rightparen before semicolon. Flex Problem
1093: Syntax error. Flex Problem
1093: Syntax error. Flex Problem
1093: Syntax error. Flex Problem
I don’t know If someone can help me?
Martijn, note that in line 158 you have the string:
0×7DC202
the symbol there is non printable that looks like and x , change it to 0x7DC202 and it should work (you might have an extra parenthesis there too).
Sorry, meant, change it to:
0x7DC202
Okay, the double post explains it… the site formats 0X11111 numbers and puts this strange char
sorry..
i didnt get it, still having error on line
183 1084
189 else is unexpected
can you load flv with Bulkloader to play them over the marker ?
Thanks
Thank you for sharing that, it’s very useful to me! Thanks again!
As previously stated by WIetse on February 27th, 2010, I am also interested in the use collada models instead of cubes.
I can currently produce the code for one collada model but do you have a simple 2 collada model to show multiple marker detection in action.
I also have issues on line 183 and 189 as syzen and Martijn.
183 1084: Syntax error: expecting rightparen before semicolon.
183 1008: Attribute is invalid.
183 1084: Syntax error: expecting rightbrace before rightparen.
189 1083: Syntax error: else is unexpected.