The Machine Perception Toolbox

[Introduction]- [News]- [Download]- [Screenshots]- [Manual (pdf)]- [Forums]- [API Reference]- [Repository ]

 

Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

blink.cc

Go to the documentation of this file.
00001 /*
00002  *  blink.cc
00003  *
00004  *  Author:Ian Fasel, Bret Fortenberry
00005  *  Fixes:
00006  *
00007  *  Copyright (c) 2003 Machine Perception Laboratory
00008  *  University of California San Diego.
00009  *
00010  * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
00011  *
00012  *    1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
00013  *    2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
00014  *    3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission.
00015  *
00016  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00017  *
00018  */
00019 
00020 #include <math.h>
00021 #include <string> 
00022 #include <iostream>
00023 #include <list>
00024 #include "blink.h"
00025 #include "blink_wts.h"     
00026 
00027 #define eye_width 44
00028 #define eye_height 22
00029 #define cushion 3 //border around interpolated image to shrink
00030 #define eye_preWidth 44
00031 #define eye_preHeight 22
00032 
00033 
00034 MPBlink::MPBlink ( ){
00035   blink_wts::assignData(data);
00036   activation = 0;
00037   bVal.openTotal = 0;
00038   bVal.blinkTotal = 0;
00039   imgCount = 0;
00040         eyefinder = new MPEyeFinderBinary();
00041         //eyefinder->initStream(640, 480); 
00042   eyes = new RImage<float>(eye_preWidth, eye_preHeight);
00043 }
00044 
00045 MPBlink::~MPBlink ( ){
00046         eyefinder->releaseStream();
00047         delete eyes;
00048 }
00049 
00050 double MPBlink::findBlinks(const RImage<float> &pixels, VisualObject &faces,
00051                 float WINSHIFT, combine_mode mode){
00052   // First, find the faces
00053         static int lastimgWidth = 0, lastimgHeight = 0;
00054         if (pixels.width != lastimgWidth || pixels.height != lastimgHeight) {
00055                 eyefinder->resetStream(pixels.width, pixels.height);
00056                 lastimgWidth = pixels.width;
00057                 lastimgHeight = pixels.height;
00058         }
00059 
00060         eyefinder->findEyes(pixels, faces, WINSHIFT, mode);
00061         if(!faces.size())
00062                 return 0;
00063 
00064         get_eyes(pixels, faces);
00065 
00066         
00067   return 1; 
00068 }
00069 
00070 
00071 // Note: I think the image would be better quality if we were interpolating from the integral
00072 // images, because it would be taking more than just neighboring pixels into account. 
00073 // However, if we try to do interpolation from the existing RIntegral in the face_detector.stream,
00074 // it gets just as expensive to properly grab it from the Rintegral of squared pixels as to just do
00075 // interpolation from the raw image and redo the integration.  I think. Let me know if you figure it out.
00076 
00077 /*function to handle interpolation and rotation, if the eyes are rotated it handles how to rotate 
00078 the image to make the eyes perfectly aligned*/
00079 
00080 #define eye_dest_width 44
00081 #define eye_dest_height 22
00082 #define h_off_pct .02
00083 #define h_eye_factor 0.39f
00084 #define v_off_pct .02
00085 #define v_eye_factor 0.29f
00086 
00087 void MPBlink::get_eyes(const RImage<float> &pixels, VisualObject &faces){
00088         list<VisualObject *>::iterator it = faces.begin();
00089   FaceBoxList face;
00090         for (; it != faces.end(); ++it) {
00091                 FaceObject * f = static_cast<FaceObject*>(*it);
00092                 if (f->eyes.rightEye && f->eyes.leftEye){
00093 
00094                         double xd = f->eyes.xLeft - f->eyes.xRight;
00095                         double yd = f->eyes.yLeft - f->eyes.yRight;
00096                         float eye_dist = sqrt((xd*xd +yd*yd));
00097                         float sin_d = -yd/xd;
00098                         float cos_d = eye_dist/xd;
00099 
00100                         float h_eye_zero = max(0.0f,f->eyes.xRight-eye_dist*(h_eye_factor+h_off_pct));
00101                         float v_eye_zero = max(0.0f,f->eyes.yRight-eye_dist*(v_eye_factor+v_off_pct));
00102                         float xwidth = eye_dist*(1 + 2*h_eye_factor);
00103                         float ywidth = eye_dist*(2*v_eye_factor);
00104 
00105                         int xedges;
00106                         int yedges;
00107                         float xfrac;
00108                         float yfrac;
00109                         float xoff[eye_dest_width];
00110                         float yoff[eye_dest_height];
00111                         double xstep = xwidth/static_cast<double>(eye_dest_width-1);
00112                         double ystep = ywidth/static_cast<double>(eye_dest_height-1);
00113 
00114                         float j;
00115                         int i;
00116                         for(i = 0, j = 0; i < eye_dest_width; ++i, j+=xstep){
00117                                 xoff[i] = cos_d * j;
00118                                 yoff[i] = -sin_d * j;
00119                         }
00120   
00121                         float tempx, tempy;
00122                         float *p = eyes->array;
00123                         float f00, f01, f11, f10, fx0, fx1;
00124                         for(int y=0; y < eye_dest_height; ++y){ 
00125                                 float xinit = (sin_d * ystep*y)+h_eye_zero;
00126                                 float yinit = v_eye_zero + ystep*y;
00127                                 for(int x=0; x < eye_dest_width; ++x){
00128                                         tempx = xinit + xstep*x;
00129                                         tempy = yinit + yoff[x];
00130                                         xedges = static_cast<int>(tempx);
00131                                         yedges = static_cast<int>(tempy);
00132                                         xfrac = tempx - xedges;
00133                                         yfrac = tempy - yedges;
00134                                                         
00135                                         f00 = pixels.getPixel(xedges,yedges);
00136                                         f01 = pixels.getPixel(xedges,yedges + 1);
00137                                         f10 = pixels.getPixel(xedges + 1,yedges);
00138                                         f11 = pixels.getPixel(xedges + 1,yedges + 1);
00139       
00140                                         // xfrac and y frac are the remainders
00141                                         fx0 = f00 + xfrac*(f10-f00);
00142                                         fx1 = f01 + xfrac*(f11-f01);
00143                                         *(p++) = (fx0 + yfrac*(fx1-fx0)); 
00144                                 }
00145                         }
00146                         int num_blink_windows = search(*eyes, face, 0, 1.0f, 0, &f->activation,0);
00147                         //f->activation = cluster.UpdateCluster(f->activation) - f->activation;
00148                 }
00149                 else
00150                         f->activation = 0.0f;
00151         }
00152 }
00153 
00154 
00155 /*
00156  * 
00157  * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
00158  * 
00159  *    1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
00160  *    2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
00161  *    3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission.
00162  * 
00163  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00164  * 
00165  */
00166 

Generated on Mon Nov 8 17:07:30 2004 for MPT by  doxygen 1.3.9.1