/home/fwph/code/wurde/modules/visionModule/Operators/face/FaceOperator.cpp

Go to the documentation of this file.
00001 #include "FaceOperator.H"
00002 #include <Logger.H>
00003 #include <string>
00004 
00005 #include "cv.h"
00006 #include "highgui.h"
00007 #include "cvaux.h"
00008 
00009 #include "cvtypes.h"
00010 
00011 #include "MyHaar.H"
00012 
00013 
00014 using namespace std;
00015 using namespace RobotObjects;
00016 using namespace RobotVision;
00017 
00018 FaceOperator::FaceOperator(std::string pName) : VisionOperator(pName), mRangeFinder(STRAT_ASSIGNED, "LaserClient"), mPtu(STRAT_ASSIGNED, "PTUClient"), mFaceDetector(pName) {
00019         m_state = STATE_RUN;
00020         g_debug("Registering a SickLaser consumer");
00021         registerConsumer(&mRangeFinder);
00022         g_debug("Registering a PTU consumer");
00023         registerConsumer(&mPtu);
00024         g_debug("Registering a FaceDetector supplier");
00025         registerSupplier(&mFaceDetector);
00026         count = 0;
00027 }
00028 
00029 void FaceOperator::initOperator() {
00030         g_debug("Initializing Face Detector");
00031                 
00032         g_debug("Creating HAAR Cascade");
00033 
00034   //  Hard-coded at the moment until I can get the configuration working
00035         //mCascade = (CvHaarClassifierCascade*)cvLoad( "haarcascade_frontalface_default.xml" ,0, 0, 0 );
00036         
00037         /*char msg[1024]; 
00038         sprintf(msg, "%'s Cascade name from config: %s", m_name.c_str(), g_globalConfiguration.getModuleOption(m_name,"HAARCascadeFile").c_str());      
00039   if(g_globalConfiguration.haveModuleOption(m_name,"HAARCascadeFile")) {        g_debug(msg); } else { g_debug("Don't have HAARCascadeFile"); }
00040         sprintf(msg, "%'s 'asdf' from config: %s", m_name.c_str(), g_globalConfiguration.getModuleOption(m_name,"asdf").c_str());       
00041   if(g_globalConfiguration.haveModuleOption(m_name,"asdf")) {   g_debug(msg); } else { g_debug("Don't have asdf"); }
00042   g_debug(msg);*/
00043         std::string configfile;
00044 
00045         if(g_globalConfiguration.haveModuleOption(m_name,"HAARCascadeFile")){
00046                configfile=g_globalConfiguration.getModuleOption(m_name,"HAARCascadeFile");
00047                if(configfile[0]!='/'){
00048                       configfile=g_globalConfiguration.getConfigDirectory()+"/"+configfile;
00049                }
00050         }else if(g_globalConfiguration.haveOption("HAARCascadeFile")){
00051                configfile=g_globalConfiguration.getOption("HAARCascadeFile");
00052                if(configfile[0]!='/'){
00053                       configfile=g_globalConfiguration.getConfigDirectory()+"/"+configfile;
00054                }
00055         }else{
00056                configfile=g_globalConfiguration.getConfigDirectory()+"/"+"haarcascade_frontalface_default.xml";
00057         }
00058 
00059         //      mCascade = (CvHaarClassifierCascade*)cvLoad( g_globalConfiguration.getOption("HAARCascadeFile").c_str(), 0, 0, 0 );
00060         mCascade = (CvHaarClassifierCascade*)cvLoad( configfile.c_str(), 0, 0, 0 );
00061 
00062         if(!g_globalConfiguration.haveModuleOption(m_name,"MinHeight")||
00063            !g_globalConfiguration.haveModuleOption(m_name,"MaxHeight")){
00064                mMinHeight=1;
00065                mMaxHeight=2;
00066         }else{
00067                mMinHeight = atof(g_globalConfiguration.getModuleOption(m_name,"MinHeight").c_str());
00068                mMaxHeight = atof(g_globalConfiguration.getModuleOption(m_name,"MaxHeight").c_str());
00069         }
00070         
00071 
00072         if(!g_globalConfiguration.haveModuleOption(m_name,"MinSize")||
00073            !g_globalConfiguration.haveModuleOption(m_name,"MaxSize")){
00074                mMinSize=0.08;
00075                mMaxSize=0.4;
00076         }else{
00077                mMinSize = atof(g_globalConfiguration.getModuleOption(m_name,"MinSize").c_str());
00078                mMaxSize = atof(g_globalConfiguration.getModuleOption(m_name,"MaxSize").c_str());
00079         }
00080 
00081         
00082         mStorage = cvCreateMemStorage(0);
00083         
00084         m_state = STATE_RUN;
00085         
00086         //This really should be FORMAT_CHAR_1_GRAY, but it's not implemented yet
00087         m_format=FORMAT_CHAR_1_GRAY;
00088         m_stereo=false;
00089         
00090         // Uncomment only if you are going to be debugging, as it creates an X window that displays the stream
00091         // cvNamedWindow("Name of Window", CV_WINDOW_AUTOSIZE);
00092         mFrames = 0;
00093         g_debug("Done initializing FD");
00094 }
00095 
00096 struct pixel {
00097   char b,g,r;
00098 };
00099 
00100 void ColorPixel(void * pImg, int pX, int pY, char pR, char pG, char pB) {
00101   pixel *img = (pixel *)pImg;
00102   if(pX >= 0 && pX < 320 && pY >= 0 && pY < 240) {
00103                 img[pY * 320 + pX].r = pR;
00104                 img[pY * 320 + pX].g = pG;
00105                 img[pY * 320 + pX].b = pB;              
00106         }
00107 }
00108 void FaceOperator::DrawLaserDataDots(IplImage *pImg, double *pData, unsigned char r, unsigned char g, unsigned char b) {
00109 
00110         double pan, tilt;
00111                 
00112         GetPTUData(&pan, &tilt);
00113   //Put some nice dots on the screen where the laser hit
00114   for(int i = 0; i < 181; i++) {
00115                 double radians = i / 180.0 * 3.141592 - (3.141592 / 2.0);
00116                 
00117                 double cp = cos(pan);  //Might need to change these to positive
00118                 double sp = sin(pan);
00119                 double ct = cos(tilt);
00120                 double st = sin(tilt);
00121                 
00122                 double wx = cos(radians) * pData[i];
00123                 double wy = sin(radians) * pData[i];
00124                 double wz = 0.38;
00125                 
00126           double camx =  ct * cp * wx + ct * sp  * wy + st * wz - .13 * cp * ct ;
00127     double camy = -sp * wx + cp * wy + sp * 0.13 - 0.09;
00128     double camz = -st * cp * wx + -st * sp * wy + ct * wz + 0.13 * cp * st - 1.48 * ct;
00129                 
00130                 int xpix = 320 - int(387.5 * tan(atan2(camy, camx)) + 160);
00131                 int ypix = 240 - int(387.5 * tan(atan2(camz, camx)) + 120);
00132                 
00133                 ColorPixel(pImg->imageData, xpix, ypix, r, g, b);
00134                 ColorPixel(pImg->imageData, xpix+1, ypix, r, g, b);
00135                 ColorPixel(pImg->imageData, xpix-1, ypix, r, g, b);
00136                 ColorPixel(pImg->imageData, xpix, ypix+1, r, g, b);
00137                 ColorPixel(pImg->imageData, xpix, ypix-1, r, g, b);
00138         }
00139         //printf("Pan: %f - Tilt: %f\n", pan, tilt);
00140 }
00141 
00142 
00143 bool done = false;
00144 
00145 void FaceOperator::runOperator(RoleImage mImage) {
00146        if(mFrames == 0) {
00147               mBegin.now();
00148        }
00149        mFrames++;
00150         
00151        CvPoint pt1, pt2;
00152        char buff[256];
00153 
00154        cvClearMemStorage( mStorage );
00155 
00156        CvSize imgSize;
00157        imgSize.width = 320;
00158        imgSize.height = 240;
00159 
00160        /*       IplImage* temp= cvCreateImage(imgSize,IPL_DEPTH_8U,3);
00161        for(int i = 0;i < 76800;++i){
00162               temp[i*3]=mImage.second[i];
00163               temp[i*3+1]=mImage.second[i];
00164               temp[i*3+2]=mImage.second[i];
00165               }*/
00166        
00167         double ranges[181];
00168         for(int i =0; i < 181; i++) { ranges[i] = 99999999; }
00169         GetLaserData(ranges);
00170         //DrawLaserDataDots(mImage.second, ranges, 255,0,0);
00171         GetClosedLaserData(ranges);
00172         //DrawLaserDataDots(mImage.second, ranges, 0,255,0);
00173         double pan, tilt;
00174         GetPTUData(&pan, &tilt);
00175 
00176         CvSeq* faces = myHaarDetectObjects( mImage.second, mCascade, mStorage,1.1, 2, CV_HAAR_DO_CANNY_PRUNING, cvSize(20, 20), ranges, pan, tilt, mMinHeight, mMaxHeight, mImage.second,mMinSize,mMaxSize);
00177         //CvSeq* faces = cvHaarDetectObjects( mImage.second, mCascade, mStorage,1.1, 2, CV_HAAR_DO_CANNY_PRUNING, cvSize(40, 40));
00178         
00179         mFaceDetector.data.foundFaces.clear();
00180         
00181         //if(faces->total) {
00182          //std::cout << "FOUND A FACE!" << flush;
00183         //}
00184         
00185         mFaceDetector.data.foundFaces.clear();
00186 
00187         //if(faces->total > 0){
00188         g_logdebug << "Found "<<faces->total<< " faces."<<endl;
00189         //xs  }
00190         for( int i = 0; i < (faces ? faces->total : 0); i++ ){
00191                CvRect* r = (CvRect*)cvGetSeqElem( faces, i );
00192                FaceLocation f;
00193                f.width = r->width;
00194                f.height = r->height;
00195                f.origin.x(r->x);
00196                f.origin.y(r->y);
00197                f.centroid.x(r->x + r->width / 2.0);
00198                f.centroid.y(r->y + r->height / 2.0);
00199                mFaceDetector.data.foundFaces.push_back(f);
00200                g_logdebug << "Just added a face." << endl;
00201                
00202                pt1.x = r->x;
00203                pt2.x = (r->x+r->width);
00204                pt1.y = r->y;
00205                pt2.y = (r->y+r->height);
00206                // cvRectangle( temp, pt1, pt2, CV_RGB(255,0,0), 3, 8, 0 );
00207         }
00208         mFaceDetector.publishData();
00209         g_logdebug << "Just published some faces" << endl;
00210         
00211         //      sprintf(buff,"/usr/local/share/role/data/pict%05d.jpg",count);
00212         //cvSaveImage(buff, temp);
00213         ++count;
00214 
00215         //printf("(%i,%i)\n", mImage.second->width, mImage.second->height);
00216         
00217         //cvShowImage("Name of Window", mImage.second);
00218 
00219 }
00220 
00221 void FaceOperator::quitOperator() {
00222         
00223        //       mPtu.disconnect();
00224        //mRangeFinder.disconnect();
00225         
00226         mEnd.now();
00227         double seconds = mEnd.getSeconds() - mBegin.getSeconds();
00228 
00229   g_loginfo << "Frames per second: " << (mFrames / seconds) << endl;
00230 }
00231 
00232 void FaceOperator::GetLaserData(double *data) {
00233   bool gotdata = false;
00234                 //printf("LOOP\n");
00235                 while(mRangeFinder.newInfo()) {
00236                         mRangeFinder.getNextInfo();
00237                 }
00238                 while(mRangeFinder.newData()) {
00239                         mRangeFinder.getNextData();
00240                 }
00241                 if(mRangeFinder.data.ranges.size()) {
00242                 for(int i = 0; i < 181; i++) {
00243                                 data[i] = mRangeFinder.data.ranges[i];
00244           }
00245         }
00246 }
00247 
00248 void FaceOperator::GetPTUData(double *pPan, double *pTilt) {
00249   bool gotdata = false;
00250                 while(mPtu.newInfo()) {
00251                 mPtu.getNextInfo();  
00252                 gotdata = true;
00253                 }
00254         (*pPan) = mPtu.info.pan.getValue();
00255   (*pTilt) = mPtu.info.tilt.getValue();
00256 }
00257 void FaceOperator::GetClosedLaserData(double *pOut) {
00258   //We're assuming always 181 lasers here (!)
00259   
00260   double r = 0.3;
00261   PTUnit ptu("safeTomPTUserver");
00262   double data[181];
00263   GetLaserData(data);
00264   
00265   float angleMin = mRangeFinder.info.angle_min.getValue();
00266   float angleSep = mRangeFinder.info.theta_separation.getValue();
00267   
00268   
00269 
00270   for (int i = 0; i < 180; i++){
00271     double x = 9999999;
00272     int w = int(asin(r / data[i]) * 180 / 3.14159265358);     //FIXME: 90 is the biggest w will ever $                        float x = MAX_FLO
00273     //int w = 90;     //FIXME: 90 is the biggest w will ever $                        float x = MAX_FLOAT
00274     if(w == 0) {
00275       pOut[i] = data[i];
00276     }
00277     for (int j = 0; j < w; j++){
00278     
00279       float theta = j * 3.1415927 / 180.0;
00280       float xtemp;
00281       if (i+j >= 0 && i+j < 180){
00282         float l = data[i+j];
00283         xtemp = l * cos(theta) - sqrt( r*r - pow(l*sin(theta),2));
00284         if (xtemp < x) {
00285           x = xtemp;
00286         }
00287       }
00288       if (i-j >= 0 && i-j < 180){
00289         double l = data[i-j];
00290         xtemp = l * cos(-theta) - sqrt( r*r - pow(l*sin(-theta),2));
00291         if (xtemp < x){
00292           x = xtemp;
00293         }
00294       }
00295       pOut[i] = x;
00296     }
00297   } 
00298 }
00299 
00300 extern "C" {
00301        VisionOperator *FaceOperator_factory(std::string name) {
00302               return new FaceOperator(name);
00303        }
00304        
00305        class FaceOperatorProxy { 
00306        public:
00307               FaceOperatorProxy(){
00308                      operatorFactory["FaceOperator"] = FaceOperator_factory;
00309               }
00310        };
00311        
00312        FaceOperatorProxy p_Faceoperator;
00313 }
00314 
00315 

Generated on Thu Feb 1 15:31:52 2007 for WURDE by  doxygen 1.5.1