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

動体検知

まだまだ途中バージョン
* 作っている自分も良くわかってません。
* videoのサイズ大きいと負荷が高いのかPCのファンが高速回転汗
* 参考URL
* 動体検知:Flash8で動体検知
* http://faces.bascule.co.jp/motiondetection/
* bitmap操作関連:ActionScript 3.0 でラベリング (改)を勝手に添削
* http://void.heteml.jp/blog/archives/2007/10/as3_labeling.html
// forked from fumix's forked from: 動体検知
// forked from ll_koba_ll's 動体検知
// write as3 code here..
/***
 * まだまだ途中バージョン
 * 作っている自分も良くわかってません。
 * videoのサイズ大きいと負荷が高いのかPCのファンが高速回転汗
 * 参考URL
 * 動体検知:Flash8で動体検知
 * http://faces.bascule.co.jp/motiondetection/
 * bitmap操作関連:ActionScript 3.0 でラベリング (改)を勝手に添削
 * http://void.heteml.jp/blog/archives/2007/10/as3_labeling.html
***/

package
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.BlendMode;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.filters.ConvolutionFilter;
	import flash.geom.ColorTransform;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.media.Camera;
	import flash.media.Video;
	import flash.text.TextField;

	[SWF(width = "465", height = "465", frameRate = "15",backgroundColor="0x000000")]
	public class blend extends Sprite
	{
		private var camera:Camera;
		private var video:Video;
		private var now:BitmapData;
		private var before:BitmapData;
		private var bmd:BitmapData;
		private var rect:Rectangle;
		private var pt:Point;
		
		private var noiseReduction:ConvolutionFilter;
		
		
		private var size:int = 465;
		
		public function blend()
		{
			super();
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
		/**
		 * 初期処理 
		 * @param e
		 * 
		 */
		private function init(e:Event = null):void 
		{
            removeEventListener(Event.ADDED_TO_STAGE, init);
            camera = Camera.getCamera();
            //カメラあり
            if(camera != null){
            	setUpCamera();
            //カメラ無し
            }else{
            	var txt:TextField = new TextField();
            	txt.text ='カメラ無し';
            	addChild(txt);
            }
            
			noiseReduction = new ConvolutionFilter(3, 3);
            noiseReduction.bias = -(0x1000 + 0x100 * 6);
            noiseReduction.matrix = [
                1,  1, 1,
                1, 16, 1,
                1,  1, 1
            ];            
            bmd = new BitmapData(size,size/camera.width * camera.height,false,0x000000);
            addChild(new Bitmap(bmd));
            
            addEventListener(Event.ENTER_FRAME,loop);
            /*
            var btn:Sprite = new Sprite();
            btn.graphics.beginFill(0xFFFFFF);
            btn.graphics.drawRect(0,0,50,30);
            btn.graphics.endFill();
            btn.buttonMode = true;
            btn.addEventListener(MouseEvent.CLICK,loop);
            addChild(btn);
            */

            now = new BitmapData(size,size/camera.width * camera.height,false);
            before = new BitmapData(size,size/camera.width * camera.height,false);
            rect = new Rectangle(0, 0, size,size/camera.width * camera.height);
            pt = new Point;
		}
		/**
		 *カメラのセットアップ 
		 * 
		 */
		private function setUpCamera():void
		{
			camera.setMode(Math.floor(size/2), Math.floor(size/2), 15);
			video = new Video(size,size/camera.width * camera.height);
			video.attachCamera(camera);
			addChild(video);
		}
		private function loop(e:Event=null):void
		{
			now.draw(video);
			now.draw(before,new Matrix(), new ColorTransform(),BlendMode.DIFFERENCE);
			var ret:uint = now.threshold(now,rect,pt,">",0xff111111,0xffffffff);
			//ノイズリダクション
			var ret2 = now.applyFilter(now, rect, pt, noiseReduction);


			before.draw(video);
			//bmd.draw(now);
			
			//動体検知処理
			//参照:http://void.heteml.jp/blog/archives/2007/10/as3_labeling.html
			var dst:BitmapData = now.clone();
			var temp:BitmapData = new BitmapData(dst.width,1,false,0x000000);
			var lno:int = 0;
			var zero:Point = new Point();
			
			//ブロック化
			var rect:Rectangle = dst.getColorBoundsRect(0xffffff,0xffffff,true);
			var area:Rectangle = new Rectangle(0,0,dst.width,1);
			var drawMap:Sprite = new Sprite();
			var recs:Array = new Array();
			while( !rect.isEmpty()){
				area.y = rect.top;
				temp.copyPixels(dst,area,zero);
				rect = temp.getColorBoundsRect(0xffffff,0xffffff,true);
				dst.floodFill(rect.x,area.y,0xff00ff);
				var br:Rectangle = dst.getColorBoundsRect(0xFFFFFF, 0xFF00FF);
				dst.fillRect(br, 0x0000ff);
				rect = dst.getColorBoundsRect( 0xffffff, 0xffffff, true );
				recs.push(br);
			}

			//rectangleが重なってたら、同じものとみなして、数を絞る
			for(var idx:int=0; idx<recs.length; idx++){
				var idx_rec:Rectangle = recs[idx];
				
				for(var i:int=idx+1; i<recs.length; i++){
					var tgt_rec:Rectangle = recs[i];
					if( idx_rec!=tgt_rec && idx_rec.intersects(tgt_rec) ){
						recs.push(idx_rec.union(tgt_rec));
						recs.splice(Number(i), 1);
						recs.splice(Number(idx), 1);
						idx --;
						break;
					}
				}
			}
			for(idx=0; idx<recs.length; idx++){
				tgt_rec = recs[idx];
				drawMap.graphics.lineStyle(1,0xff0000);
				drawMap.graphics.drawRect(tgt_rec.x,tgt_rec.y,tgt_rec.width,tgt_rec.height);							
			}
			//trace(lno);
			bmd.draw(video);
			bmd.draw(drawMap);
			
			
		}
	}
}