Navigation Menu

Skip to content

Commit

Permalink
add flash version!
Browse files Browse the repository at this point in the history
  • Loading branch information
jackylee0424 committed Aug 10, 2011
1 parent 42be0c8 commit 84f9a5c
Show file tree
Hide file tree
Showing 40 changed files with 3,459 additions and 5 deletions.
17 changes: 12 additions & 5 deletions README.mdown
Expand Up @@ -2,10 +2,10 @@ Attention Meter
===============

Attention Meter is able to track multiple person's real-time facial attention.
It utilizes OpenCV 2.1 to locate faces and to analyze face movement.
It utilizes OpenCV to locate faces and to analyze face movement.
[![](https://github.com/jackylee0424/Attention-Meter/raw/master/attention.jpg)](https://github.com/jackylee0424/Attention-Meter/raw/master/attention.jpg)

Attention Meter (Python)
Attention Meter in Python
===============

* Mac Installation:
Expand All @@ -17,7 +17,7 @@ Attention Meter (Python)
http://br1ckb0x.fancy-bits.net/blog/?page_id=417 for installing OpenCV.
However, I haven't tried it yet.

3. For Leopard users, you may install this private framework
3. For Leopard users, you may install this OpenCV 2.1 private framework
http://www.cs.colostate.edu/facerec/algorithms/support/OpenCV2.1_rev3291_MacOS10.6.pkg
and try >>> import cv
It worked for me and saved me hours of time. Try it and let me know if it still works for you.
Expand All @@ -27,10 +27,17 @@ Attention Meter (Python)

2. In command line, do > python attention-win.py

Roadmap

Attention Meter in Flash CS5
===============
* Web-based Attention Meter via Flash (coming soon in 2 weeks)
The original inspiration and source code came from http://www.quasimondo.com/archives/000687.php
I utilized and modified this code into the web version Attention Meter.

Installation:
Use Adobe Flash CS5 to open flash-cs5/webcamFace.fla.

Roadmap
===============
* Attention Meter + Video Chat (under development)

* iOS Attention Meter (under development)
Expand Down
1 change: 1 addition & 0 deletions flash-cs5/Face_Attention.as
@@ -0,0 +1 @@
//// Face_Attention.as//// This is a Flash-based Attention Meter.//// Jackie Lee//// Aug. 10, 2011//// Affective Computing Group// MIT Media Laboratory//// Special Thanks to Hyemian Wang//package { import flash.media.Video; import flash.media.Camera; import flash.utils.Timer; import flash.events.TimerEvent; import flash.display.Graphics; import flash.display.BitmapData; import flash.display.Bitmap; import flash.display.Sprite; import flash.net.*; public class Face_Attention extends Object{ public var age:int; public var fwidth:int; public var fheight:int; public var xpt:int; public var ypt:int; public var life:int; public var fstate:int; public var laststate:int; public var alternations:int; public var faceStill:int; public var stills:int; public var lefts:int; public var rights:int; public var ups; public var downs; public const FACE_MAX_LIFE = 1; public const FACE_MAX_MOVEMENT = 20; public const FACE_MAX_ATTENTION = 10; public function Face_Attention(age:int, fwidth:int, fheight:int, xpt:int, ypt:int, life:int){ this.age = age; this.fwidth = fwidth; this.fheight = fheight; this.xpt = xpt; this.ypt = ypt; this.life = life; } public function updateFace(fwidth:int, fheight:int, xpt:int, ypt:int):void{ if (this.age<FACE_MAX_ATTENTION){this.age++;}else{this.age=FACE_MAX_ATTENTION;} this.fwidth = fwidth; this.fheight = fheight; this.xpt = xpt; this.ypt = ypt; this.life = 0; } private function isTooOld():Boolean{ if (this.life>FACE_MAX_LIFE){return true;}else{return false;} } private function updateLife():int{this.life++;return this.life} }}
Expand Down
1 change: 1 addition & 0 deletions flash-cs5/WebcamFaceDetector.as
@@ -0,0 +1 @@
//// WebcamFaceDetector.as//// This is a Flash-based Attention Meter.//// Jackie Lee//// Aug. 10, 2011//// Affective Computing Group// MIT Media Laboratory//// Special Thanks to Hyemian Wang//package { import flash.media.Video; import flash.media.Camera; import flash.utils.Timer; import flash.events.TimerEvent; import flash.display.Graphics; import flash.display.BitmapData; import flash.display.Bitmap; import flash.display.Sprite; import flash.net.*; import gs.easing.Cubic; import gs.TweenLite; import Face_Attention; import jp.maaash.ObjectDetection.ObjectDetector; import jp.maaash.ObjectDetection.ObjectDetectorEvent; import jp.maaash.ObjectDetection.ObjectDetectorOptions; public class WebcamFaceDetector extends Sprite { //How long a rectangle will remain visible after no faces are found private const __noFaceTimeout : int = 800; //how often to analyze the webcam image private const __faceDetectInterval : int = 300; //bigger the slower //color of the rectangle private const __rectColor : int = 0xffff00; private var _detector :ObjectDetector; private var _options :ObjectDetectorOptions; private var _bmpTarget :Bitmap; private var _detectionTimer : Timer; private var _rects:Array; private var _rduration:Array; //duration of each rectangles private var _video : Video; private var _noFaceTimer : Timer; public var cameraContainer : Sprite; private var faceno:int=0; private var pre_faceno:int=0; private var trackedFaces:Array; // for Face_Attention class private var maxfaces:int=10; // max faces in a cam view var att_line:Sprite = new Sprite(); // draw an attention line var fupload:Boolean = false; public function WebcamFaceDetector() { //Timer for rectangles not being found _noFaceTimer = new Timer( __noFaceTimeout ); _noFaceTimer.addEventListener( TimerEvent.TIMER , _noFaceTimer_timer); //Array of reusable rectangles _rects = new Array( ); _rduration = new Array(); //duration trackedFaces = new Array(maxfaces); //make a Face_Attention array for (var i:int = 0; i<maxfaces;i++){ var f:Face_Attention = new Face_Attention(0,0,0,0,0,0); trackedFaces[i]= f; } //timer for how often to detect _detectionTimer = new Timer( __faceDetectInterval ); _detectionTimer.addEventListener( TimerEvent.TIMER , _detectionTimer_timer); _detectionTimer.start(); //initalize detector _initDetector(); //set up camera _setupCamera(); //set up attention line addChild(att_line); att_line.graphics.lineStyle(1,0xFF0000); att_line.graphics.beginFill(0x000000,0); att_line.graphics.drawRect(0,0,10,.1); //hook up detection complete _detector.addEventListener( ObjectDetectorEvent.DETECTION_COMPLETE , _detection_complete ); } private function _setupCamera() : void{ var camera : Camera; var index:int = 0; for ( var i : int = 0 ; i < Camera.names.length ; i ++ ) { if ( Camera.names[ i ] == "USB Video Class Video" ) { index = i; } } camera = Camera.getCamera( String( index ) ); camera.setMode(320, 240, 24); if (camera != null) { _video = new Video( camera.width , camera.height ); _video.attachCamera( camera ); addChild( _video ); } else { trace( "You need a camera." ); } } /** * Called when No faces are found after __noFaceTimeout time */ private function _noFaceTimer_timer (event : TimerEvent) : void { _noFaceTimer.stop(); for (var i : int = 0; i < _rects.length; i++) { TweenLite.to( _rects[i] , .5, { alpha:0, x:_rects[i].x + _video.x, y:_rects[i].y, ease:Cubic.easeOut } ); } faceno=0; } /** * Creates a rectangle */ private function _createRect() : Sprite{ var rectContainer : Sprite = new Sprite(); rectContainer.graphics.lineStyle( 2 , __rectColor , 1 ); rectContainer.graphics.beginFill(0x000000,0); rectContainer.graphics.drawRect(0, 0, 100, 100); return rectContainer; } /** * Evalutates the webcam video for faces on a timer */ private function _detectionTimer_timer (event : TimerEvent) : void { _bmpTarget = new Bitmap( new BitmapData( _video.width, _video.height, false ) ); _bmpTarget.bitmapData.draw( _video ); _detector.detect( _bmpTarget ); pre_faceno = faceno; } /** * Fired when a detection is complete */ private function _detection_complete (event : ObjectDetectorEvent) : void { //no faces found if(event.rects.length == 0) return; //stop the no-face timer and start back up again _noFaceTimer.stop( ); _noFaceTimer.start(); //loop through faces found for (var i : int = 0; i < event.rects.length ; i++) { //create rectangles if needed if(_rects[i] == null){ _rects[i] = _createRect(); addChild(_rects[i]); } //Animate to new size TweenLite.to( _rects[i] , .5, { alpha:1, x:event.rects[i].x*_video.scaleX + _video.x, y:event.rects[i].y*_video.scaleY, width:event.rects[i].width*_video.scaleX, height:event.rects[i].height*_video.scaleY, ease:Cubic.easeOut } ); //add to Face_Attention class if (event.rects[0].x != trackedFaces[0].xpt){ } if (Math.abs((event.rects[0].x-trackedFaces[0].xpt))<trackedFaces[0].FACE_MAX_MOVEMENT){ trackedFaces[0].updateFace(event.rects[0].width, event.rects[0].height, event.rects[0].x, event.rects[0].y); trace("face0-attention:"+trackedFaces[0].age+"/"+trackedFaces[0].FACE_MAX_ATTENTION); }else{ var fa:Face_Attention = new Face_Attention(0, event.rects[i].width, event.rects[i].height, event.rects[i].x, event.rects[i].y, 0); trackedFaces[0]=fa; } //Animate att_line to new size TweenLite.to( att_line , .8, { alpha:1, x:trackedFaces[0].xpt+1, y:trackedFaces[0].ypt-5, width:1+trackedFaces[0].fwidth*trackedFaces[0].age/trackedFaces[0].FACE_MAX_ATTENTION, height:1, ease:Cubic.easeOut } ); } if (event.rects.length>0){faceno = event.rects.length;}else{faceno =0;} //hide the rest of the rectangles if(event.rects.length < _rects.length){ faceno=0; for (var j : int = event.rects.length; j < _rects.length; j++) { TweenLite.to( _rects[j] , .5, { alpha:0, x:_rects[j].x, y:_rects[j].y, ease:Cubic.easeOut } ); } } } /** * Initializes the detector */ private function _initDetector () : void { _detector = new ObjectDetector; _detector.options = getDetectorOptions( ); _detector.loadHaarCascades( "face.zip" ); } /** * Gets dector options */ private function getDetectorOptions () : ObjectDetectorOptions { _options = 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; } }}
Expand Down

0 comments on commit 84f9a5c

Please sign in to comment.