In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

Accumulation of Background Statistics

refer to http://opencv.jp/sample/accumulation_of_background.html
Get Adobe Flash player
by alpicola 04 Jan 2010
/**
 * Copyright alpicola ( http://wonderfl.net/user/alpicola )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/f9N8
 */

// refer to http://opencv.jp/sample/accumulation_of_background.html


package {
	import flash.display.*;
	import flash.events.*;
	import flash.filters.*;
	import flash.geom.*;
	import flash.media.*;
	import flash.net.*;
	import flash.text.*;
	//import com.flashdynamix.utils.SWFProfiler;

	[SWF(width="320", height="240", backgroundColor="#ffffff", frameRate="30")] 

	public class Test extends Sprite {

		private const WIDTH:uint  = 320;
		private const HEIGHT:uint = 240;
		private const PIXELS:uint = WIDTH * HEIGHT;

		private var camera:Camera;
		private var video:Video;
		private var bitmap:BitmapData = new BitmapData(WIDTH, HEIGHT, false, 0);
		private var object:BitmapData = new BitmapData(WIDTH, HEIGHT, true , 0);
		private var statistics1:Vector.<Number> = new Vector.<Number>(PIXELS, true);
		private var statistics2:Vector.<Number> = new Vector.<Number>(PIXELS, true);
		private var r1:Number = 0.02;
		private var r2:Number = 0.005;
		private var count:int = 0;
		private var shader:Sprite = new Sprite();
		private var luminance:ColorMatrixFilter;
		private var erode:ConvolutionFilter;
		private var dilate:ConvolutionFilter;
		private var blur:BlurFilter;

		public function Test() {
			stage.scaleMode = "noScale";
			stage.align = "TL";
			//SWFProfiler.init(stage, this);

			camera = Camera.getCamera();
			if (camera == null) return;
			camera.setMode(WIDTH, HEIGHT, 30);
			video = new Video(WIDTH, HEIGHT);
			video.attachCamera(camera);
			addChild(video);
			addChild(new Bitmap(object));

			luminance = new ColorMatrixFilter([
				0, 0, 0, 0, 0,
				0, 0, 0, 0, 0,
				0.3, 0.59, 0.11, 0, 0,
				0, 0, 0, 0, 0
			]); 
			erode = new ConvolutionFilter(3, 3);
			erode.bias = -(0xff0 + 0xff * 7);
			erode.matrix = [
				1,  1, 1,
				1, 16, 1,
				1,  1, 1
			];
			dilate = new ConvolutionFilter(3, 3);
			dilate.matrix = [
				1, 1, 1,
				1, 1, 1,
				1, 1, 1
			];
			blur = new BlurFilter(2, 2);

			if (camera.muted) {
				camera.addEventListener(StatusEvent.STATUS, function(e:StatusEvent):void {
					if (!camera.muted) start();
				});
			} else {
				start();
			}
		}

		public function start():void {
			shader.graphics.beginFill(0x000000, 0.5);
			shader.graphics.drawRect(0, 0, WIDTH, HEIGHT);
			addChild(shader);
			var tf:TextField = new TextField();
			tf.defaultTextFormat = new TextFormat("_sans", 18);
			tf.autoSize = "left";
			tf.textColor = 0xffffff;
			tf.text = "initializing...";
			tf.x = (WIDTH  - tf.width)  / 2;
			tf.y = (HEIGHT - tf.height) / 2;
			shader.addChild(tf);
			addChild(shader);
			addEventListener(Event.ENTER_FRAME, initialize);
		}

		public function initialize(e:Event):void {
			var frame:Vector.<uint> = getFrame();
			var i:int = PIXELS;
			var x:Number, amplitude:Number;
			if (count < 50) {
				while (i--) statistics1[i] += frame[i] & 0xff;
			} else if (count == 50) {
				while (i--) statistics1[i] /= 50;
			} else if (count < 100) {
				while (i--) statistics2[i] += (x = (frame[i] & 0xff) - statistics1[i]) > 0 ? x : -x;
			} else {
				while (i--) statistics2[i] /= 50;
				removeChild(shader);
				removeEventListener(Event.ENTER_FRAME, initialize);
				addEventListener(Event.ENTER_FRAME, loop);
			}
			count++;
		}

		public function loop(e:Event):void {
			var frame:Vector.<uint> = getFrame();
			var amplitude:Number;
			object.lock();
			for (var i:int = 0; i < PIXELS; i++) {
				amplitude = (frame[i] & 0xff) - statistics1[i];
				amplitude = amplitude > 0 ? amplitude : -amplitude;
				if (amplitude > 1.414 * statistics2[i] + 10) {
					statistics2[i] = (1 - r1) * statistics2[i] + r1 * amplitude; 
					object.setPixel32(i % WIDTH, int(i / WIDTH), 0xff00ffff);
				} else {
					statistics1[i] = (1 - r2) * statistics1[i] + r2 * (frame[i] & 0xff); 
					statistics2[i] = (1 - r2) * statistics2[i] + r2 * amplitude; 
					object.setPixel32(i % WIDTH, int(i / WIDTH), 0x00000000);
				}
			}
			object.applyFilter(object, object.rect, new Point(), erode);
			object.applyFilter(object, object.rect, new Point(), dilate);
			object.applyFilter(object, object.rect, new Point(), blur);
			object.unlock();
		}

		public function getFrame():Vector.<uint> {
			bitmap.draw(video);
			bitmap.applyFilter(bitmap, bitmap.rect, new Point(), luminance);
			return bitmap.getVector(bitmap.rect);
		}

	}
}