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

faceobject.cpp

Go to the documentation of this file.
00001 /* 
00002  *  FACEOBJECT.cpp
00003  *
00004  *  Created by Bret Fortenberry on Aug 27, 2003.
00005  *  Fixes: 
00006  * 
00007  *  Copyright (c) 2003 Machine Perception Laboratory 
00008  *  University of California San Diego.
00009  * 
00010  * Please read the disclaimer and notes about redistribution 
00011  * at the end of this file.
00012  *  
00013  */
00014 
00015 #include "faceobject.h"
00016 #include <iostream>
00017 
00018 FaceObject::FaceObject(){
00019         feature = e_face;
00020         leftEyes.reserve(EYEMEMSIZE);
00021         rightEyes.reserve(EYEMEMSIZE);
00022 }
00023                 
00024 FaceObject::FaceObject(float x_in, float y_in, float xSize_in, float ySize_in, float scale_in){
00025         x = x_in;
00026         y = y_in;
00027         xSize = xSize_in;
00028         ySize = ySize_in;
00029         scale = scale_in;
00030         feature = e_face;
00031         leftEyes.reserve(EYEMEMSIZE);
00032         rightEyes.reserve(EYEMEMSIZE);
00033 }
00034 
00035 FaceObject::FaceObject(FaceObject &thelist)
00036 {
00037         objects = thelist.objects;
00038         x = thelist.x;
00039         y = thelist.y;
00040         xSize = thelist.xSize;
00041         ySize = thelist.ySize;
00042         scale = thelist.scale;
00043   eyes = thelist.eyes;
00044         leftEyes = thelist.leftEyes;
00045         rightEyes = thelist.rightEyes;
00046         feature = thelist.feature;
00047         activation = thelist.activation;
00048 }
00049 
00050 FaceObject::FaceObject(TSquare<float> &square)
00051 {
00052         x = square.x;
00053         y = square.y;
00054         xSize = square.size;
00055         ySize = square.size;
00056         scale = square.scale;
00057         leftEyes.reserve(EYEMEMSIZE);
00058         rightEyes.reserve(EYEMEMSIZE);
00059         feature = e_face;
00060 }
00061 
00062 FaceObject::FaceObject(list<Square>::iterator face)
00063 {
00064         x = face->x;
00065         y = face->y;
00066         xSize = face->size;
00067         ySize = face->size;
00068         scale = face->scale;
00069         feature = e_face;
00070 }
00071 
00072 FaceObject::~FaceObject() {}
00073 
00074 void FaceObject::clear(){
00075         if(objects.size())
00076         {
00077                 list< VisualObject* >::iterator it = objects.begin();
00078                 for(; it != objects.end(); ++it)
00079                 {
00080                         (*it)->clear();
00081                         delete (*it);
00082                 }
00083                 objects.clear();
00084         }
00085         leftEyes.clear();
00086         rightEyes.clear();
00087 }
00088 
00089 
00090 
00091 void FaceObject::findMax()
00092 {
00093   double max = -1000000;
00094   if(leftEyes.size()){
00095     //cout << "finding max left eye" << endl;
00096     eyes.leftEye = true;
00097     vector< EyeObject >::iterator it = leftEyes.begin();
00098     for(; it != leftEyes.end(); ++it){
00099       if(max < it->activation){
00100                                 max = it->activation;
00101                                 //cout << "max: " <<  max;
00102                                 eyes.xLeft = it->x;
00103                                 eyes.yLeft = it->y;
00104                                 eyes.leftScale = it->scale;
00105                                 //cout << " at (" << it->x << "," << it->y << ")" << endl; 
00106       }
00107     }
00108   }
00109   max = -1000000;
00110   if(rightEyes.size()){
00111     eyes.rightEye = true;
00112     vector< EyeObject >::iterator it = rightEyes.begin();
00113     for(; it != rightEyes.end(); ++it){
00114       if(max < it->activation){
00115                                 max = it->activation;
00116                                 eyes.xRight = it->x;
00117                                 eyes.yRight = it->y;
00118                                 eyes.rightScale = it->scale;
00119       }
00120     }
00121   }
00122 }
00123 
00124 void FaceObject::posterior(combine_mode mode)
00125 {
00126         switch(mode){
00127                 double maxAct;
00128                 case face_only:
00129                         eyes.xLeft = x + (xSize*0.7077f);
00130                         eyes.yLeft = y + (xSize*0.3099f);
00131                         eyes.leftScale = scale;
00132                         eyes.xRight = x + (xSize*0.3149f);
00133                         eyes.yRight = y + (xSize*0.3136f);
00134                         eyes.rightScale = scale;
00135                         break;
00136 
00137                 case wt_max:
00138                 case none:
00139 
00140                         maxAct = -1000000;
00141                         if(leftEyes.size()){
00142                                 eyes.leftEye = true;
00143                                 vector< EyeObject >::iterator it = leftEyes.begin();
00144                                 for(; it != leftEyes.end(); ++it){
00145                                         if(maxAct < it->activation){
00146                                                 maxAct = it->activation;
00147                                                 eyes.xLeft = it->x;
00148                                                 eyes.yLeft = it->y;
00149                                                 eyes.leftScale = it->scale;
00150                                         }
00151                                 }
00152                         }
00153 
00154                         maxAct = -1000000;
00155                         if(rightEyes.size()){
00156                                 eyes.rightEye = true;
00157                                 vector< EyeObject >::iterator it = rightEyes.begin();
00158                                 for(; it != rightEyes.end(); ++it){
00159                                         if(maxAct < it->activation){
00160                                                 maxAct = it->activation;
00161                                                 eyes.xRight = it->x;
00162                                                 eyes.yRight = it->y;
00163                                                 eyes.rightScale = it->scale;
00164                                         }
00165                                 }
00166                         }
00167                         break;
00168                 case wt_avg:
00169                 case average:
00170                         float xWt;
00171                         float yWt;
00172                         float scaleWt;
00173                         float totalAct;
00174                         vector< vector< float > > meanSub;
00175                         vector< vector< float > > wtMeanSub;
00176                         vector< vector< float > > invMtx;
00177                         vector< vector< float > > covMtx;
00178                         vector< EyeObject > *EyesPtr;
00179 
00180                         //cout << "leftEyes size = " << leftEyes.size() << endl;
00181                         for(int cur_eye = 0; cur_eye < 2; cur_eye++){
00182                                 bool run = false;
00183                                 if(leftEyes.size() && cur_eye == 0){  
00184                                         EyesPtr = &leftEyes;
00185                                         run = true;
00186                                 }
00187                                 else if(rightEyes.size() && cur_eye == 1){
00188                                         EyesPtr = &rightEyes;
00189                                         run = true;
00190                                 }
00191                                 else
00192                                         cur_eye++;
00193                                 if (run){
00194                                         vector< EyeObject > Eyes = *EyesPtr;
00195                                         float expo;
00196                                         bool outlier = true;
00197                                         float mean3d[3];
00198                                         float determ;
00199                                         while(outlier){
00200                                                 totalAct = 0.0f;
00201                                                 xWt = 0.0f;
00202                                                 yWt = 0.0f;
00203                                                 scaleWt = 0.0f;
00204                                                 for (int i = 0; i < Eyes.size(); i++){
00205                                                         expo = exp(Eyes[i].activation);
00206                                                         xWt += (expo * Eyes[i].x);
00207                                                         yWt += (expo * Eyes[i].y);
00208                                                         scaleWt += (expo * Eyes[i].scale);
00209                                                         totalAct += expo;
00210                                                 }
00211                                                 mean3d[0] = xWt/totalAct; mean3d[1] = yWt/totalAct; mean3d[2] = scaleWt/totalAct;
00212 
00213                                                 for(int pos = 0; pos < Eyes.size(); ++pos){
00214                                                         vector< float > v;
00215                                                         vector< float > wt;
00216                                                         expo = exp(Eyes[pos].activation);
00217                                                         v.push_back(Eyes[pos].x - mean3d[0]);
00218                                                         wt.push_back(v[0] * expo);
00219                                                         v.push_back(Eyes[pos].y - mean3d[1]);
00220                                                         wt.push_back(v[1] * expo);
00221                                                         v.push_back(Eyes[pos].scale - mean3d[2]);
00222                                                         wt.push_back(v[2] * expo);
00223                                                         meanSub.push_back(v);
00224                                                         wtMeanSub.push_back(wt);
00225                                                 }
00226                                                 float divTotAct = 1.0f/totalAct;
00227                                                 if(mtxMult_2T(meanSub, wtMeanSub, covMtx, divTotAct) != 9){
00228                                                         meanSub.clear();
00229                                                         wtMeanSub.clear();
00230                                                         invMtx.clear();
00231                                                         covMtx.clear();
00232                                                         break;
00233                                                 }
00234                                                 if(determ = det3(covMtx)){
00235                                                         TransCof3(covMtx, invMtx, determ);
00236                                                 }
00237                                                 else { //later implement psudo inverse page 192
00238                                                         meanSub.clear();
00239                                                         wtMeanSub.clear();
00240                                                         invMtx.clear();
00241                                                         covMtx.clear();
00242                                                         break; //exit while loop
00243                                                 }
00244                                                 outlier = findOutliers(meanSub, invMtx, Eyes);
00245                                                 meanSub.clear();
00246                                                 wtMeanSub.clear();
00247                                                 invMtx.clear();
00248                                                 covMtx.clear();
00249                                         }//while loop
00250                                         if(mean3d[0] > x && mean3d[0] < (x+xSize) && mean3d[1] > y && mean3d[1] < (y+ySize)){
00251                                                 if(cur_eye == 0){
00252                                                         eyes.xLeft = mean3d[0];
00253                                                         eyes.yLeft = mean3d[1];
00254                                                         eyes.leftScale = mean3d[2];
00255                                                         eyes.leftEye = true;
00256                                                 }
00257                                                 if(cur_eye == 1){
00258                                                         eyes.xRight = mean3d[0];
00259                                                         eyes.yRight = mean3d[1];
00260                                                         eyes.rightScale = mean3d[2];
00261                                                         eyes.rightEye = true;
00262                                                 }
00263                                         }
00264                                 }
00265                         }
00266 
00267                 break;
00268         };
00269 }
00270 
00271 
00272 void FaceObject::TransCof3(vector< vector< float > > &inMtx, vector< vector< float > > &rtnMtx, float det){
00273         float divDet = 1/det;
00274         vector< float > v;
00275         v.push_back((inMtx[1][1]*inMtx[2][2]-inMtx[1][2]*inMtx[2][1])*divDet);
00276         v.push_back(-(inMtx[0][1]*inMtx[2][2]-inMtx[0][2]*inMtx[2][1])*divDet);
00277         v.push_back((inMtx[0][1]*inMtx[1][2]-inMtx[0][2]*inMtx[1][1])*divDet);
00278         rtnMtx.push_back(v);
00279         vector< float > v2;
00280         v2.push_back(-(inMtx[1][0]*inMtx[2][2]-inMtx[1][2]*inMtx[2][0])*divDet);
00281         v2.push_back((inMtx[0][0]*inMtx[2][2]-inMtx[0][2]*inMtx[2][0])*divDet);
00282         v2.push_back(-(inMtx[0][0]*inMtx[1][2]-inMtx[0][2]*inMtx[1][0])*divDet);
00283         rtnMtx.push_back(v2);
00284         vector< float > v3;
00285         v3.push_back((inMtx[1][0]*inMtx[2][1]-inMtx[1][1]*inMtx[2][0])*divDet);
00286         v3.push_back(-(inMtx[0][0]*inMtx[2][1]-inMtx[0][1]*inMtx[2][0])*divDet);
00287         v3.push_back((inMtx[0][0]*inMtx[1][1]-inMtx[0][1]*inMtx[1][0])*divDet);
00288         rtnMtx.push_back(v3);
00289 }//http://astronomy.swin.edu.au/~pbourke/analysis/inverse/
00290 
00291 float FaceObject::det3(vector< vector< float > > &matrix){ 
00292         if ((matrix.size() != 3) || (matrix[0].size() != 3))
00293                 return (0.0f);
00294         return ((matrix[0][0] * (matrix[1][1]*matrix[2][2] - matrix[1][2]*matrix[2][1])) - 
00295                 (matrix[0][1] * (matrix[1][0]*matrix[2][2] - matrix[1][2]*matrix[2][0])) +
00296                 (matrix[0][2] * (matrix[1][0]*matrix[2][1] - matrix[1][1]*matrix[2][0])));
00297 }//http://www.mathworks.com/access/helpdesk/help/toolbox/aeroblks/determinantof3x3matrix.shtml
00298 
00299 
00300 
00301 int FaceObject::mtxMult(vector< vector< float > > &matrix1, vector< vector< float > > &matrix2, vector< vector< float > > &rtnMtx){
00302         if(matrix1[0].size() != matrix2.size()){
00303                 return 0;
00304                 }
00305         rtnMtx.clear();
00306         float comb;
00307         int size = 0;
00308         for(int cur_row = 0; cur_row < matrix1.size(); ++cur_row){
00309                 vector< float > v;
00310                 for(int cur_col = 0; cur_col < matrix2[0].size(); ++cur_col){
00311                         comb = 0;
00312                         for(int cur_pos = 0; cur_pos < matrix1[0].size(); ++cur_pos){
00313                                 comb += matrix1[cur_row][cur_pos] * matrix2[cur_pos][cur_col];
00314                         }
00315                         v.push_back(comb);
00316                         size++;
00317                 }
00318                 rtnMtx.push_back(v);
00319         }
00320         return size;
00321 }
00322 
00323 
00324 int FaceObject::mtxMult_2T(vector< vector< float > > &matrix1, vector< vector< float > > &matrix2, vector< vector< float > > &rtnMtx, float mult){
00325         if(matrix1.size() != matrix2.size())
00326                 return 0;
00327         rtnMtx.clear();
00328         float comb;
00329         int size = 0;
00330         for(int cur_row = 0; cur_row < matrix1[0].size(); ++cur_row){
00331                 vector< float > v;
00332                 for(int cur_col = 0; cur_col < matrix2[0].size(); ++cur_col){
00333                         comb = 0;
00334                         for(int cur_pos = 0; cur_pos < matrix1.size(); ++cur_pos){
00335                                 comb += matrix1[cur_pos][cur_row] * matrix2[cur_pos][cur_col];
00336                         }
00337                         v.push_back(comb*mult);
00338                         size++;
00339                 }
00340                 rtnMtx.push_back(v);
00341         }
00342         return size;
00343 }
00344 
00345 
00346 bool FaceObject::findOutliers(vector< vector< float > > &meanSub, vector< vector< float > > &invMtx, vector< EyeObject > &Eyes){
00347         vector< vector< float > > mnSubMtx;
00348         vector< vector< float > > tempMtx;
00349         vector< vector< float > > di;
00350         bool rtn = false;
00351         for (int i = (meanSub.size() - 1); i >= 0; --i){
00352                 mnSubMtx.push_back(meanSub[i]);
00353                 mtxMult(mnSubMtx, invMtx, tempMtx);
00354                 mtxMult_2T(tempMtx, mnSubMtx, di);
00355                 //cout << "outlier di = " << di[0][0] << endl;
00356                 if (di[0][0] > 1.0f){
00357 #ifndef WIN32
00358                         cout << "outlier di !!!!!!!= " << di[0][0] << endl;
00359 #endif
00360                         rtn = true;
00361                         Eyes.erase(Eyes.begin() + i);
00362                 }
00363                 mnSubMtx.clear();
00364                 tempMtx.clear();
00365                 di.clear();
00366         }
00367         return rtn;
00368 }
00369 
00370 
00371 #ifndef WIN32
00372 int FaceObject::prtMtx(vector< vector< float > > &matrix){
00373         for(int cur_row = 0; cur_row < matrix.size(); ++cur_row){
00374                 cout << "(";
00375                 for(int cur_col = 0; cur_col < matrix[0].size(); ++cur_col){
00376                                 cout << matrix[cur_row][cur_col] << ", ";
00377                 }
00378                 cout << ")\n";
00379         }
00380         cout << endl;
00381         return 1;
00382 }
00383 #endif
00384 
00385 
00386 /*
00387  * 
00388  * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
00389  * 
00390  *    1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
00391  *    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.
00392  *    3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission.
00393  * 
00394  * 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.
00395  * 
00396  */

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