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

by tepe forked from 動体検知 + 肌色認識 (diff: 44)
♥0 | Line 104 | Modified 2011-04-28 14:15:51 | 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/eXp9
 */

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

package {
    import flash.display.*;
    import flash.events.*;
    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 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);//キャプチャ画像表示
            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();//今回の画像のコピー
            //
            //now.draw(prev, new Matrix(), new ColorTransform(), BlendMode.DIFFERENCE);
            now.draw(prev, null, new ColorTransform(), BlendMode.DIFFERENCE);
            prev = copy.clone();//prev更新
            copy.applyFilter(now, rect, pt, skin);
            now.applyFilter(now, rect, pt, grayScale);
            now.threshold(now, rect, pt, ">", 0xff111111, 0xffffffff);
            //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);
            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;
            var i:int;
            for (i = 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;
                    }
                }
            }
            
            s.graphics.lineStyle(0, 0x00c0c0);
            for (i = 0; i < length; i++) {
                var rect:Rectangle = rects[i];
                s.graphics.drawRect(rect.x, rect.y, rect.width, rect.height);
            }
        }
    }
}