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

mp_eyefinderMex.cc

Go to the documentation of this file.
00001 /*
00002  *  mp_eyefinderMex.cc
00003  * 
00004  *  Matlab interface for calling C++ mpisearch face detector from matlab  
00005  *
00006  *  Created by Ian Fasel on Thu Apr 18 2002.
00007  * 
00008  *  Copyright (c) 2003 Machine Perception Laboratory
00009  *  University of California San Diego.
00010  *
00011  * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
00012  *
00013  *    1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
00014  *    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.
00015  *    3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission.
00016  *
00017  * 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.
00018  *
00019  */
00020 
00021 
00022 #include "mp_eyefinderMex.h"
00023 #include "loadstruct.h"
00024 #include <iostream>   //TESTING!
00025 
00026 extern "C" {
00027 #include <math.h>
00028 #include <string.h>
00029 #include <stdlib.h>
00030 #include <sys/time.h>
00031 #include <unistd.h>
00032 #include "mex.h" 
00033 #include "matrix.h"  
00034 }
00035 
00036 
00037 
00038 MPEyeFinderMex::MPEyeFinderMex (const mxArray ** leftEyeCi, const mxArray ** rightEyeCi) : MPEyeFinder() {
00039   mpisearchMexData::loadStruct(leftEyeCi,left_eye_data);
00040   mpisearchMexData::loadStruct(rightEyeCi,right_eye_data);
00041   // cout << "Loaded struct. Now doing extra bits." << endl;
00042   // load centering and patch_conditions
00043   int centering_field = -1;
00044   int patch_condition_field = -1;
00045   int nfields = mxGetNumberOfFields(*leftEyeCi);
00046   for(int i = 0; i < nfields; ++i){
00047     const char * field = mxGetFieldNameByNumber(*leftEyeCi, i);
00048     if(!strcmp(field, "centering"))
00049       centering_field = i;
00050     if(!strcmp(field, "patch_condition"))
00051       patch_condition_field = i;
00052   }
00053   // cout << "patch_condition_field: " << patch_condition_field <<endl;
00054   char buf[255]; int buflen = 255;
00055   if(centering_field != -1){
00056     mxGetString(mxGetFieldByNumber(*leftEyeCi, 0, centering_field),buf,buflen);
00057     if(!strcmp(buf,"face_centered"))
00058       m_centering = face_centered;
00059     else if(!strcmp(buf,"eye_centered"))
00060       m_centering = eye_centered;
00061     else
00062       mexErrMsgTxt("mp_eyefinderMex: invalid centering in ci");
00063   } else
00064     mexErrMsgTxt("mp_eyefinderMex: must specify centering in ci");
00065 
00066   if(patch_condition_field != -1){
00067     mxGetString(mxGetFieldByNumber(*leftEyeCi, 0, patch_condition_field),buf,buflen);
00068     if(!strcmp(buf,"largest_2"))
00069       m_rez = largest_2;
00070     else if(!strcmp(buf,"largest"))
00071       m_rez = largest;
00072     else if(!strcmp(buf,"eye_dist"))
00073       m_rez = eye_dist;
00074     else if(!strcmp(buf,"half_dist"))
00075       m_rez = half_dist;
00076     else if(!strcmp(buf,"eye_only"))
00077       m_rez = eye_only;
00078     else if(!strcmp(buf,"smallest"))
00079       m_rez = smallest;
00080     else
00081       mexErrMsgTxt("mp_eyefinderMex: invalid patch_condition in ci");
00082   } else
00083     mexErrMsgTxt("mp_eyefinderMex: must specify patch_conditon in ci");
00084 }
00085 
00086 MPEyeFinderMex::~MPEyeFinderMex (){
00087   mpisearchMexData::releaseStruct(left_eye_data);
00088   mpisearchMexData::releaseStruct(right_eye_data);
00089 }
00090 
00091 static inline double difftv(const struct timeval &t1, const struct timeval &t0)
00092 { return( (t1.tv_sec -t0.tv_sec )*1.0 +(t1.tv_usec-t0.tv_usec)*1e-6); }
00093 
00094 extern "C" {
00095 void mexFunction(int nlhs,mxArray *plhs[],int nrhs, const mxArray *prhs[]);
00096 }
00097 
00098 void mexFunction(int nlhs,mxArray*plhs[],int nrhs, const mxArray*prhs[])
00099 {
00100   //[boxes, detects] = MPEyeFinderMex(ci, ci2, img, get_detects)
00101   // check and get input / output
00102   if (nlhs < 1 )
00103     mexErrMsgTxt("mp_eyefinderMex: requires at least one output");
00104   if (nrhs < 5)
00105         mexErrMsgTxt("mp_eyefinderMex: requires at least 5 inputs");
00106 
00107   const mxArray ** leftCI = &(prhs[0]);
00108   const mxArray ** rightCI = &(prhs[1]);
00109   double * img = mxGetPr(prhs[2]);
00110   int rows = static_cast<int>(mxGetM(prhs[2]));
00111   int cols = static_cast<int>(mxGetN(prhs[2]));
00112   int get_detects = static_cast<int>(mxGetScalar(prhs[3]));
00113         int modestrlen = 256;
00114   char modestr[255];
00115   mxGetString(prhs[4],modestr,modestrlen);
00116   combine_mode themode;
00117   cout << "Using mode "<<modestr<<endl;
00118         for(int i = 0; i < num_modes; ++i){
00119                 if(!strcmp(modestr,mode_strings[i])){
00120                         themode = static_cast<combine_mode>(i);
00121       break;
00122     }
00123   }
00124         cout << "The enum we got was " << themode << endl;
00125 
00126   // create image and make upright (i.e., transpose)
00127   RImage<MPISEARCH_PIXEL_TYPE> pixels(cols, rows);
00128   // cout << "Image: "
00129   //     << pixels.width
00130   //     << "x" << pixels.height
00131   //     << endl;
00132   int ct = 0;
00133   for (int c = 0; c < cols; c++){
00134     for(int r = 0; r < rows; r++){
00135       pixels.array[cols*r+c] = static_cast<MPISEARCH_PIXEL_TYPE>(*(img++));
00136     }
00137   }
00138 
00139   // Initialize the MPEyeFinderMex object
00140   struct timeval tv_now, last;
00141   gettimeofday(&last,0);
00142   MPEyeFinderMex *mpeyefinder = new MPEyeFinderMex(leftCI, rightCI);
00143   gettimeofday(&tv_now,0);
00144   // cout << "Loading the data took " << difftv(tv_now, last) << " seconds" << endl;
00145   mpeyefinder->initStream(pixels.width, pixels.height);
00146 
00147   // Search
00148   VisualObject faces;
00149   // cout << "Starting Search" << endl;
00150   gettimeofday(&last,0);
00151   mpeyefinder->findEyes(pixels, faces, 1.0f, themode);
00152   gettimeofday(&tv_now,0);
00153   cout << "   The search took "<< difftv(tv_now, last) << " seconds" << endl;
00154 
00155   // Write results into matlab struct array
00156 
00157   int dims[2];
00158   dims[0] = faces.size(); dims[1] = 1;
00159 
00160   if(faces.size()){
00161     // initialize field names
00162     // stupid, but matlab crashes if I just pass field_names in directly
00163     const int nfields = 17;
00164     const char field_names[nfields][25] = {"x","y","size","xLeft","yLeft","xRight","yRight",
00165                                 "left_eye_x","left_eye_y","left_eye_size","left_eye_activation","left_eye_flag",
00166                                                 "right_eye_x","right_eye_y","right_eye_size","right_eye_activation","right_eye_flag"};
00167     const char **fnames;       /* pointers to field names */
00168     fnames = (const char **)mxCalloc(nfields, sizeof(*fnames));
00169     for(int i = 0; i < nfields; ++i){
00170       fnames[i] = (char *)malloc(25 * sizeof(char));
00171       strcpy((char *)fnames[i],field_names[i]);
00172     }
00173     // cout << "Creating struct matrix" << endl;
00174     plhs[0] = mxCreateStructArray(2, dims, nfields, fnames);
00175     mxFree(fnames);
00176     if(plhs[0] == NULL)
00177       mexErrMsgTxt("could not allocate space for struct");
00178     int xfield = mxGetFieldNumber(plhs[0],"x");
00179     int yfield = mxGetFieldNumber(plhs[0],"y");
00180     int sizefield = mxGetFieldNumber(plhs[0],"size");
00181     int xLeftfield = mxGetFieldNumber(plhs[0],"xLeft");
00182     int yLeftfield = mxGetFieldNumber(plhs[0],"yLeft");
00183     int xRightfield = mxGetFieldNumber(plhs[0],"xRight");
00184     int yRightfield = mxGetFieldNumber(plhs[0],"yRight");
00185     int left_eye_xfield = mxGetFieldNumber(plhs[0],"left_eye_x");
00186     int left_eye_yfield = mxGetFieldNumber(plhs[0],"left_eye_y");
00187     int left_eye_sizefield = mxGetFieldNumber(plhs[0],"left_eye_size");
00188     int left_eye_activationfield = mxGetFieldNumber(plhs[0],"left_eye_activation");
00189     int left_eye_flagfield = mxGetFieldNumber(plhs[0],"left_eye_flag");
00190     int right_eye_xfield = mxGetFieldNumber(plhs[0],"right_eye_x");
00191     int right_eye_yfield = mxGetFieldNumber(plhs[0],"right_eye_y");
00192     int right_eye_sizefield = mxGetFieldNumber(plhs[0],"right_eye_size");
00193     int right_eye_activationfield = mxGetFieldNumber(plhs[0],"right_eye_activation");
00194     int right_eye_flag = mxGetFieldNumber(plhs[0],"right_eye_flag");
00195 
00196     list<VisualObject *>::iterator face = faces.begin();
00197     list<VisualObject *>::iterator last_face = faces.end();
00198     // cout << "Num Faces: " << faces.size() << endl;
00199     for(int i = 0; face != last_face; ++face, ++i){
00200       // cout << "Setting fields for face " << i << endl; 
00201       FaceObject *f = static_cast<FaceObject*>(*face);
00202       // cout << "f->x: " << f->x << endl;
00203       mxArray *facex = mxCreateDoubleScalar(f->x);
00204       mxSetFieldByNumber(plhs[0],i,xfield,facex);
00205       mxArray *facey = mxCreateDoubleScalar(f->y);
00206       mxSetFieldByNumber(plhs[0],i,yfield,facey);
00207       mxArray *facesize = mxCreateDoubleScalar(f->xSize);
00208       mxSetFieldByNumber(plhs[0],i,sizefield,facesize);
00209       mxArray *facexLeft = mxCreateDoubleScalar(f->eyes.xLeft);
00210       mxSetFieldByNumber(plhs[0],i,xLeftfield,facexLeft);
00211       mxArray *faceyLeft = mxCreateDoubleScalar(f->eyes.yLeft);
00212       mxSetFieldByNumber(plhs[0],i,yLeftfield,faceyLeft);
00213       mxArray *facexRight = mxCreateDoubleScalar(f->eyes.xRight);
00214       mxSetFieldByNumber(plhs[0],i,xRightfield,facexRight);
00215       mxArray *faceyRight = mxCreateDoubleScalar(f->eyes.yRight);
00216       mxSetFieldByNumber(plhs[0],i,yRightfield,faceyRight);
00217 
00218 
00219       // Create structures for eyes of each face
00220       // cout << "Doing left eyes" << endl;
00221       int numLeftEyes = f->leftEyes.size();
00222       mxArray *left_eye_x;
00223       mxArray *left_eye_y;
00224       mxArray *left_eye_size;
00225       mxArray *left_eye_act;
00226       mxArray *left_eye_flag;
00227       if(numLeftEyes == 0){
00228         left_eye_x = mxCreateDoubleMatrix(0,0,mxREAL);
00229         left_eye_y = mxCreateDoubleMatrix(0,0,mxREAL);
00230         left_eye_size = mxCreateDoubleMatrix(0,0,mxREAL);
00231         left_eye_act = mxCreateDoubleMatrix(0,0,mxREAL);
00232         left_eye_flag = mxCreateDoubleMatrix(0,0,mxREAL);
00233 
00234       } else {
00235         left_eye_x = mxCreateDoubleMatrix(numLeftEyes,1,mxREAL);
00236         left_eye_y = mxCreateDoubleMatrix(numLeftEyes,1,mxREAL);
00237         left_eye_size = mxCreateDoubleMatrix(numLeftEyes,1,mxREAL);
00238         left_eye_act = mxCreateDoubleMatrix(numLeftEyes,1,mxREAL);
00239         left_eye_flag = mxCreateDoubleMatrix(numLeftEyes,1,mxREAL);
00240         double *plx, *ply, *pls, *pla, *plf;
00241         plx = mxGetPr(left_eye_x);
00242         ply = mxGetPr(left_eye_y);
00243         pls = mxGetPr(left_eye_size);
00244         pla = mxGetPr(left_eye_act);
00245         plf = mxGetPr(left_eye_flag);
00246         for(int k = 0; k < f->leftEyes.size(); ++k){
00247                                         EyeObject *le = &(f->leftEyes[k]);
00248                                         *plx++ = le->x;
00249                                         *ply++ = le->y;
00250                                         *pls++ = le->scale;
00251                                         *pla++ = le->activation;
00252                 *plf++ = le->flag;
00253         }
00254       }
00255       mxSetField(plhs[0], i, "left_eye_x", left_eye_x);
00256       mxSetField(plhs[0], i, "left_eye_y", left_eye_y);
00257       mxSetField(plhs[0], i, "left_eye_size", left_eye_size);
00258       mxSetField(plhs[0], i, "left_eye_activation", left_eye_act);
00259       mxSetField(plhs[0], i, "left_eye_flag", left_eye_flag);
00260 
00261       // cout << "Doing right eyes" << endl;
00262       int numRightEyes = f->rightEyes.size();
00263       mxArray *right_eye_x;
00264       mxArray *right_eye_y;
00265       mxArray *right_eye_size;
00266       mxArray *right_eye_act;
00267       mxArray *right_eye_flag;
00268       if(numRightEyes == 0){
00269         right_eye_x = mxCreateDoubleMatrix(0,0,mxREAL);
00270         right_eye_y = mxCreateDoubleMatrix(0,0,mxREAL);
00271         right_eye_size = mxCreateDoubleMatrix(0,0,mxREAL);
00272         right_eye_act = mxCreateDoubleMatrix(0,0,mxREAL);
00273         right_eye_flag = mxCreateDoubleMatrix(0,0,mxREAL);
00274       } else {
00275         right_eye_x = mxCreateDoubleMatrix(numRightEyes,1,mxREAL);
00276         right_eye_y = mxCreateDoubleMatrix(numRightEyes,1,mxREAL);
00277         right_eye_size = mxCreateDoubleMatrix(numRightEyes,1,mxREAL);
00278         right_eye_act = mxCreateDoubleMatrix(numRightEyes,1,mxREAL);
00279         right_eye_flag = mxCreateDoubleMatrix(numRightEyes,1,mxREAL);
00280         double *prx, *pry, *prs, *pra, *prf;
00281         prx = mxGetPr(right_eye_x);
00282         pry = mxGetPr(right_eye_y);
00283         prs = mxGetPr(right_eye_size);
00284         pra = mxGetPr(right_eye_act);
00285         prf = mxGetPr(right_eye_flag);
00286         for(int k = 0; k < f->rightEyes.size(); ++k){
00287           EyeObject *re = &(f->rightEyes[k]);
00288           *prx++ = re->x;
00289           *pry++ = re->y;
00290           *prs++ = re->scale;
00291           *pra++ = re->activation;
00292           *prf++ = re->flag;
00293         }
00294       }
00295       mxSetField(plhs[0], i, "right_eye_x", right_eye_x);
00296       mxSetField(plhs[0], i, "right_eye_y", right_eye_y);
00297       mxSetField(plhs[0], i, "right_eye_size", right_eye_size);
00298       mxSetField(plhs[0], i, "right_eye_activation", right_eye_act);
00299       mxSetField(plhs[0], i, "right_eye_flag", right_eye_flag);
00300 
00301     }
00302   } else {
00303     plhs[0] = mxCreateDoubleMatrix(0,0,mxREAL);
00304   }
00305   delete mpeyefinder;
00306 }
00307 
00308 
00309 

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