forked from: Accumulation of Background Statistics

by gasubasu forked from Accumulation of Background Statistics (diff: 2)
refer to http://opencv.jp/sample/accumulation_of_background.html
import com.flashdynamix.utils.SWFProfiler;
♥0 | Line 126 | Modified 2011-01-28 20:45:43 | MIT License
play

ActionScript3 source code

/**
 * Copyright gasubasu ( http://wonderfl.net/user/gasubasu )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/vxjI
 */

// forked from alpicola's Accumulation of Background Statistics
// 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);
        }

    }
}