00001 /*!@file GameBoard/psycho-direction.C overlays the markup on top of the image */ 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/GameBoard/psycho-direction.C $ 00035 // 00036 00037 #include "Component/ModelManager.H" 00038 #include "Image/Image.H" 00039 #include "Psycho/PsychoDisplay.H" 00040 #include "Psycho/EyeTrackerConfigurator.H" 00041 #include "Psycho/EyeTracker.H" 00042 #include "Psycho/PsychoOpts.H" 00043 #include "Component/EventLog.H" 00044 #include "Component/ComponentOpts.H" 00045 #include "Raster/Raster.H" 00046 #include "Util/MathFunctions.H" 00047 #include "Util/Types.H" 00048 #include "GameBoard/basic-graphics.H" 00049 #include "GameBoard/resize.h" 00050 #include <sys/types.h> 00051 #include <dirent.h> 00052 #include <errno.h> 00053 #include <vector> 00054 #include <map> 00055 #include <string> 00056 #include <iostream> 00057 #include <SDL/SDL.h> 00058 #include <SDL/SDL_image.h> 00059 #include <stdio.h> 00060 #include <stdlib.h> 00061 #include <sstream> 00062 #include <time.h> 00063 #include "Image/DrawOps.H" 00064 #include "GameBoard/resize.h" 00065 #include <iostream> 00066 #include <fstream> 00067 #include <set> 00068 #include <algorithm> 00069 00070 #define PI 3.14159265 00071 00072 using namespace std; 00073 map<string,string> argMap ; 00074 00075 00076 //pushes back the name of files in the directory into the given vector 00077 int getdir (string dir, vector<string> &files ,string ext) 00078 { 00079 DIR *dp; 00080 struct dirent *dirp; 00081 if((dp = opendir(dir.c_str())) == NULL) { 00082 cout << "Error(" << errno << ") opening " << dir << endl; 00083 return errno; 00084 } 00085 string fn = "" ; 00086 size_t found; 00087 string extension = "" ; 00088 while ((dirp = readdir(dp)) != NULL) { 00089 fn = string(dirp->d_name) ; 00090 found = fn.find_last_of("."); 00091 if(found > 0 && found <1000){ 00092 extension = fn.substr(found) ; 00093 if(extension.compare(ext)== 0 ) 00094 files.push_back(dir+"/"+fn); 00095 } 00096 } 00097 closedir(dp); 00098 return 0; 00099 } 00100 00101 string getCorrespondingDataFile(string fn, vector<string> files){ 00102 uint pos = fn.find_last_of("/"); 00103 string lp = fn.substr(pos+1) ; 00104 lp = lp.substr(0,lp.find(".")); 00105 for( uint i = 0 ; i < files.size() ; i++ ){ 00106 uint posd = files[i].find_last_of("/"); 00107 string lpd = files[i].substr(posd+1) ; 00108 lpd = lpd.substr(0,lpd.find(".")); 00109 if(lpd.compare(lp) == 0) return files[i] ; 00110 } 00111 return "" ; 00112 } 00113 void overlay_rect(SDL_Surface* surf,Point2D<int> location , Point2D<int> size , Uint32 bc){ 00114 Point2D<int> corner = Point2D<int>(location.i- size.i/2 , location.j - size.j/2) ; 00115 drawRectangle(surf,bc,corner.i,corner.j,size.i -1,size.j -1 ,1); 00116 00117 } 00118 00119 00120 int addArgument(const string st,const string delim="="){ 00121 int i = st.find(delim) ; 00122 argMap[st.substr(0,i)] = st.substr(i+1); 00123 00124 return 0 ; 00125 } 00126 00127 std::string getArgumentValue(string arg){ 00128 return argMap[arg] ; 00129 } 00130 00131 std::string getUsageComment(){ 00132 00133 string com = string("\nlist of arguments : \n"); 00134 00135 com += "\ndelay=[>=0] (the delaly for overlaying marks) {default=0}\n"; 00136 com += "\nlogfile=[logfilename.psy] {default = eyemarkup.psy}\n" ; 00137 com += "\nmode=[1..2] (1 for static , 2 for dynamic) {default=2}\n" ; 00138 com += "\nimage-dir=[path to directory of images]\n" ; 00139 com += "\ndata-dir=[path to directory of .ceyeS files]\n" ; 00140 return com ; 00141 } 00142 00143 void findDirection(Point2D<float> p , Point2D<float> c , map<double,double>& dirMap){ 00144 bool flag = true ; 00145 if(c.i == p.i) flag=false; 00146 double myTan = (double)(-c.j + p.j)/(double)(c.i-p.i); 00147 double dis = sqrt((-c.j + p.j)*(-c.j + p.j) + (c.i-p.i)*(c.i-p.i)); 00148 double myCos = (double)(c.i-p.i)/dis; 00149 double direction = 0.0 ; 00150 00151 if(flag){ 00152 if( myCos<=0 ){ 00153 if(myTan<=0) {direction = atan(myTan) + PI ;}else{ direction = atan(myTan) - PI ;} 00154 } else{ 00155 direction = atan(myTan) ; 00156 } 00157 }else{ 00158 if(c.j>p.j){ 00159 direction = -PI/2 ; 00160 } else{ 00161 direction = PI/2 ; 00162 } 00163 } 00164 00165 map<double,double>::iterator it = dirMap.find(direction); 00166 if( it!= dirMap.end()) { 00167 // cout<<"here"<<endl ; 00168 dirMap[direction] = dirMap[direction]+dis ; 00169 }else{ 00170 dirMap[direction] = dis ; 00171 // cout<<"there " << direction << " "<< dis <<endl ; 00172 } 00173 00174 } 00175 00176 extern "C" int main(const int argc, char** argv) 00177 { 00178 ModelManager manager("Psycho Skin"); 00179 nub::soft_ref<PsychoDisplay> d(new PsychoDisplay(manager)); 00180 00181 MYLOGVERB = LOG_INFO; // suppress debug messages 00182 argMap["mode"] = "2" ; 00183 argMap["logfile"]="eyemarkup.psy" ; 00184 argMap["image-dir"]="."; 00185 argMap["data-dir"] = "." ; 00186 argMap["delay"]="0" ; 00187 00188 manager.addSubComponent(d); 00189 nub::soft_ref<EventLog> el(new EventLog(manager)); 00190 manager.addSubComponent(el); 00191 d->setEventLog(el); 00192 if (manager.parseCommandLine(argc, argv, 00193 "at least one argument needed", 1, -1)==false){ 00194 cout<<getUsageComment()<<endl; 00195 return(1); 00196 } 00197 00198 for(uint i = 0 ; i < manager.numExtraArgs() ; i++){ 00199 addArgument(manager.getExtraArg(i),std::string("=")) ; 00200 } 00201 // Parse command-line: 00202 manager.setOptionValString(&OPT_EventLogFileName, argMap["logfile"]); 00203 manager.start(); 00204 00205 string dir = argMap["image-dir"]; 00206 vector<string> imfiles = vector<string>(); 00207 getdir(dir,imfiles,".png"); 00208 00209 dir = argMap["data-dir"]; 00210 vector<string> datafiles = vector<string>(); 00211 getdir(dir,datafiles,".eyes"); 00212 00213 while(imfiles.size() > 0){ 00214 string imfilename = imfiles[0] ; 00215 imfiles.erase(imfiles.begin()); 00216 LINFO(imfilename.c_str()); 00217 00218 //let's define a bunch of colors for different events and put them in a map 00219 // fixation: 0 blue 00220 // saccade: 1 green 00221 // blink/Artifact: 2 red 00222 // Saccade during Blink: 3 green .- 00223 // smooth pursuit: 4 magenta 00224 // drift/misclassification: 5 black 00225 Uint32 blue = d->getUint32color(PixRGB<byte>(0, 0, 255)); 00226 Uint32 green = d->getUint32color(PixRGB<byte>(0,255,0) ); 00227 Uint32 red = d->getUint32color(PixRGB<byte>(255,0,0) ); 00228 Uint32 saccade_green = d->getUint32color(PixRGB<byte>(0,150,0) ); 00229 Uint32 magenta = d->getUint32color(PixRGB<byte>(0,255,255) ); 00230 Uint32 black = d->getUint32color(PixRGB<byte>(0,0,0) ); 00231 map<string,Uint32> colormap = map<string,Uint32>() ; 00232 colormap["0"] = blue ; colormap["1"] = green ;colormap["2"] = red ; 00233 colormap["3"] = saccade_green ; colormap["4"]=magenta ; colormap["5"]= black ; 00234 00235 //now let's take in the corresponding .ceyeS file 00236 string datafilename = getCorrespondingDataFile(imfilename,datafiles); 00237 if(datafilename.size()!=0){ 00238 00239 SDL_Surface* im = load_image(imfilename) ; 00240 float rsf = min((float)d->getWidth()/(float)im->w , (float)d->getHeight()/(float)im->h ) ; 00241 im = SDL_Resize(im , rsf, 5) ; 00242 SDL_Rect offset ; 00243 offset.x= (d->getWidth() - im->w) /2; 00244 offset.y=(d-> getHeight() - im->h) /2; 00245 // int maxX = (d->getWidth()-10);//*rsf; 00246 // int maxY = (d->getHeight()-10);//*rsf ; 00247 ifstream inFile( datafilename.c_str() , ios::in); 00248 if (! inFile) 00249 { 00250 LINFO("profile '%s' not found!" , datafilename.c_str()); 00251 return -1; 00252 } 00253 Point2D<int> loc ; 00254 Point2D<int> rectsize = Point2D<int>(6,6) ; 00255 Point2D<float> preLoc ; 00256 preLoc.i = -1.0 ; 00257 Point2D<float> curLoc ; 00258 char ch[1000]; 00259 map<double,double> dirDistMap; 00260 while (inFile.getline(ch , 1000) ){ 00261 string line = ch; 00262 //cout<<line<<endl; 00263 if(line.compare("NaN NaN NaN 0.0")!=0){ 00264 uint pos = line.find(" "); 00265 curLoc.i = atof(line.substr(0,pos).c_str()) ; 00266 loc.i = (int) (rsf*curLoc.i) ; 00267 line = line.substr(pos+1); 00268 pos = line.find(" "); 00269 curLoc.j = atof(line.substr(0,pos).c_str()) ; 00270 loc.j = (int) (rsf*curLoc.j) ; 00271 00272 // string colorcode = line.substr(line.size()-1) ; 00273 //if(colorcode.compare("2")!=0){ 00274 if(preLoc.i!=-1.0){ 00275 findDirection(preLoc,curLoc,dirDistMap); 00276 } 00277 preLoc.i = curLoc.i ; 00278 preLoc.j = curLoc.j ; 00279 //}else{ 00280 // preLoc.i = -1.0 ; 00281 //} 00282 // if (loc.i > 4 && loc.j > 4 && loc.i < maxX && loc.j < maxY) 00283 // overlay_rect(im,loc,rectsize,colormap["1"]); 00284 00285 if(argMap["mode"].compare("2")==0) 00286 d->waitFrames(atoi(argMap["delay"].c_str())); 00287 d->displaySDLSurfacePatch(im , &offset,NULL , -2,false, true) ; 00288 }else{preLoc.i = -1.0 ;} 00289 } 00290 00291 map<Point2D<double>,double> binDirDistMap ; 00292 map<double, double>::iterator iter; 00293 00294 // cout<<"size " <<dirDistMap.size()<<endl ; 00295 // for (iter=dirDistMap.begin(); iter != dirDistMap.end(); ++iter) { 00296 // cout<<"direction "<<iter->first<<" distance "<<iter->second<<endl ; 00297 // // if (iter->first >= a && iter->second < a+PI/32.0) binDirDistMap[a] = binDirDistMap[a]+iter->second; 00298 // } 00299 00300 double tD= 0.0 ; 00301 00302 int numOfSec = 64 ; 00303 for(int i = 0 ; i < numOfSec ; i++){ 00304 double a = (i- numOfSec/2 )*PI/(numOfSec/2) ; 00305 binDirDistMap[Point2D<double>(a,a+ PI/(numOfSec/2))] = 0.0 ; 00306 } 00307 map<Point2D<double>,double>::iterator fiter ; 00308 for(fiter=binDirDistMap.begin() ; fiter != binDirDistMap.end() ; ++fiter){ 00309 Point2D<double> p = fiter->first ; 00310 double v = 0.0 ; 00311 for(iter = dirDistMap.begin() ; iter != dirDistMap.end() ; ++iter){ 00312 double ov = iter->first ; 00313 double od = iter->second ; 00314 if(ov>p.i && ov<=p.j) v+= od ; 00315 } 00316 binDirDistMap[p] = v ; 00317 tD+=v ; 00318 cout<<p.j<<" "<<v<<endl ; 00319 } 00320 // for(int i = 0 ; i < 64 ; i++){ 00321 // double a = (i-32)*PI/32 ; 00322 // for (iter=dirDistMap.begin(); iter != dirDistMap.end(); ++iter) { 00323 // if (iter->first > a && iter->second <= a+PI/32.0) binDirDistMap[a] += iter->second; 00324 // tD += iter->second ; 00325 // } 00326 // } 00327 // for (iter=binDirDistMap.begin(); iter != binDirDistMap.end(); ++iter) { 00328 // cout<<iter->first<<" "<<iter->second<<endl ; 00329 // } 00330 // cout<<"total :"<<tD <<endl ; 00331 d->waitForMouseClick() ; 00332 dumpSurface(im) ; 00333 00334 } 00335 00336 00337 00338 00339 } 00340 manager.stop(); 00341 return 0 ; 00342 00343 } 00344