IN2AR allows you to detect images and estimate their pose using standard webcams/cameras. The pose information can be used to place 3D objects and/or videos onto the image and create wonderfull Augmented Reality applications, or to create unique games that can be controlled by movements of your image.

Some features:

  • Compact SWC Library
  • Robust multiple markerless image detection/tracking at extreme angles
  • Superb performance
  • Easy to use with third party 3D Libraries like Away3D
  • Bundled example project files to get you started straight away.

Sample

package
{
	import arsupport.away3dlite.ARAway3DLiteContainer;
	import arsupport.demo.away3dlite.Away3DLiteWorld;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.geom.Matrix;
	import flash.geom.Rectangle;
	import flash.media.Camera;
	import flash.media.Video;
	import flash.system.ApplicationDomain;
	import flash.text.TextField;
	import flash.ui.ContextMenu;
	import flash.ui.ContextMenuItem;
	import flash.utils.ByteArray;
	import flash.utils.Endian;
	import net.hires.debug.Stats;
	import ru.inspirit.asfeat.ASFEAT;
	import ru.inspirit.asfeat.calibration.IntrinsicParameters;
	import ru.inspirit.asfeat.detect.ASFEATDetectType;
	import ru.inspirit.asfeat.detect.ASFEATReference;
	import ru.inspirit.asfeat.event.ASFEATCalibrationEvent;
	import ru.inspirit.asfeat.event.ASFEATDetectionEvent;
	import ru.inspirit.asfeat.event.ASFEATLSHIndexEvent;
	import ru.inspirit.asfeat.IASFEAT;

	/**
	 * @author Eugene Zatepyakin
	 */
	[SWF(width='640',height='600',frameRate='25',backgroundColor='0xFFFFFF')]
	public final class SimpleDemo extends Sprite
	{
		// embed your data file here
		[Embed(source = '../assets/def_data.ass', mimeType='application/octet-stream')]
		private static const data_ass:Class;

		// init asfeat instance and support classes
		public var asfeat:ASFEAT;
		public var asfeatLib:IASFEAT;
		public var intrinsic:IntrinsicParameters;
		public var world3d:Away3DLiteWorld;

		// max transfromation error to accept
		public var maxTransformError:Number = 10 * 10;

        // forget it
        public var ram:ByteArray;
		// for Fast Memory read/write ops
		public var applicationDomain:ApplicationDomain = ApplicationDomain.currentDomain;

		// different visual objects
		protected var myview:Sprite;
        public static var _txt:TextField;
        protected var camBmp:Bitmap;
        protected var _cam:Camera;
        protected var _video:Video;
        protected var _cambuff:BitmapData;
        protected var _buffer:BitmapData;
        protected var _cambuff_rect:Rectangle;
		protected var _cam_mtx:Matrix;
		protected var _buff_rect:Rectangle;
		protected var _buff_mtx:Matrix;

		// models array if u need it
		public var models:Vector.;

		// camera size
		public var camWidth:int = 640;
        public var camHeight:int = 480;
        public var downScaleRatio:Number = 1;
        public var srcWidth:int = 640; // should be the same as camera size untill downscale is used
        public var srcHeight:int = 480;
        public var maxPointsToDetect:int = 300; // max point to allow on the screen
        public var maxReferenceObjects:int = 1; // max reference objects to be used
        public var mirror:Boolean = true; // mirror camera output

        public var stat:Stats;

		public function SimpleDemo()
		{
			if(stage) onAddedToStage();
			else addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
		}

		protected function onAddedToStage(e:Event = null):void
		{
			removeEventListener( Event.ADDED_TO_STAGE, onAddedToStage );

			asfeat = new ASFEAT(null);
			asfeat.addEventListener( Event.INIT, init ); // wait before this event fired or it wont work
		}

		protected function init(e:Event = null):void
		{
			initStage();
			//
			myview = new Sprite();

            // DEBUG TEXT FIELD
            _txt = new TextField();
            _txt.autoSize = 'left';
            _txt.width = 300;
            _txt.x = 5;
            _txt.y = 480;
            myview.addChild(_txt);
			//
			srcWidth = camWidth * downScaleRatio;
			srcHeight = camHeight * downScaleRatio;

            // WEB CAMERA INITIATION
            initCamera(camWidth, camHeight, 25);
            camBmp = new Bitmap(_cambuff.clone());
            myview.addChild(camBmp);
            //

			// DIFFERENT OBJECTS USED TO WORK WITH WEB CAMERA
			_cambuff_rect = _cambuff.rect;
			_cam_mtx = new Matrix(-1.0, 0, 0, 1.0, camWidth);

			_buffer = new BitmapData( srcWidth, srcHeight, false, 0x00 );
			_buff_rect = _buffer.rect;
			_buff_mtx = new Matrix(downScaleRatio, 0, 0, downScaleRatio);
			//

			// INITIATE ASFEAT/IN2AR LIB
			initASFEAT();

			// ADD STATISTIC
			stat = new Stats();
			myview.addChild( stat );
			stat.x = 640 - 80;
			stat.y = 490;

			addChild(myview);

			// INIT 3D WORLD OBJECT
			init3d();

			// START DECTION + 3D RENDER
			addEventListener(Event.ENTER_FRAME, render);
		}

		protected function initASFEAT():void
		{
			asfeat.removeEventListener( Event.INIT, init );
			asfeatLib = asfeat.lib;

			// just believe me
			ram = new ByteArray();
			ram.endian = Endian.LITTLE_ENDIAN;
			ram.length = asfeatLib.calcRequiredChunkSize(srcWidth, srcHeight, maxPointsToDetect, maxReferenceObjects);
			ram.position = 0;
			applicationDomain.domainMemory = ram;

			// init our engine
			asfeatLib.init( ram, 0, srcWidth, srcHeight, maxPointsToDetect, maxReferenceObjects, maxTransformError, stage );

			// add reference object
			asfeatLib.addReferenceObject( ByteArray( new data_ass ) );

			// add event listeners
			asfeatLib.addListener( ASFEATDetectionEvent.DETECTED, onModelDetected );
			asfeatLib.addListener( ASFEATCalibrationEvent.COMPLETE, onCalibDone );
			asfeatLib.addListener( ASFEATLSHIndexEvent.COMPLETE, onIndexComplete );

			// ATTENTION
			// use it if u want only one model to be detected
			// and available at single frame (better performance)
			asfeatLib.setSingleReferenceMode(true);

			// indexing reference data will result in huge
			// speed up during matching (see docs for more info)
			asfeatLib.indexReferenceData(20, 12);

			// u can repform geometric calibration
			// during detection/tracking (see onCalibDone method)
			asfeatLib.startGeometricCalibration();
		}

		protected function render(e:Event = null):void
		{
			// draw video stream to buffer
			_cambuff.draw( _video );

			// update out screen camera bitmap
			if(mirror)
			{
				camBmp.bitmapData.draw( _cambuff, _cam_mtx );
			} else {
				camBmp.bitmapData.draw( _cambuff );
			}

			// call it each frame so if lost will accur
			// more then 5 frames with no detected/tracked event
			// it will be erased from the screen
			models[0].lost();
			_txt.text = '';

			// update detection buffer & run detection
			_buffer.draw( _cambuff, _buff_mtx, null, null, null, true );
			asfeatLib.detect( _buffer );

			// render 3d world models
			world3d.render();
		}

		protected function onModelDetected(e:ASFEATDetectionEvent):void
		{
			var refList:Vector. = e.detectedReferences;
			var ref:ASFEATReference;
			var n:int = e.detectedReferencesCount;
			var state:String;

			for(var i:int = 0; i < n; ++i)
			{
				ref = refList[i];
				state = ref.detectType;

				models[0].setTransform( ref.rotationMatrix, ref.translationVector, ref.poseError, mirror );
				_txt.text = state;
				if(state == '_detect')
				{
					_txt.appendText( '\nmathed: ' + ref.matchedPointsCount );
				}
				_txt.appendText( '\nfound id: ' + ref.id );
			}

			_txt.appendText( '\ncalib fx/fy: ' + [intrinsic.fx, intrinsic.fy] );
		}

		protected function onCalibDone(e:ASFEATCalibrationEvent):void
		{
			var fx:Number = (e.fx + e.fy) * 0.5;
			var fy:Number = fx;

			intrinsic.update(fx, fy, intrinsic.cx, intrinsic.cy);

			asfeatLib.updateIntrinsicParams();
			world3d.updateAROptions();

			_txt.appendText( '\ncalib fx/fy: ' + [intrinsic.fx, intrinsic.fy] );
		}

		protected function onIndexComplete(e:ASFEATLSHIndexEvent):void
		{
			//trace(e.indexInfo);
		}

		protected function init3d():void
		{
			intrinsic = asfeatLib.getIntrinsicParams();
			world3d = new Away3DLiteWorld( intrinsic, camWidth, camHeight );

			world3d.initIn2ArLogo();

			models = Vector.([
												world3d.in2ar
												]);

			addChild(world3d);
		}

		protected function initCamera(w:int = 640, h:int = 480, fps:int = 25):void
        {
            _cambuff = new BitmapData( w, h, false, 0x0 );
            _cam = Camera.getCamera();
            _cam.setMode( w, h, fps, true );

            _video = new Video( _cam.width, _cam.height );
            _video.attachCamera( _cam );
        }

        protected function initStage():void
		{
			stage.scaleMode = StageScaleMode.NO_SCALE;
			//stage.align = StageAlign.TOP_LEFT;

			var myContextMenu:ContextMenu = new ContextMenu();
			myContextMenu.hideBuiltInItems();

			var copyr:ContextMenuItem;
			copyr = new ContextMenuItem("ASFEAT/IN2AR DEMO", true, false);
			myContextMenu.customItems.push(copyr);
			copyr = new ContextMenuItem("© inspirit.ru", false, false);
			myContextMenu.customItems.push(copyr);

			contextMenu = myContextMenu;
		}
	}
}
Augmented Reality , . URL.