Marilenaを使って顔検知してみる2

FileReferenceで読み込んだ画像にMarilenaを使って顔検知してみる。先日のMarilenaを使って顔検知してみるとほぼ同じ。

使い方:「Load Image」ボタンをクリックして、顔写真(なるべく正面顔)を選択する。

Get Adobe Flash player

▼ActionScript AS3(FP10)
[sourcecode language=”as3″]
/*
* Marilenaを使って顔検知してみる。
* http://www.libspark.org/wiki/mash/Marilena
*
* FileReferenceで画像を取得して、MarilenaのObjectDetectorに
* 投げているだけ。
*
* */

package
{
import com.bit101.components.PushButton;
import flash.display.StageScaleMode;
import flash.display.StageAlign;
import flash.display.Sprite;
import flash.display.Graphics;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.events.Event;
import flash.geom.Rectangle;

public class Main extends Sprite {
private var _faceDetect:FaceDetect;
private var _faceRectContainer:Sprite;
private var _bitmap:Bitmap;
private var _snapShot:SnapShot;

public function Main() {
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;

_bitmap = new Bitmap(new BitmapData(465, 465));
this.addChild(_bitmap);

_faceRectContainer = new Sprite();
this.addChild(_faceRectContainer);

new PushButton(this, 0, 0, "Load Image", onSt);

_snapShot = new SnapShot();
_snapShot.onStart = onStart;
_snapShot.y = 240;
}
public function onSt(e:Event):void {
trace("Main.onSt");
_snapShot.start();
}
private function onStart():void {
trace("Main.onStart");
_faceDetect = new FaceDetect();
_faceDetect.setBitmap(_snapShot.bitmap);
_faceDetect.onComplete = onComplete;
}

private function onComplete(rects:*):void {
_bitmap.bitmapData.draw(_faceDetect.getBitmap());
if( rects ){
var g:Graphics = _faceRectContainer.graphics;
g.clear();

rects.forEach(function(r:Rectangle, idx:int, arr:Array):void {

g.beginFill(0xFF6666, 0.8);
g.drawEllipse(r.x – r.width * 0.15, r.y – r.height * 0.28, r.width * 1.3, r.height * 1.3);
g.drawEllipse(r.x, r.y, r.width, r.height);

g.beginFill(0,0);
g.lineStyle(1, 0xFF0000);
g.drawCircle(r.x + r.width / 3.6, r.y + r.height / 3, r.width/7);
g.drawCircle(r.x + r.width – r.width / 3.6, r.y + r.height / 3, r.width / 7);
g.endFill();

g.lineStyle(1, 0x000000);
g.moveTo(r.x + r.width / 3.6, r.y + r.height / 1.4);
g.lineTo(r.x – r.width / 20, r.y + r.height / 1.5);
g.moveTo(r.x + r.width / 3.6, r.y + r.height / 1.3);
g.lineTo(r.x – r.width / 10, r.y + r.height / 1.32);
g.moveTo(r.x + r.width / 3.6,r.y + r.height / 1.25);
g.lineTo(r.x, r.y + r.height / 1.1);

g.moveTo(r.x + r.width – r.width / 3.6, r.y + r.height / 1.4);
g.lineTo(r.x + r.width + r.width / 20, r.y + r.height / 1.5);
g.moveTo(r.x + r.width – r.width / 3.6, r.y + r.height / 1.3);
g.lineTo(r.x + r.width + r.width / 10, r.y + r.height / 1.32);
g.moveTo(r.x + r.width – r.width / 3.6, r.y + r.height / 1.2);
g.lineTo(r.x + r.width, r.y + r.height / 1.1);
g.endFill();

g.lineStyle(0,0,0);
g.beginFill(0xFF0000, 1);
g.drawCircle(r.x + r.width / 2, r.y + r.height / 1.8, r.width / 12);
g.endFill();
});
}
}
}
}

import flash.display.Bitmap;
import flash.display.Sprite;
class SnapShot extends Sprite {
public var onStart:Function = function():void { };
public var bitmap:Bitmap;
public function SnapShot() { };
public function start():void {
var loaderFile:LoadFile = new LoadFile();
loaderFile.atComplete = atComp;
loaderFile.start();
}
private function atComp(event:Event):void {
bitmap = event.target.content;
onStart();
}
}

//Bitmapを投げると、顔の範囲をあれば返すクラス。
import flash.display.Bitmap;
import jp.maaash.ObjectDetection.ObjectDetector;
import jp.maaash.ObjectDetection.ObjectDetectorOptions;
import jp.maaash.ObjectDetection.ObjectDetectorEvent;
class FaceDetect {
private var _detector:ObjectDetector;
public var onComplete:Function = function(rects:*):void { };
private var _bitmap:Bitmap;
public function FaceDetect() {
_detector = new ObjectDetector();
_detector.options = getDetectorOptions();
_detector.addEventListener(ObjectDetectorEvent.DETECTION_COMPLETE, DETECTION_COMPLETE);
};
private function DETECTION_COMPLETE(event:ObjectDetectorEvent):void {
onComplete(event.rects);
}
public function setBitmap(bitmap:Bitmap):void {
_detector.loadHaarCascades("face.zip");
//アップされているswfではblogに乗せるように↓にしている。
//_detector.loadHaarCascades("http://www.mztm.jp/wp/wp-content/uploads/2010/04/face.zip");
_detector.detect(bitmap);
_bitmap = bitmap;
}
public function getBitmap():Bitmap {
return _bitmap;
}
private function getDetectorOptions() :ObjectDetectorOptions {
var options:ObjectDetectorOptions = new ObjectDetectorOptions();
options.min_size = 50;
options.startx = ObjectDetectorOptions.INVALID_POS;
options.starty = ObjectDetectorOptions.INVALID_POS;
options.endx = ObjectDetectorOptions.INVALID_POS;
options.endy = ObjectDetectorOptions.INVALID_POS;
return options;
}
}

import flash.display.Loader;
import flash.events.Event;
import flash.net.FileReference;
import flash.system.LoaderContext;
class LoadFile{
private var _fileReference:FileReference;
public var atComplete:Function = function(event:Event):void{};
/**
* 開始
*
*/
public function start():void
{
if(_fileReference){
return;
}
_fileReference = new FileReference();
_fileReference.browse();
_fileReference.addEventListener(Event.SELECT, atSelect);
}
/**
* ファイルの選択が完了すると動く
* @param event
*
*/
private function atSelect(event:Event):void{
_fileReference.removeEventListener(Event.SELECT, atSelect);
_fileReference.addEventListener(Event.COMPLETE, atFileComplete);
_fileReference.load();
}
/**
* 選択したファイルを読み込み完了すると動く
* @param event
*
*/
private function atFileComplete(event:Event):void{
_fileReference.removeEventListener(Event.COMPLETE, atFileComplete);
var loader:Loader = new Loader();
loader.loadBytes(event.target.data, new LoaderContext());
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, atBytesComplete);
}
/**
* 読み込んだファイルのバイトアレイを変換完了で動く
* @param event
*
*/
private function atBytesComplete(event:Event):void{
event.target.removeEventListener(Event.COMPLETE, atBytesComplete);
atComplete(event);
}
}

[/sourcecode]