動体検知
まだまだ途中バージョン
* 作っている自分も良くわかってません。
* 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);
}
}
}