forked from: forked from: forked from: 動体検知 + 肌色認識

by tepe forked from forked from: forked from: 動体検知 + 肌色認識 (diff: 44)
練習中
♥0 | Line 104 | Modified 2012-02-29 12:00:35 | MIT License
play

ActionScript3 source code

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

// forked from ikusu's forked from: forked from: 動体検知 + 肌色認識

package {
    import flash.display.*;
    import flash.events.Event;
    import flash.geom.*;;
    import flash.filters.*;
    import flash.media.*;

    [SWF(width="465", height="465", backgroundColor="#ffffff", frameRate="15")] 
    
    public class MotionDetection extends Sprite {
        
        private var camera:Camera;
        private var video:Video;//カメラキャプチャ
        private var now:BitmapData;//今回の画像
        private var prev:BitmapData;//前回の画像
        private var tmp:Bitmap;
        private var rect:Rectangle;
        private var pt:Point;
        private var noiseReduction:ConvolutionFilter;
        private var grayScale:ColorMatrixFilter;
        private var skin:ColorMatrixFilter;
        private var s:Sprite;
        
        //エントリ
        public function MotionDetection() {
            stage.align = "TL";
            stage.scaleMode = "noScale";

            camera = Camera.getCamera();
            if (camera == null) return;
            camera.setMode(465, 465, 15);
            video = new Video(camera.width, camera.height);
            video.attachCamera(camera);
            addChild(video);
            //addChild(tmp);
            s = new Sprite();
            addChild(s);

            //画像取得
            now = new BitmapData(camera.width, camera.height, false);
            prev = new BitmapData(camera.width, camera.height, false);
            rect = new Rectangle(0, 0, camera.width, camera.height);
            pt = new Point;
            
            //フィルタリング
            noiseReduction = new ConvolutionFilter(3, 3);
            noiseReduction.bias = -(0x1000 + 0x100 * 6);
            noiseReduction.matrix = [
                1,  1, 1,
                1, 16, 1,
                1,  1, 1
            ];
            grayScale = new ColorMatrixFilter([
                0.3, 0.59, 0.11, 0, 0,
                0.3, 0.59, 0.11, 0, 0,
                0.3, 0.59, 0.11, 0, 0,
                0, 0, 0, 1, 0
            ]);
            skin = new ColorMatrixFilter([
                0, 0, 0, 0, 0,
                -0.43, -0.85, 1.28, 0, 198.4,
                1.28, -1.07, -0.21, 0, 108.8,
                0, 0, 0, 1, 0
            ]);
            //エンターフレームイベント
            addEventListener(Event.ENTER_FRAME, update);
        }

        //更新
        private function update(e:Event):void {
            s.graphics.clear();//表示画像クリア

            now.draw(video);//キャプチャデータをコピー
            var copy:BitmapData = now.clone();//今回の画像BMP
            //前回との差分
            now.draw(prev, new Matrix(), new ColorTransform(), BlendMode.DIFFERENCE);
            prev = copy.clone();//前回画像の更新
            //copy.applyFilter(now, rect, pt, skin);//肌色フィルター
            now.applyFilter(now, rect, pt, grayScale);//グレースケールフィルター
            now.threshold(now, rect, pt, ">", 0xff111111, 0xffffffff);
            //tmp.bitmapData = now;
            //now.threshold(now, rect, pt, "!=", 0xffffffff, 0xff000000);
            //閾値
            now.threshold(copy, rect, pt, "!=", 0x008080, 0xff000000, 0x00c0c0);
            //フィルタ適用画像取得
            now.applyFilter(now, rect, pt, noiseReduction);
           
            var rects:Vector.<Rectangle> = new Vector.<Rectangle>();
            //指定した色を含む矩形
            var bound:Rectangle = now.getColorBoundsRect(0xffffff, 0xffffff);
            //1pixel画像
            var line:BitmapData = new BitmapData(rect.width, 1, false);
            
            var lineBound:Rectangle = new Rectangle(0, 0, rect.width, 1);
            
            while (!bound.isEmpty()) {
                lineBound.y = bound.y;
                line.copyPixels(now, lineBound, pt);
                bound = line.getColorBoundsRect(0xffffff, 0xffffff);
                now.floodFill(bound.x, lineBound.y, 0xff00ff);
                var rect:Rectangle = now.getColorBoundsRect(0xffffff, 0xff00ff);
                rect.inflate(4, 4);
                now.fillRect(rect, 0x0000ff);
                rects.push(rect);//検出エリア追加
                //指定した色を含む矩形
                bound = now.getColorBoundsRect(0xffffff, 0xffffff);
            }

            var length:int = rects.length;
            for (var i:int = 0; i < length; i++) {
                var rect1:Rectangle = rects[i];
                for (var j:int = i + 1; j < length; j++) {
                    var rect2:Rectangle = rects[j];
                    if (rect1.intersects(rect2)) {
                        rects.push(rect1.union(rect2));
                        rects.splice(j, 1);
                        rects.splice(i, 1);
                        i--;
                        length--;
                        break;
                    }
                }
            }
            
            //検出エリア描画
            var color:uint = 0x00ff00;
            s.graphics.lineStyle(0, color);
            for (var i2:int = 0; i2 < length; i2++) {
                var rectB:Rectangle = rects[i2]; 
                s.graphics.drawRect(rectB.x, rectB.y, rectB.width, rectB.height);
            }
        }
    }
}