psycho-skin-indexing.C

Go to the documentation of this file.
00001 /*!@file AppPsycho/psycho-skin-indexing.C Psychophysics display of different skins for a gameboard */
00002 
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the //
00005 // University of Southern California (USC) and the iLab at USC.         //
00006 // See http://iLab.usc.edu for information about this project.          //
00007 // //////////////////////////////////////////////////////////////////// //
00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00010 // in Visual Environments, and Applications'' by Christof Koch and      //
00011 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00012 // pending; application number 09/912,225 filed July 23, 2001; see      //
00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00014 // //////////////////////////////////////////////////////////////////// //
00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00016 //                                                                      //
00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00018 // redistribute it and/or modify it under the terms of the GNU General  //
00019 // Public License as published by the Free Software Foundation; either  //
00020 // version 2 of the License, or (at your option) any later version.     //
00021 //                                                                      //
00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00025 // PURPOSE.  See the GNU General Public License for more details.       //
00026 //                                                                      //
00027 // You should have received a copy of the GNU General Public License    //
00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00030 // Boston, MA 02111-1307 USA.                                           //
00031 // //////////////////////////////////////////////////////////////////// //
00032 //
00033 // Primary maintainer for this file: Laurent Itti <itti@usc.edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/AppPsycho/psycho-skin-indexing.C $
00035 // $Id: psycho-skin-indexing.C 14376 2011-01-11 02:44:34Z pez $
00036 //
00037 
00038 #ifndef INVT_HAVE_LIBSDL_IMAGE
00039 
00040 #include <cstdio>
00041 int main()
00042 {
00043   fprintf(stderr, "The SDL_image library must be installed to use this program\n");
00044   return 1;
00045 }
00046 
00047 #else
00048 
00049 /*
00050 Attention: SDL_image is needed for linking
00051 
00052 */
00053 
00054 #include "Component/ModelManager.H"
00055 #include "Image/Image.H"
00056 #include "Psycho/PsychoDisplay.H"
00057 #include "Psycho/EyeTrackerConfigurator.H"
00058 #include "Psycho/EyeTracker.H"
00059 #include "Psycho/PsychoOpts.H"
00060 #include "Component/EventLog.H"
00061 #include "Component/ComponentOpts.H"
00062 #include "Raster/Raster.H"
00063 #include "Util/MathFunctions.H"
00064 #include "Util/Types.H"
00065 #include <iostream>
00066 #include <fstream>
00067 #include <SDL/SDL.h>
00068 #include <SDL/SDL_image.h>
00069 #include "psycho-skin-resize.h"
00070 #include <stdio.h>
00071 #include <stdlib.h>
00072 #include <map>
00073 #include <time.h>
00074 
00075 
00076 using namespace std;
00077 
00078 
00079 //The attributes of the screen
00080 const int SCREEN_WIDTH = 840;
00081 const int SCREEN_HEIGHT = 680;
00082 const int SCREEN_BPP = 32;
00083 const int NUMBER_OF_CLASSES = 6;
00084 const int MAX_CELLS = 400 ;
00085 const int IMAGE_WIDTH = 128 ;
00086 const string classes[NUMBER_OF_CLASSES]={"class1","class2","class3","class4","class5","class6"};
00087 SDL_Event event ;
00088 int delay = 15 ;
00089 bool programQuit = false ;
00090 map<string,map<string,SDL_Surface*> > skinsmap ;
00091 ModelManager manager("Psycho Skin Indexing");
00092 nub::soft_ref<PsychoDisplay> d(new PsychoDisplay(manager));
00093 
00094 //////////////////////////////////////////
00095 
00096 SDL_Surface *load_image( string filename )
00097 {
00098     //The image that's loaded
00099     SDL_Surface* loadedImage = NULL;
00100 
00101     //The optimized image that will be used
00102     SDL_Surface* optimizedImage = NULL;
00103 
00104     //Load the image
00105     loadedImage = IMG_Load( filename.c_str() );
00106 
00107     //If the image loaded
00108     if( loadedImage != NULL )
00109     {
00110         //Create an optimized image
00111         optimizedImage = SDL_DisplayFormat( loadedImage );
00112 
00113         //Free the old image
00114         SDL_FreeSurface( loadedImage );
00115 
00116         //If the image was optimized just fine
00117         if( optimizedImage != NULL )
00118         {
00119             //Map the color key
00120             Uint32 colorkey = SDL_MapRGB( optimizedImage->format, 0, 0xFF, 0xFF );
00121 
00122             //Set all pixels of color R 0, G 0xFF, B 0xFF to be transparent
00123             SDL_SetColorKey( optimizedImage, SDL_SRCCOLORKEY, colorkey );
00124         }
00125     }else{cout<<filename;}
00126 
00127     //Return the optimized image
00128     return optimizedImage;
00129 }
00130 ///////////////////////////////////
00131 
00132 SDL_Surface *getAFreshSurface(int w ,  int h){
00133 
00134         SDL_Surface *sur = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32,
00135                                    0x00000000, 0x00000000, 0x00000000, 0x00000000);
00136 
00137         return sur ;
00138 
00139 }
00140 
00141 ///////////////////////////////////
00142 
00143 
00144 void dumpSurface(SDL_Surface * surface){
00145 
00146  SDL_FreeSurface( surface );
00147 }
00148 
00149 /////////////////////////////////////////////
00150 
00151 void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination , SDL_Rect* clip = NULL)
00152 {
00153     //Make a temporary rectangle to hold the offsets
00154     SDL_Rect offset;
00155 
00156     //Give the offsets to the rectangle
00157     offset.x = x;
00158     offset.y = y;
00159 
00160     //Blit the surface
00161     SDL_BlitSurface( source, clip, destination, &offset );
00162 }
00163 
00164 
00165 void clean_up()
00166 {
00167 
00168     for( map<string,map<string,SDL_Surface*> >::iterator ii=skinsmap.begin(); ii!=skinsmap.end(); ++ii)
00169    {
00170            for(map<string,SDL_Surface*>::iterator jj=((*ii).second).begin() ; jj!= ((*ii).second).end() ; ++jj){
00171                     SDL_FreeSurface(jj->second);
00172            }
00173 
00174    }
00175 
00176     SDL_Quit();
00177 }
00178 /////////////////////////////////////
00179 void readTop(ifstream* inFile){
00180 //        tempSur = load_image("skin1/class1/ball.png");
00181         char ch[1000];
00182    while ((*inFile).getline(ch , 1000)){
00183                    string line = ch;
00184                 LINFO("top reader reads : '%s'", line.c_str());
00185                    if(line.compare("end top")==0) break;
00186                 string::size_type position = line.find("=");
00187                 string skinname = line.substr(0, position);
00188                 string path = line.substr(position+1);
00189                 map<string,SDL_Surface*> themap;
00190 
00191                 for(int i = 0 ; i < NUMBER_OF_CLASSES ; i++){
00192                         string filepath ;
00193                         filepath += path+"/"+classes[i]+"/ball.png" ;
00194 
00195                           themap[classes[i]]= load_image(filepath) ;
00196                 }
00197                 skinsmap[skinname] = themap;
00198 
00199         }
00200 
00201 }
00202 
00203 void showStaticSlide(string *slideMap,string skinName , int col , int row , int px , int py , float rf){
00204 
00205 d->clearScreen();
00206         map<string,SDL_Surface*> resizedSurfacesMap;
00207                   map<string,int> clipNumMap;
00208                   SDL_Rect theClip ;
00209                   theClip.x = 0 ;
00210                 theClip.y = 0 ;
00211                 theClip.w = (int)(rf* IMAGE_WIDTH) ;
00212                 theClip.h = (int)(rf* IMAGE_WIDTH) ;
00213                   //bool slideQuit = false ;
00214                 SDL_Surface* nbg = getAFreshSurface((int)(IMAGE_WIDTH*col*rf), (int)(IMAGE_WIDTH*row*rf));
00215 
00216 
00217                   //this block discovers how many clips are there in a sprite and put the number in a  map
00218                   //moreover it will construct required clips and put them in a map too
00219                   for(map<string,SDL_Surface*>::iterator jj=(skinsmap[skinName]).begin() ; jj!= (skinsmap[skinName]).end() ; ++jj )
00220                   {
00221                           int numOfImages = ((jj->second)->h)/IMAGE_WIDTH ;
00222                     clipNumMap[jj->first] = numOfImages ;
00223                     //cout<<"Number of clips : "<<(jj->second)->h<<endl;
00224 
00225                  }
00226 
00227                 //this block makes a map from name of classes to the resized surface of each class
00228                 for(map<string,SDL_Surface*>::iterator jj=(skinsmap[skinName]).begin() ; jj!= (skinsmap[skinName]).end() ; ++jj )
00229                   {
00230                           SDL_Surface *tmpSurface = getAFreshSurface(IMAGE_WIDTH,IMAGE_WIDTH);
00231                           *tmpSurface = *(jj->second);
00232                           tmpSurface = SDL_Resize(tmpSurface , rf , 3 );
00233                           resizedSurfacesMap[jj->first] = tmpSurface;
00234 
00235                  }
00236 
00237 
00238 
00239 
00240                  for(map<string,SDL_Surface*>::iterator jj=(skinsmap[skinName]).begin() ; jj!= (skinsmap[skinName]).end() ; ++jj){
00241                                 string className = jj->first;
00242 
00243 
00244 
00245                                    for(int i = 0 ; i < col*row ; i++){
00246 
00247                                            if(slideMap[i].compare( className )==0){
00248                                                    int clipY = (int)((rand()% clipNumMap[className])*IMAGE_WIDTH*rf);
00249                                                    theClip.y = clipY ;
00250                                                 apply_surface((int)((i%col)*IMAGE_WIDTH*rf),(int)((i/col)*IMAGE_WIDTH*rf),resizedSurfacesMap[className],nbg,&theClip) ;
00251                                            }
00252                                    }
00253 
00254 
00255 
00256                            }
00257                 SDL_Rect offset;
00258 
00259                     //Give the offsets to the rectangle
00260                     offset.x = px;
00261                     offset.y = py;
00262                 d->displaySDLSurfacePatch(nbg , &offset,NULL , -2,false, true);
00263                       d->waitNextRequestedVsync(false, true);
00264                 d->waitForKey();
00265 
00266 
00267                 for(map<string,SDL_Surface*>::iterator jj=(skinsmap[skinName]).begin() ; jj!= (skinsmap[skinName]).end() ; ++jj )
00268                                                                   {
00269                                                                     dumpSurface(resizedSurfacesMap[jj->first]);
00270                                                                  }
00271                 dumpSurface(nbg) ;
00272 
00273 }
00274 
00275 
00276 void showDynamicSlide(string *slideMap,string skinName , int col , int row , int px , int py , float rf){
00277 
00278                   map<string,SDL_Surface*> resizedSurfacesMap;
00279                   map<string,int> clipNumMap;
00280                 int phase[col*row] ;
00281                   SDL_Rect theClip ;
00282                   theClip.x = 0 ;
00283                 theClip.y = 0 ;
00284                 theClip.w = (int)(rf* IMAGE_WIDTH) ;
00285                 theClip.h = (int)(rf* IMAGE_WIDTH) ;
00286                   bool slideQuit = false ;
00287                   SDL_Surface *nbg = getAFreshSurface((int)(IMAGE_WIDTH*col*rf), (int)(IMAGE_WIDTH*row*rf));
00288 
00289                   //this block discovers how many clips are there in a sprite and put the number in a  map
00290                   //moreover it will construct required clips and put then in a map too
00291                   for(map<string,SDL_Surface*>::iterator jj=(skinsmap[skinName]).begin() ; jj!= (skinsmap[skinName]).end() ; ++jj )
00292                   {
00293                           int numOfImages = ((jj->second)->h)/IMAGE_WIDTH ;
00294                             clipNumMap[jj->first] = numOfImages ;
00295 
00296                  }
00297 
00298                 //this block makes a map from name of classes to the resized surface of each class
00299                 for(map<string,SDL_Surface*>::iterator jj=(skinsmap[skinName]).begin() ; jj!= (skinsmap[skinName]).end() ; ++jj )
00300                   {
00301                           SDL_Surface* tmpSurface = getAFreshSurface(IMAGE_WIDTH,IMAGE_WIDTH );
00302                           *tmpSurface = *(jj->second);
00303                           tmpSurface = SDL_Resize(tmpSurface , rf , 3 );
00304                           resizedSurfacesMap[jj->first] = tmpSurface;
00305 
00306                  }
00307 
00308                 for(int i = 0 ; i < col*row ; i++){
00309 
00310                         phase[i] = rand()% clipNumMap[*(slideMap+i)];
00311                 }
00312 
00313                 int l = 0 ;
00314 
00315                  while( slideQuit == false ) {
00316 
00317                         while(SDL_PollEvent( &event )){
00318 
00319                                 if(event.type == SDL_KEYDOWN){
00320                                         if( event.key.keysym.sym == SDLK_SPACE )
00321                                     {
00322                                         slideQuit = true ;
00323                             }
00324                             if( event.key.keysym.sym == SDLK_ESCAPE )
00325                                     {
00326                                         slideQuit = true ;
00327                                         programQuit = true ;
00328                             }
00329                             if(event.key.keysym.sym == SDLK_UP){
00330                                                 if (delay > 2 )delay -= 2 ;
00331                                         }
00332 
00333                                         if(event.key.keysym.sym == SDLK_DOWN){
00334                                                 if (delay < 500 )delay += 2 ;
00335                                         }
00336 
00337                                 }
00338 
00339 
00340                             if( event.type == SDL_QUIT || event.key.keysym.sym == SDLK_ESCAPE )
00341                             {
00342                                 programQuit = true;
00343                                 slideQuit = true ;
00344                             }
00345 
00346 
00347                         }
00348 
00349                         for(map<string,SDL_Surface*>::iterator jj=(skinsmap[skinName]).begin() ; jj!= (skinsmap[skinName]).end() ; ++jj){
00350                                 string className = jj->first;
00351 
00352                                    for(int i = 0 ; i < col*row ; i++){
00353 
00354                                         int clipY = (int)(((l+phase[i]) % clipNumMap[className])*IMAGE_WIDTH*rf);
00355                                         theClip.y = clipY ;
00356 
00357                                            if(slideMap[i].compare( className )==0){
00358                                                    apply_surface((int)((i%col)*IMAGE_WIDTH*rf),(int)((i/col)*IMAGE_WIDTH*rf),resizedSurfacesMap[className],nbg,&theClip);
00359                                            }
00360                                    }
00361 
00362 
00363                            }
00364 
00365                 SDL_Rect offset;
00366 
00367                     //Give the offsets to the rectangle
00368                     offset.x = px;
00369                     offset.y = py;
00370                 d->displaySDLSurfacePatch(nbg , &offset ,NULL,  -2,true, true);
00371 
00372                         l++ ;
00373                         SDL_Delay( delay );
00374                 }
00375 
00376 
00377                 for(map<string,SDL_Surface*>::iterator jj=(skinsmap[skinName]).begin() ; jj!= (skinsmap[skinName]).end() ; ++jj )
00378                                                                   {
00379                                                                     dumpSurface(resizedSurfacesMap[jj->first]);
00380                                                                  }
00381                 dumpSurface(nbg) ;
00382 
00383 }
00384 
00385 
00386 /*
00387  * Reads part of profile starting with slide till end of the part indicated by end slide
00388  * */
00389 void readSlide(ifstream* inFile){
00390         char ch[1000];
00391         string skinName;
00392         float resizefactor = 1.0f;
00393         int px = 0, py = 0, rows = 0, columns = 0;
00394         string slideMap[MAX_CELLS];
00395         bool isDynamic = false ;
00396         d->clearScreen() ;
00397         d->displayRedDotFixationBlink();
00398     d->pushEvent(std::string("===== Reading Slide ====="));
00399    while ((*inFile).getline(ch , 1000)){
00400            string line = ch;
00401         LINFO("slide reader reads : '%s'...", line.c_str());
00402            d->pushEvent(line.c_str());
00403            if(line.substr(0,4).compare("skin")==0){
00404                    string::size_type position = line.find("=");
00405                 skinName = line.substr(position+1);
00406 
00407            }
00408         if(line.substr(0,2).compare("rf")==0){
00409                    string::size_type position = line.find("=");
00410                    char rf[10] ;
00411                    strcpy(rf,line.substr(position+1).c_str());
00412                 resizefactor = atof(rf);
00413            }
00414            if(line.substr(0,2).compare("px")==0){
00415                    string::size_type position = line.find("=");
00416                    char rf[10] ;
00417                    strcpy(rf,line.substr(position+1).c_str());
00418                 px = atoi(rf);
00419            }
00420         if(line.substr(0,2).compare("py")==0){
00421                    string::size_type position = line.find("=");
00422                    char rf[10] ;
00423                    strcpy(rf,line.substr(position+1).c_str());
00424                 py = atoi(rf);
00425            }
00426            if(line.substr(0,2).compare("rs")==0){
00427                    string::size_type position = line.find("=");
00428                    char rf[10] ;
00429                    strcpy(rf,line.substr(position+1).c_str());
00430                 rows = atoi(rf);
00431            }
00432            if(line.substr(0,2).compare("cs")==0){
00433                    string::size_type position = line.find("=");
00434                    char rf[10] ;
00435                    strcpy(rf,line.substr(position+1).c_str());
00436                 columns = atoi(rf);
00437            }
00438 
00439            if(line.substr(0,6).compare("static")==0){
00440                    isDynamic = false ;
00441            }
00442 
00443            if(line.substr(0,7).compare("dynamic")==0){
00444                    isDynamic = true ;
00445            }
00446 
00447            if(line.substr(0,3).compare("map")==0){
00448                    int p = 3 ;
00449                    string cs = "class";
00450                    for (int i =0 ; i < rows*columns ; i++){
00451                            int pos = p+1 +i*2 ;
00452                            string cn = line.substr(pos ,1);
00453                            slideMap[i] = cs+cn;
00454                    }
00455                    if(isDynamic == true){
00456 
00457                            showDynamicSlide(&slideMap[0],skinName,columns,rows,px,py,resizefactor) ;
00458 
00459                    }else{
00460                            showStaticSlide(&slideMap[0],skinName,columns,rows,px,py,resizefactor) ;
00461                    }
00462 
00463 
00464            }
00465 
00466 
00467 
00468            if(line.compare("end slide")==0) break;
00469 
00470 
00471         }
00472 
00473 }
00474 
00475 int readprofile(const char* filename){
00476         ifstream inFile(filename, ios::in);
00477         if (! inFile)
00478    {
00479       return -1;
00480    }
00481 
00482    char ch[1000];
00483    while (inFile.getline(ch , 500)){
00484            string line = ch;
00485         LINFO("profile reader reads : '%s'...", line.c_str());
00486            if(line.compare("top")==0 ) readTop(&inFile);
00487 
00488            if(line.compare("slide")==0) readSlide(&inFile);
00489            if(programQuit == true) break ;
00490         }
00491 
00492         return 0 ;
00493 }
00494 
00495 
00496 extern "C" int main( int argc, char* args[] ){
00497         MYLOGVERB = LOG_INFO;
00498 
00499           manager.addSubComponent(d);
00500           nub::soft_ref<EventLog> el(new EventLog(manager));
00501           manager.addSubComponent(el);
00502 
00503           manager.setOptionValString(&OPT_EventLogFileName, "psychodata.psy");
00504 
00505           d->setEventLog(el);
00506 
00507           manager.start();
00508 
00509           // let's display an ISCAN calibration grid:
00510           d->clearScreen();
00511           d->displayISCANcalib();
00512           d->waitForKey();
00513         // let's do an eye tracker calibration:
00514           d->displayText("<SPACE> to calibrate; other key to skip");
00515           //int c = 
00516              d->waitForKey();
00517          // if (c == ' ') d->displayEyeTrackerCalibration();
00518 
00519           d->clearScreen();
00520           d->displayText("<SPACE> for random play; other key for ordered");
00521           //c = 
00522             d->waitForKey();
00523 
00524         d->displayFixation();
00525 
00526               // ready to go whenever the user is ready:
00527               d->waitForKey();
00528               d->waitNextRequestedVsync(false, true);
00529 
00530 
00531         string filename;
00532         if(argc == 2) {
00533                 if(readprofile(args[1])< 0) return -1;
00534         }else{
00535                 cerr << "usage : " << args[0] << " file_name.exp \n";
00536                 return -1 ;
00537         }
00538 
00539         clean_up();
00540         manager.stop() ;
00541         return 0;
00542 }
00543 
00544 #endif // INVT_HAVE_LIBSDL_IMAGE
Generated on Sun May 8 08:04:12 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3