Mike T. Henderson

Interactive Design & Art Direction

AS3 Camera Motion Detection using BitmapData.threshold()

Dec 14 2009

The idea for this experiment was to detect the percentage of motion on camera from previous frame to current frame.

Liam O'Donnell simply breaks down the process of determining the changed pixels from previous frame to current frame on his blog where he explains it as drawing the current frame to a BitmapData object, then using the blend mode of difference to draw the previous frame to the same BitmapData object. The final step then is to use BitmapData.threshold() to capture the difference in the changed pixels.

BitmapData.threshold() is defined by Adobe as:

Tests pixel values in an image against a specified threshold and sets pixels that pass the test to new color values. Using the threshold() method, you can isolate and replace color ranges in an image and perform other logical operations on image pixels.

One of the best features of the threshold() method is that it returns a uint value of the number of pixels that were changed. With this value I can then use to determine the percent of changed pixels in the entire area of the camera object from previous frame to current frame.

 

 
package {
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.BlendMode;
	import flash.display.Sprite;
	import flash.events.TimerEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.media.Camera;
	import flash.media.Video;
	import flash.text.TextField;
	import flash.utils.Timer;
 
	[SWF(width="590", height="250", framerate="30", backgroundColor="#ffffff")]
 
	public class MotionDetection extends Sprite
	{
 
		// app properties
		private var appW:int = 295;
		private var appH:int = 250;
		private var output:TextField;
 
		// camera, video, and BitmapData Properties
		private var vid:Video;
		private var cam:Camera;
		private var previousBD:BitmapData;
		private var differenceBD:BitmapData;
		private var thresholdBD:BitmapData;
		private var thresholdBM:Bitmap;
 
		// percentage properties
		private var _perc:Number;
		private var _pixelsChanged:uint;
 
		// timer properties
		private var detectChange:Timer;
 
		public function MotionDetection()
		{
			initApp();
		}
 
		private function initApp():void
		{
			setupCamera();
			setupBitmapData();
			setupTextOutput();
			initTimer();
		}
 
		private function setupCamera():void
		{
			cam = Camera.getCamera();
			cam.setMode(appW, appH, stage.frameRate);
 
			vid = new Video( appW, appH );
			vid.attachCamera( cam );
			addChild( vid );
		}
 
		private function setupBitmapData():void
		{
			previousBD =	new BitmapData( appW, appH, false, 0x000000 );
			differenceBD = 	new BitmapData( appW, appH, false, 0x000000 );
			thresholdBD = 		new BitmapData( appW, appH, false, 0x000000 );
 
			thresholdBM = new Bitmap( thresholdBD );
			thresholdBM.x = appW;
			addChild( thresholdBM );
		}
 
		private function setupTextOutput():void
		{
			output = new TextField();
			output.x = appW + 5;
			output.y = 5;
			output.textColor = 0xff0000;
			output.width = appW - 10;
			addChild(output);
		}
 
		private function initTimer():void
		{
			detectChange = new Timer( 250 );
			detectChange.addEventListener( TimerEvent.TIMER, onDetectChange );
			detectChange.start();
		}
 
		private function onDetectChange( event:TimerEvent ):void
		{
			differenceBD.draw( vid );
			differenceBD.draw( previousBD, null, null, BlendMode.DIFFERENCE );
 
			thresholdBD.fillRect(new Rectangle(0,0,thresholdBD.width,thresholdBD.height),0xFFFFFFFF);
			_pixelsChanged = thresholdBD.threshold(differenceBD, differenceBD.rect, new Point(0,0), ">", 0xFF333333, 0xFF000000);
 
			previousBD.draw( vid );
 
			output.text = String(int(movementPercentage * 100)) + " % pixel movement on camera."
		}
 
		private function get movementPercentage():Number
		{
			_perc = _pixelsChanged / (appW * appH);
			_perc = Math.round(_perc*100)/100; // rounds decimal
			return _perc;
		}
 
	}
}
 

Creative Commons License
Camera Motion Detection using BitmapData.threshold by Mike T. Henderson
is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.
Based on a work at mikethenderson.com.

0 Posted under: BitmapData, Camera

Leave a Reply