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

mpisearchMex.cc

Go to the documentation of this file.
00001 /*
00002  *  mpisearchMex.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 "mpisearchMex.h"
00023 #include "ci.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 static inline double difftv(const struct timeval &t1, const struct timeval &t0)
00037 { return( (t1.tv_sec -t0.tv_sec )*1.0 +(t1.tv_usec-t0.tv_usec)*1e-6); }
00038 
00039 extern "C" {
00040 void mexFunction(int nlhs,mxArray *plhs[],int nrhs, const mxArray *prhs[]);
00041 }
00042 
00043 void mexFunction(int nlhs,mxArray*plhs[],int nrhs, const mxArray*prhs[]) 
00044 {
00045   //[boxes, detects, n, index_array, output_values] = mpisearchMex(ci, img, get_detects, do_simplify, box, index_array, output_values)
00046   // check and get input / output
00047   if (nlhs < 3 )
00048     mexErrMsgTxt("mpisearchMex: requires at least three outputs");
00049   if (nrhs < 5)
00050     mexErrMsgTxt("mpisearchMex: requires at least five inputs");
00051   
00052   const mxArray ** ci = &(prhs[0]);
00053   double * img = mxGetPr(prhs[1]);
00054   int rows = static_cast<int>(mxGetM(prhs[1]));
00055   int cols = static_cast<int>(mxGetN(prhs[1]));
00056   int max_num_detects = static_cast<int>(mxGetScalar(prhs[2]));
00057   int do_simplify = static_cast<int>(mxGetScalar(prhs[3]));
00058   int box = static_cast<int>(mxGetScalar(prhs[4]));
00059   double *index_flags=NULL, *output_values=NULL;
00060   int reset_aH = 1;
00061 
00062   // Should change this to automatically create the appropriate memory if needed, but will do it later
00063   if(nlhs > 3){
00064     if(nrhs <= 5)
00065       mexErrMsgTxt("mpisearchMex: you must input the index_flags array if you also want it as output");
00066 
00067     plhs[3] = mxCreateNumericMatrix(mxGetM(prhs[5]),mxGetN(prhs[5]), mxDOUBLE_CLASS, 0);
00068     index_flags = mxGetPr(plhs[3]);
00069     double *input_index_flags = mxGetPr(prhs[5]);
00070     int index_len = max(mxGetM(prhs[5]),mxGetN(prhs[5]));
00071     for(int i = 0; i < index_len; ++i)
00072       index_flags[i] = input_index_flags[i];
00073   }
00074   if(nlhs > 4){
00075     if(nrhs <= 6)
00076       mexErrMsgTxt("mpisearchMex: you must input the output_values array if you also want it as output");
00077     plhs[4] = mxCreateNumericMatrix(mxGetM(prhs[6]),mxGetN(prhs[6]), mxDOUBLE_CLASS, 0);
00078     output_values = mxGetPr(plhs[4]);
00079     double *input_output_values = mxGetPr(prhs[6]);
00080     int output_len = max(mxGetM(prhs[6]),mxGetN(prhs[6]));
00081     for(int i = 0; i < output_len; ++i)
00082       output_values[i] = input_output_values[i];
00083   }
00084   
00085   if(nrhs >= 8){
00086     reset_aH = static_cast<int>(mxGetScalar(prhs[7]));
00087   } else
00088     reset_aH = 1;
00089 
00090 
00091   // create image and make upright (i.e., transpose)
00092   RImage<float> pixels(cols, rows);
00093   //cout << "Image: " 
00094   //    << pixels.width 
00095   //     << "x" << pixels.height 
00096   //     << endl;
00097   int ct = 0;
00098   for (int c = 0; c < cols; c++){
00099     for(int r = 0; r < rows; r++){ 
00100       pixels.array[cols*r+c] = static_cast<float>(*(img++));
00101     }
00102   }
00103 
00104   // Initialize the MPISearchMex object
00105   struct timeval tv_now, last;
00106   gettimeofday(&last,0);
00107   MPISearchMex *mpisearch = new MPISearchMex((mxIsStruct(prhs[0]) ? ci : NULL), max_num_detects, plhs[1]);
00108   gettimeofday(&tv_now,0);
00109   //cout << "Loading the data took "<< difftv(tv_now, last) << " seconds" << endl;
00110 
00111   // Search
00112   FaceBoxList faces;
00113   //cout << "Starting Search" << endl;
00114   gettimeofday(&last,0);
00115   plhs[2] = mxCreateNumericMatrix(1, 1, mxDOUBLE_CLASS, mxREAL);
00116   *(mxGetPr(plhs[2])) = mpisearch->search(pixels, faces, 0, 1, index_flags, output_values, box);
00117   gettimeofday(&tv_now,0);
00118   //cout << "   The search took "<< difftv(tv_now, last) << " seconds" << endl;
00119 
00120   // Simplify if necessary
00121   if(do_simplify){
00122     printf("Initially found %d faces.\n", faces.size());
00123     faces.simplify(0.24f);
00124     printf("Now found %d.\n", faces.size());
00125   }
00126 
00127   // write out face boxes into a matlab happy array
00128   int nBoxes = faces.size();
00129   plhs[2] = mxCreateNumericMatrix(1, 1, mxDOUBLE_CLASS, 0);
00130   *mxGetPr(plhs[2]) = nBoxes;
00131   plhs[0] = mxCreateNumericMatrix(nBoxes, 6, mxDOUBLE_CLASS, 0);
00132   if(nBoxes != 0) {
00133     double * boxes = mxGetPr(plhs[0]);
00134     int boxCounter = 0;
00135     while(!faces.empty( ))
00136       {
00137         Square face = faces.front();  
00138         faces.pop_front();
00139         boxes[nBoxes*0+boxCounter] = 1;
00140         boxes[nBoxes*1+boxCounter] = 1;
00141         boxes[nBoxes*2+boxCounter] = face.y;
00142         boxes[nBoxes*3+boxCounter] = face.y + face.size;
00143         boxes[nBoxes*4+boxCounter] = face.x;
00144         boxes[nBoxes*5+boxCounter] = face.x + face.size;
00145         boxCounter++;
00146       }
00147   }
00148 
00149   // Properly dimension the patches array;
00150   if(max_num_detects){
00151     double *ptr;
00152     void *newptr;
00153     ptr = mxGetPr(plhs[1]);
00154     newptr = mxRealloc(ptr,static_cast<int>(sizeof(*ptr) * 
00155                            (mpisearch->patchSize()*mpisearch->patchSize()*min(nBoxes, max_num_detects))));
00156     mxSetPr(plhs[1],static_cast<double *>(newptr));
00157     int dims[3] = {mpisearch->patchSize(), mpisearch->patchSize(), min(nBoxes, max_num_detects)};
00158     mxSetDimensions(plhs[1], dims, 3);
00159   }
00160 
00161   delete mpisearch;
00162 }
00163 

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