動体検知 + 肌色認識
/**
* Copyright alpicola ( http://wonderfl.net/user/alpicola )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/A37q
*/
package {
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.display.BlendMode;
import flash.events.Event;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.filters.ColorMatrixFilter;
import flash.filters.ConvolutionFilter;
import flash.media.Camera;
import flash.media.Video;
[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);
prev = copy.clone();
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;
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;
}
}
}
s.graphics.lineStyle(0, 0x00c0c0);
for (var i:int = 0; i < length; i++) {
var rect:Rectangle = rects[i];
s.graphics.drawRect(rect.x, rect.y, rect.width, rect.height);
}
}
}
}