00001 /*!@file AppPsycho/psycho-skin-bsindexing.c Psychophysics main application for indexing experiment */ 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 // 00035 // 2008-02-20 16:14:27Z nnoori $ 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 00051 /* 00052 Attention: SDL_image is needed for linking 00053 00054 */ 00055 00056 #include "Component/ModelManager.H" 00057 #include "Image/Image.H" 00058 #include "Psycho/PsychoDisplay.H" 00059 #include "Psycho/EyeTrackerConfigurator.H" 00060 #include "Psycho/EyeTracker.H" 00061 #include "Psycho/PsychoOpts.H" 00062 #include "Component/EventLog.H" 00063 #include "Component/ComponentOpts.H" 00064 #include "Raster/Raster.H" 00065 #include "Util/MathFunctions.H" 00066 #include "Util/Types.H" 00067 #include <iostream> 00068 #include <fstream> 00069 #include <SDL/SDL.h> 00070 #include <SDL/SDL_image.h> 00071 #include "psycho-skin-resize.h" 00072 #include <stdio.h> 00073 #include <stdlib.h> 00074 #include <map> 00075 #include <time.h> 00076 #include "psycho-skin-mapgenerator.h" 00077 #include <sstream> 00078 00079 00080 using namespace std; 00081 00082 ModelManager manager("Psycho Skin"); 00083 nub::soft_ref<PsychoDisplay> d(new PsychoDisplay(manager)); 00084 bool programQuit = false ; 00085 map<string,string> skinFileMap ; 00086 const int NUMBER_OF_CLASSES = 6; 00087 const int IMAGE_WIDTH = 128 ; 00088 const string classes[NUMBER_OF_CLASSES]={"class1","class2","class3","class4","class5","class6"}; 00089 int targetExposure ; 00090 int emptyTime ; 00091 ////////////////////////////////////////// 00092 int emergencyExit(){ 00093 time_t rawtime; 00094 time ( &rawtime ); 00095 LINFO("...emergencyExit called @%s .", ctime( &rawtime )); 00096 d->pushEvent(std::string("experiment ended at ")+ ctime( &rawtime ) ); 00097 manager.stop(); 00098 return -1; 00099 } 00100 00101 00102 ////////////////////////////////////////// 00103 // Here we collect subjects response 00104 uint getResponse(){ 00105 00106 int c = -1; 00107 int conf = -1 ; 00108 int quit = -1 ; 00109 do{ 00110 d-> displayText("Press 1 for 'yes', 2 for 'no'"); 00111 c = -1 ; 00112 while( c!=49 && c!=50 ){ 00113 c = d->waitForKey(); 00114 } 00115 if( c == 49){ 00116 d-> displayText("You chose 'yes' press space-bar to confirm"); 00117 } else { 00118 d-> displayText("You chose 'no' press space-bar to confirm"); 00119 } 00120 conf = d-> waitForKey() ; 00121 if( conf == 127){ 00122 quit = d-> waitForKey() ; 00123 if( quit == 127 ){ 00124 emergencyExit() ; 00125 } 00126 } 00127 }while(conf!=32) ; 00128 00129 if( c == 49 ){ 00130 d->pushEvent("positive identification confirmed"); 00131 return 1 ; 00132 } else { 00133 d->pushEvent("negative identification confirmed"); 00134 return 0 ; 00135 } 00136 } 00137 00138 ///////////////////////////////////////////// 00139 SDL_Surface *load_image( string filename ) 00140 { 00141 //The image that's loaded 00142 SDL_Surface* loadedImage = NULL; 00143 00144 //The optimized image that will be used 00145 SDL_Surface* optimizedImage = NULL; 00146 00147 //Load the image 00148 loadedImage = IMG_Load( filename.c_str() ); 00149 00150 //If the image loaded 00151 if( loadedImage != NULL ) 00152 { 00153 //Create an optimized image 00154 optimizedImage = SDL_DisplayFormat( loadedImage ); 00155 00156 //Free the old image 00157 SDL_FreeSurface( loadedImage ); 00158 00159 //If the image was optimized just fine 00160 if( optimizedImage != NULL ) 00161 { 00162 //Map the color key 00163 Uint32 colorkey = SDL_MapRGB( optimizedImage->format, 0, 0xFF, 0xFF ); 00164 00165 //Set all pixels of color R 0, G 0xFF, B 0xFF to be transparent 00166 SDL_SetColorKey( optimizedImage, SDL_SRCCOLORKEY, colorkey ); 00167 } 00168 }else{ 00169 emergencyExit() ; 00170 } 00171 00172 //Return the optimized image 00173 return optimizedImage; 00174 } 00175 /////////////////////////////////// 00176 00177 SDL_Surface *getAFreshSurface(int w , int h){ 00178 00179 SDL_Surface *sur = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, 00180 0x00000000, 0x00000000, 0x00000000, 0x00000000); 00181 00182 return sur ; 00183 00184 } 00185 //////////////////////////////////// 00186 00187 template <class T> 00188 string stringify(T &i) 00189 { 00190 ostringstream o ; 00191 o << i ; 00192 return o.str(); 00193 } 00194 00195 /////////////////////////////////// 00196 void dumpSurface(SDL_Surface& surface){ 00197 SDL_FreeSurface( &surface ); 00198 } 00199 ///////////////////////////////////////////// 00200 void apply_surface( int x, int y, SDL_Surface& source, SDL_Surface& destination , SDL_Rect& clip ) 00201 { 00202 //Make a temporary rectangle to hold the offsets 00203 SDL_Rect offset; 00204 00205 //Give the offsets to the rectangle 00206 offset.x = x; 00207 offset.y = y; 00208 00209 //Blit the surface 00210 SDL_BlitSurface( &source, &clip, &destination, &offset ); 00211 } 00212 ///////////////////////////////////////////// 00213 int readTop(ifstream& inFile){ 00214 char ch[1000] ; 00215 while( inFile.getline(ch , 1000) ){ 00216 string line = ch ; 00217 LINFO("reads : %s" , line.c_str()) ; 00218 if( line.compare("end_top") == 0 ) break; 00219 if( line.substr(0,4).compare("skin")==0 ){ 00220 string::size_type position = line.find("=") ; 00221 string skinName = line.substr(0,position) ; 00222 string path = line.substr(position+1) ; 00223 skinFileMap[skinName] = path ; 00224 } 00225 if( line.substr(0,15).compare("target_exposure")==0 ){ 00226 string::size_type position = line.find("="); 00227 char rf[10] ; 00228 strcpy(rf,line.substr(position+1).c_str()); 00229 targetExposure = atoi(rf); 00230 d->pushEvent(line.c_str()); 00231 } 00232 if( line.substr(0,10).compare("empty_time")==0 ){ 00233 string::size_type position = line.find("=") ; 00234 char rf[10] ; 00235 strcpy(rf,line.substr(position+1).c_str()); 00236 emptyTime = atoi(rf); 00237 } 00238 00239 } 00240 return 0 ; 00241 } 00242 ///////////////////////////////////////////// 00243 void showStaticTarget(Matrix& pattern , SDL_Surface* classSkin){ 00244 int pw = classSkin->w; 00245 int ph = classSkin->h ; 00246 SDL_Rect theClip ; 00247 theClip.x = 0 ; 00248 theClip.y = 0 ; 00249 theClip.w = pw ; 00250 theClip.h = pw ; 00251 SDL_Surface* blankSurface = getAFreshSurface(pw*pattern.getNumOfColumns(),pw*pattern.getNumOfRows()); 00252 int nv = ph / pw ; 00253 for( int r = 0 ; r < pattern.getNumOfRows() ; r++){ 00254 for( int c = 0 ; c < pattern.getNumOfColumns() ; c++){ 00255 if( pattern.get(r,c)== 1 ){ 00256 theClip.y = (rand()%nv)*pw ; 00257 apply_surface(c*pw,r*pw, *classSkin , *blankSurface ,theClip) ; 00258 } 00259 } 00260 } 00261 d->clearScreen(); 00262 SDL_Rect offset; 00263 00264 //Give the offsets to the rectangle 00265 offset.x = (d->getWidth() - blankSurface->w) /2; 00266 offset.y = (d-> getHeight() - blankSurface->h) /2; 00267 d->displaySDLSurfacePatch(blankSurface , &offset,NULL , -2,false, true); 00268 d->waitFrames(targetExposure); 00269 SDL_FreeSurface(blankSurface); 00270 theClip.~SDL_Rect(); 00271 } 00272 ///////////////////////////////////////// 00273 void showDynamicTarget(Matrix& pattern , SDL_Surface* classSkin){ 00274 int pw = classSkin->w; 00275 int ph = classSkin->h ; 00276 SDL_Rect theClip ; 00277 theClip.x = 0 ; 00278 theClip.y = 0 ; 00279 theClip.w = pw ; 00280 theClip.h = pw ; 00281 SDL_Surface* blankSurface = getAFreshSurface(pw*pattern.getNumOfColumns(),pw*pattern.getNumOfRows()); 00282 int nv = ph / pw ; 00283 Matrix* phaseMatrix = getARandomMap(pattern.getNumOfRows(),pattern.getNumOfColumns(),nv) ; 00284 int counter = 0 ; 00285 while(counter < targetExposure ){ 00286 for( int r = 0 ; r < pattern.getNumOfRows() ; r++){ 00287 for( int c = 0 ; c < pattern.getNumOfColumns() ; c++){ 00288 if( pattern.get(r,c)== 1 ){ 00289 theClip.y = ((counter+phaseMatrix->get(r,c)) %nv)*pw ; 00290 apply_surface(c*pw,r*pw, *classSkin , *blankSurface ,theClip) ; 00291 } 00292 } 00293 } 00294 00295 00296 SDL_Rect offset; 00297 00298 //Give the offsets to the rectangle 00299 offset.x = (d->getWidth() - blankSurface->w) /2; 00300 offset.y = (d-> getHeight() - blankSurface->h) /2; 00301 d->displaySDLSurfacePatch(blankSurface , &offset,NULL , -2,true, true); 00302 counter++; 00303 } 00304 00305 SDL_FreeSurface(blankSurface); 00306 phaseMatrix->~Matrix(); 00307 theClip.~SDL_Rect(); 00308 } 00309 ///////////////////////////////////////// 00310 void showDynamicSlide(Matrix& theMap , map<string,SDL_Surface*>& cmap, int sT ){ 00311 int cs = theMap.getNumOfColumns(); 00312 int rs = theMap.getNumOfRows() ; 00313 map<string , int> clipNumMap; 00314 int imageWidth = -1 ; 00315 int imageHeigth = -1 ; 00316 int pw = 0 ; 00317 int maxForPhase = 0; 00318 00319 for( map<string,SDL_Surface*>:: iterator it = cmap.begin() ; it != cmap.end() ; ++it ){ 00320 string clName = it->first ; 00321 SDL_Surface* surf = it->second; 00322 int numOfClips = (surf->h) / (surf->w); 00323 clipNumMap[clName] = numOfClips; 00324 maxForPhase = max(maxForPhase,numOfClips); 00325 if(imageWidth == -1){ 00326 pw = surf->w ; 00327 imageWidth = theMap.getNumOfColumns()*pw ; 00328 imageHeigth = theMap.getNumOfRows()*pw ; 00329 } 00330 00331 } 00332 Matrix* phaseMatrix = getARandomMap(rs,cs,maxForPhase) ; 00333 00334 SDL_Rect* theClip = new SDL_Rect(); 00335 theClip->x = 0 ; 00336 theClip->y = 0 ; 00337 theClip->w = pw ; 00338 theClip->h = pw ; 00339 // 00340 SDL_Surface* nbg = getAFreshSurface(imageWidth,imageHeigth); 00341 int counter = 0 ; 00342 string cname("") ; 00343 while( counter < sT ){ 00344 for( int r = 0 ; r < rs ; r++){ 00345 for( int c = 0 ; c < cs ; c++){ 00346 switch( theMap.get(r,c) ){ 00347 case 1 : cname = "class1" ;break ; 00348 case 2 : cname = "class2" ; break ; 00349 case 3 : cname = "class3" ; break ; 00350 case 4 : cname = "class4" ; break ; 00351 case 5 : cname = "class5" ; break ; 00352 case 6 : cname = "class6" ; break ; 00353 } 00354 SDL_Surface* csurf = cmap[cname] ; 00355 int y = ( (counter+phaseMatrix->get(r,c)) % clipNumMap[cname])*pw; 00356 theClip->y = y ; 00357 apply_surface(c*pw,r*pw, *csurf , *nbg ,*theClip) ; 00358 } 00359 } 00360 //d->clearScreen(); 00361 SDL_Rect offset; 00362 offset.x = (d->getWidth() - nbg->w) /2; 00363 offset.y = (d-> getHeight() - nbg->h) /2; 00364 d->displaySDLSurfacePatch(nbg , &offset,NULL , -2,true, true); 00365 counter++ ; 00366 } 00367 00368 phaseMatrix->~Matrix(); 00369 theClip->~SDL_Rect(); 00370 SDL_FreeSurface(nbg); 00371 00372 } 00373 00374 ///////////////////////////////////////// 00375 void showStaticSlide(Matrix& theMap , map<string,SDL_Surface*>& cmap, int sT ){ 00376 d->pushEvent("exposure time will be "+stringify(sT)); 00377 int cs = theMap.getNumOfColumns(); 00378 int rs = theMap.getNumOfRows() ; 00379 map<string , int> clipNumMap; 00380 int imageWidth = -1 ; 00381 int imageHeigth = -1 ; 00382 int pw = 0 ; 00383 00384 for( map<string,SDL_Surface*>:: iterator it = cmap.begin() ; it != cmap.end() ; ++it ){ 00385 string clName = it->first ; 00386 SDL_Surface* surf = it->second; 00387 int numOfClips = (surf->h) / (surf->w); 00388 clipNumMap[clName] = numOfClips; 00389 if(imageWidth == -1){ 00390 pw = surf->w ; 00391 imageWidth = theMap.getNumOfColumns()*pw ; 00392 imageHeigth = theMap.getNumOfRows()*pw ; 00393 00394 } 00395 00396 } 00397 SDL_Rect* theClip = new SDL_Rect(); 00398 theClip->x = 0 ; 00399 theClip->y = 0 ; 00400 theClip->w = pw ; 00401 theClip->h = pw ; 00402 // 00403 SDL_Surface* nbg = getAFreshSurface(imageWidth,imageHeigth); 00404 for( int r = 0 ; r < rs ; r++){ 00405 for( int c = 0 ; c < cs ; c++){ 00406 const int ti = theMap.get(r,c); 00407 string cname = "class"+stringify(ti); 00408 SDL_Surface* csurf = cmap[cname] ; 00409 int y = (rand() % clipNumMap[cname])*pw; 00410 theClip->y = y ; 00411 apply_surface(c*pw,r*pw, *csurf , *nbg ,*theClip) ; 00412 } 00413 } 00414 d->clearScreen(); 00415 SDL_Rect offset; 00416 offset.x = (d->getWidth() - nbg->w) /2; 00417 offset.y = (d-> getHeight() - nbg->h) /2; 00418 d->clearScreen(); 00419 d->displaySDLSurfacePatch(nbg , &offset,NULL , -2,false, true); 00420 d->waitFrames(sT); 00421 SDL_FreeSurface(nbg); 00422 theClip->~SDL_Rect(); 00423 } 00424 ///////////////////////////////////////////// 00425 void doStaticTraining( map<string,SDL_Surface*>& cmap,vector<string>& messages){ 00426 d->pushEvent("training starts") ; 00427 d->displayText("Training Time! Press any key to start"); 00428 d->showCursor(true); 00429 d->waitForKey() ; 00430 ////// 00431 for( uint i = 0 ; i< messages.size() ; i++){ 00432 d->displayText(messages[i]); 00433 d->pushEvent("displayed training message : " + messages[i]); 00434 d->waitFrames(300); 00435 } 00436 00437 ///// 00438 d->pushEvent("training ends"); 00439 //d->pushEvent("Congradulations! You are ready for the real test"); 00440 d->waitFrames(45); 00441 d->displayText("Press any key to start!") ; 00442 d->waitForKey(); 00443 //d->showCursor(false); 00444 } 00445 00446 void doDynamicTraining( map<string,SDL_Surface*>& cmap,vector<string>& messages){ 00447 d->pushEvent("training starts") ; 00448 d->displayText("Training Time! Press any key to start"); 00449 d->showCursor(true); 00450 d->waitForKey() ; 00451 ////// 00452 for( uint i = 0 ; i< messages.size() ; i++){ 00453 d->pushEvent(messages[i]); 00454 } 00455 00456 ///// 00457 d->pushEvent("training ends"); 00458 //d->pushEvent("Congradulations! You are ready for the real test"); 00459 d->waitFrames(45); 00460 d->displayText("Press any key to start!") ; 00461 d->waitForKey(); 00462 d->showCursor(false); 00463 } 00464 ///////////////////////////////////////////// 00465 int readBlock(ifstream& inFile){ 00466 string block_name("") ; 00467 string pattern("") ; 00468 string skin_name("") ; 00469 int px = 0 ; 00470 int py = 0 ; 00471 int rows = 0 ; 00472 int columns = 0 ; 00473 float rf = 1.0f ; 00474 float prb = 0.5f ; 00475 int block_size = 20 ; 00476 int ie = 60 ; 00477 int skip_by = 100 ; 00478 bool staticFlag = true ; 00479 char ch[1000]; 00480 float maxSen = 0.0f; 00481 float maxAcc = 0.0f; 00482 bool trainingFlag = false ; 00483 string trainingMessage("") ; 00484 vector<string>* messages = new vector<string>() ; 00485 vector<string>* exclusionList = new vector<string>(); 00486 00487 /*let's read attributes of the block*/ 00488 while( inFile.getline(ch , 1000) ){ 00489 string line = ch ; 00490 LINFO("reads : %s" , line.c_str()) ; 00491 00492 if(line.compare("dynamic")==0) { 00493 staticFlag = false ; 00494 } 00495 if(line.compare("end_block")==0) { 00496 d -> pushEvent("ended reading block "+ block_name); 00497 break ; 00498 } 00499 if( line.substr(0,10).compare("block_name") == 0 ){ 00500 string::size_type position = line.find("=") ; 00501 block_name = line.substr(position+1) ; 00502 d -> pushEvent("started reading block "+block_name) ; 00503 } 00504 00505 if( line.substr(0,14).compare("target_pattern") == 0 ){ 00506 string::size_type position = line.find("=") ; 00507 pattern = line.substr(position+1) ; 00508 d -> pushEvent("target pattern "+pattern) ; 00509 } 00510 00511 if( line.substr(0,16).compare("excluded_pattern") == 0 ){ 00512 string::size_type position = line.find("=") ; 00513 string exPattern = line.substr(position+1); 00514 exclusionList->push_back(exPattern ) ; 00515 d -> pushEvent("excluded pattern "+exPattern) ; 00516 } 00517 00518 if( line.substr(0,4).compare("skin") == 0 ){ 00519 string::size_type position = line.find("=") ; 00520 skin_name = line.substr(position+1) ; 00521 } 00522 00523 if(line.substr(0,2).compare("rf")==0){ 00524 string::size_type position = line.find("="); 00525 char x[10] ; 00526 strcpy(x,line.substr(position+1).c_str()); 00527 rf = atof(x); 00528 } 00529 if(line.substr(0,11).compare("probability")==0){ 00530 string::size_type position = line.find("="); 00531 char rf[10] ; 00532 strcpy(rf,line.substr(position+1).c_str()); 00533 prb = atof(rf); 00534 } 00535 if(line.substr(0,2).compare("px")==0){ 00536 string::size_type position = line.find("="); 00537 char rf[10] ; 00538 strcpy(rf,line.substr(position+1).c_str()); 00539 px = atoi(rf); 00540 } 00541 if(line.substr(0,2).compare("py")==0){ 00542 string::size_type position = line.find("="); 00543 char rf[10] ; 00544 strcpy(rf,line.substr(position+1).c_str()); 00545 py = atoi(rf); 00546 } 00547 if(line.substr(0,2).compare("rs")==0){ 00548 string::size_type position = line.find("="); 00549 char rf[10] ; 00550 strcpy(rf,line.substr(position+1).c_str()); 00551 rows = atoi(rf); 00552 } 00553 if(line.substr(0,2).compare("cs")==0){ 00554 string::size_type position = line.find("="); 00555 char rf[10] ; 00556 strcpy(rf,line.substr(position+1).c_str()); 00557 columns = atoi(rf); 00558 } 00559 if(line.substr(0,16).compare("initial_exposure")==0){ 00560 string::size_type position = line.find("="); 00561 char rf[10] ; 00562 strcpy(rf,line.substr(position+1).c_str()); 00563 ie = atoi(rf); 00564 } 00565 if(line.substr(0,8).compare("skip_exp")==0){ 00566 string::size_type position = line.find("="); 00567 char rf[10] ; 00568 strcpy(rf,line.substr(position+1).c_str()); 00569 skip_by = atoi(rf); 00570 } 00571 if(line.substr(0,10).compare("block_size")==0){ 00572 string::size_type position = line.find("="); 00573 char rf[10] ; 00574 strcpy(rf,line.substr(position+1).c_str()); 00575 block_size = atoi(rf); 00576 } 00577 if( line.substr(0,15).compare("max_sensitivity")==0 ){ 00578 string::size_type position = line.find("="); 00579 char rf[10] ; 00580 strcpy(rf,line.substr(position + 1 ).c_str()); 00581 maxSen = atof(rf); 00582 } 00583 if( line.substr(0,12).compare("max_accuracy")==0 ){ 00584 string::size_type position = line.find("="); 00585 char rf[10] ; 00586 strcpy(rf,line.substr(position + 1 ).c_str()); 00587 maxAcc = atof(rf); 00588 } 00589 if( line.substr(0,16).compare("training_message")==0 ){ 00590 string::size_type position = line.find("="); 00591 trainingFlag = true ; 00592 trainingMessage = line.substr(position +1) ; 00593 messages->push_back(trainingMessage); 00594 } 00595 00596 } 00597 00598 /*let's load up the sprites associated with the skin and resize them and store them in a map*/ 00599 map<string,SDL_Surface*>* classesMap = new map<string,SDL_Surface*>(); 00600 for( int i = 0 ; i < 6 ; i++ ){ 00601 string filepath ; 00602 filepath += skinFileMap[skin_name]+"/"+classes[i]+"/ball.png" ; 00603 SDL_Surface* tmpSurface = load_image(filepath) ; 00604 tmpSurface = SDL_Resize(tmpSurface , rf , 6 ); 00605 (*classesMap)[classes[i]] = tmpSurface; 00606 } 00607 00608 /*now we find all Euclidean transormations of the patten and store them in a vector 00609 in every trial one of these pattens will be used (either included or excluded) 00610 */ 00611 Matrix *rawPattenMatrix = getPattenByString(pattern) ; 00612 vector<Matrix*>* vars = getAllVariations(*rawPattenMatrix); 00613 int vs = vars->size() ; 00614 00615 float maxSensitivity = 0.0f ; 00616 float maxAccuracy = 0.0f ; 00617 int exposureTime = ie ; 00618 00619 /*Let's start training the subject*/ 00620 d->displayText("Press any key to start!") ; 00621 d->waitForKey() ; 00622 if( trainingFlag ){ 00623 if( staticFlag ){ 00624 doStaticTraining(*classesMap,*messages) ; 00625 } else { 00626 doDynamicTraining(*classesMap,*messages) ; 00627 } 00628 00629 } 00630 00631 /*the real test starts here and unless the required sensitivity is reached or prbability of having 00632 positive cases it will continue 00633 */ 00634 do{ 00635 float sensitivity = 0.0f ; 00636 float accuracy = 0.0f ; 00637 int* experiment = new int[block_size] ; 00638 int* report = new int[block_size] ; 00639 00640 /*here we start different trials and we will have as many as block_size trials*/ 00641 for( int i = 0 ; i < block_size ; i++ ){ 00642 d->clearScreen(); 00643 d->displayText("Please wait!") ; 00644 srand ( time(NULL) ); 00645 int patternChannel = rand()%NUMBER_OF_CLASSES ; 00646 string targetClass = classes[patternChannel]; 00647 srand ( time(NULL) ); 00648 /*here we pick one of the transformed pattern to be used*/ 00649 Matrix *patternMatrix = (*vars)[rand()%vs] ; 00650 vector<Matrix*>* mapsVector ; 00651 bool positiveFalg = true ; 00652 00653 /*here we filp a coin to see if we include the pattern or exclude it*/ 00654 if( rand()%10000 < prb*10000 ){ 00655 mapsVector = getMapsWithExactPattenAndExactChannel(rows,columns,NUMBER_OF_CLASSES , patternChannel+1,*patternMatrix,1,1); 00656 /*we keep in mind that we chose to include the target in the board*/ 00657 experiment[i] = 1 ; 00658 }else{ 00659 mapsVector = getMapsWithExactPattenAndExactChannel(rows,columns,NUMBER_OF_CLASSES , patternChannel+1,*patternMatrix,0,1); 00660 /*we keep in mind that we chose to exclude the target from the board*/ 00661 experiment[i] = 0 ; 00662 positiveFalg = false ; 00663 } 00664 00665 Matrix *map = (*mapsVector)[0] ; 00666 d->pushEvent("class picked : " + targetClass) ; 00667 d->pushEvent("pattern picked : "+patternMatrix->toFormattedString()) ; 00668 d->pushEvent("map picked :" +map->toFormattedString()); 00669 00670 /*now that we have picked the target patten and the board map let's start showing the 00671 target 00672 */ 00673 d->clearScreen(); 00674 d->pushEvent("started showing target image"); 00675 if( staticFlag ){ 00676 showStaticTarget(*patternMatrix,(*classesMap)[targetClass]) ; 00677 } else { 00678 showDynamicTarget(*patternMatrix,(*classesMap)[targetClass]) ; 00679 } 00680 /*we let's delay showing the board after the target*/ 00681 d->pushEvent("started showing blink"); 00682 d->displayFixationBlink(-1, -1, emptyTime/2, 2); 00683 /*now that the target is shown we can show the board*/ 00684 d->pushEvent("started showing the test image"); 00685 if( staticFlag ){ 00686 showStaticSlide(*map,*classesMap , exposureTime ); 00687 } else { 00688 showDynamicSlide(*map,*classesMap , exposureTime ); 00689 } 00690 d->pushEvent("ended showing the test image"); 00691 /*let's ask the subject if s/he identified the target*/ 00692 report[i] = getResponse(); 00693 d->clearScreen(); 00694 } 00695 00696 /*now that we are done with trials let's do some book keeping and see what was subject's sensitivity and 00697 accuracy 00698 */ 00699 float truePositives = 0.0f ; 00700 float trueNegatives = 0.0f ; 00701 float falsePositives = 0.0f ; 00702 float falseNegatives = 0.0f ; 00703 float positives = 0.0f ; 00704 float negatives = 0.0f ; 00705 string reportString(""); 00706 string experimentString(""); 00707 for( int i = 0 ; i < block_size ; i++ ){ 00708 reportString += stringify(report[i]) ; 00709 experimentString += stringify( experiment[i]) ; 00710 if( experiment[i]==1 && report[i]==1 ) {truePositives++ ; positives++ ; } 00711 if( experiment[i]==1 && report[i]==0 ) {falseNegatives++ ; positives++ ; } 00712 if( experiment[i]==0 && report[i]==1 ) {falsePositives++ ;negatives++ ; } 00713 if( experiment[i]==0 && report[i]==0 ) {trueNegatives++ ; negatives++ ;} 00714 } 00715 if( positives != 0 ){ 00716 sensitivity = truePositives / positives ; 00717 } 00718 accuracy = (truePositives + trueNegatives) / (positives+negatives) ; 00719 maxSensitivity = max(sensitivity,maxSensitivity) ; 00720 maxAccuracy = max(accuracy,maxAccuracy); 00721 exposureTime += skip_by ; 00722 d->pushEvent("experiment srting : " + experimentString); 00723 d->pushEvent("report string : " + reportString); 00724 d->pushEvent("sensitivity : "+ stringify(sensitivity)) ; 00725 d->pushEvent("accuracy : " + stringify(accuracy)); 00726 }while( maxSensitivity < maxSen || maxAccuracy < maxAcc ); 00727 00728 00729 /*and here we do necessary cleanups before finishing up the block*/ 00730 for( map<string,SDL_Surface*>::iterator it=classesMap->begin() ; it!= classesMap->end() ; ++it){ 00731 SDL_FreeSurface(it->second); 00732 } 00733 classesMap->~map<string,SDL_Surface*>(); 00734 rawPattenMatrix->~Matrix(); 00735 vars->~vector<Matrix*>() ; 00736 messages->~vector<string>() ; 00737 exclusionList->~vector<string>() ; 00738 d-> displayText("You may take a short break!") ; 00739 d->waitForKey() ; 00740 return 0 ; 00741 } 00742 ///////////////////////////////////////////// 00743 int readprofile(const char* filename){ 00744 ifstream inFile(filename, ios::in); 00745 if (! inFile) 00746 { 00747 LINFO("profile '%s' not found!" , filename); 00748 return -1; 00749 } 00750 00751 char ch[1000]; 00752 while (inFile.getline(ch , 1000)){ 00753 string line = ch; 00754 LINFO("reads : %s", line.c_str()); 00755 if( line.substr(0,11).compare("profilename") == 0 ){ 00756 string::size_type position = line.find("="); 00757 d -> pushEvent("profile "+line.substr(position+1)+" started reading" ) ; 00758 } 00759 if(line.compare("start_top")==0 ) readTop(inFile); 00760 if(line.compare("start_block")==0) readBlock(inFile); 00761 if(programQuit == true) break ; 00762 } 00763 00764 return 0 ; 00765 } 00766 ///////////////////////////////////////////// 00767 00768 00769 extern "C" int main( int argc, char* argv[] ) 00770 00771 { 00772 00773 MYLOGVERB = LOG_INFO; // suppress debug messages 00774 00775 manager.addSubComponent(d); 00776 nub::soft_ref<EventLog> el(new EventLog(manager)); 00777 manager.addSubComponent(el); 00778 d->setEventLog(el); 00779 // Parse command-line: 00780 if (manager.parseCommandLine(argc, argv,"<profile.prf> <logfileName.psy>", 2, 2)==false) 00781 return(1); 00782 manager.setOptionValString(&OPT_EventLogFileName,manager.getExtraArg(1).c_str() ); 00783 manager.start(); 00784 d->clearScreen() ; 00785 readprofile(manager.getExtraArg(0).c_str()); 00786 d->displayText("Experiment is done! Thanks for participating! ") ; 00787 d->waitForKey() ; 00788 manager.stop(); 00789 return(0) ; 00790 // time_t rawtime; 00791 // time ( &rawtime ); 00792 // LINFO("@%s psycho-skin-bsindexing started:...", ctime(&rawtime)); 00793 // manager.start(); 00794 // d->pushEvent(std::string("started the experiment at ")+ ctime( &rawtime ) ); 00795 // SDL_Surface* free = getAFreshSurface(40,80) ; 00796 // SDL_Rect offset; 00797 // //Give the offsets to the rectangle 00798 // d->clearScreen(); 00799 // offset.x = 100; 00800 // offset.y = 60; 00801 // d->displaySDLSurfacePatch(free,&offset,NULL , -2,false, true); 00802 // d->waitFrames(10); 00803 // //////////////////////////// 00804 // d->clearScreen(); 00805 // offset.x = 100; 00806 // offset.y = 160; 00807 // d->displaySDLSurfacePatch(free , &offset,NULL , -2,false, true); 00808 // d->waitFrames(10); 00809 // d->displayText("Experiment complete. Thank you!"); 00810 // //d->waitFrames(1); 00811 // //d->waitForKey(); 00812 // time ( &rawtime ); 00813 // LINFO("...psycho-skin-bsindexing ended @%s .", ctime( &rawtime )); 00814 // d->pushEvent(std::string("experiment ended at ")+ ctime( &rawtime ) ); 00815 // manager.stop(); 00816 // 00817 // return 0 ; 00818 } 00819 00820 #endif // INVT_HAVE_LIBSDL_IMAGE 00821