00001 /*!@file GameBoard/fixationmarkup-overlay.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/fixationmarkup-overlay.C $ 00035 // $Id: fixationmarkup-overlay.C 10794 2009-02-08 06:21:09Z itti $ 00036 // 00037 00038 #include "Component/ModelManager.H" 00039 #include "Image/Image.H" 00040 #include "Psycho/PsychoDisplay.H" 00041 #include "Psycho/EyeTrackerConfigurator.H" 00042 #include "Psycho/EyeTracker.H" 00043 #include "Psycho/PsychoOpts.H" 00044 #include "Component/EventLog.H" 00045 #include "Component/ComponentOpts.H" 00046 #include "Raster/Raster.H" 00047 #include "Util/MathFunctions.H" 00048 #include "Util/Types.H" 00049 #include "GameBoard/basic-graphics.H" 00050 #include "GameBoard/resize.h" 00051 #include <sys/types.h> 00052 #include <dirent.h> 00053 #include <errno.h> 00054 #include <vector> 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 using namespace std; 00070 map<string,string> argMap ; 00071 00072 00073 ///////////////////////////////////////////// 00074 00075 // a functionf for stringigying things 00076 template <class T> std::string stringify(T i) 00077 { 00078 ostringstream o ; 00079 o << i ; 00080 return o.str(); 00081 } 00082 00083 00084 //pushes back the name of files in the directory into the given vector 00085 int getdir (string dir, vector<string> &files ,string ext) 00086 { 00087 DIR *dp; 00088 struct dirent *dirp; 00089 if((dp = opendir(dir.c_str())) == NULL) { 00090 cout << "Error(" << errno << ") opening " << dir << endl; 00091 return errno; 00092 } 00093 string fn = "" ; 00094 size_t found; 00095 string extension = "" ; 00096 while ((dirp = readdir(dp)) != NULL) { 00097 fn = string(dirp->d_name) ; 00098 found = fn.find_last_of("."); 00099 if(found > 0 && found <1000){ 00100 extension = fn.substr(found) ; 00101 if(extension.compare(ext)== 0 ) 00102 files.push_back(dir+"/"+fn); 00103 } 00104 } 00105 closedir(dp); 00106 return 0; 00107 } 00108 00109 //pushes back the name of files in the directory into the given vector 00110 int getdatafiles (string dir, vector<string> &files ,string ext , string imname) 00111 { 00112 DIR *dp; 00113 struct dirent *dirp; 00114 if((dp = opendir(dir.c_str())) == NULL) { 00115 cout << "Error(" << errno << ") opening " << dir << endl; 00116 return errno; 00117 } 00118 string fn = "" ; 00119 size_t foundslash; 00120 size_t found ; 00121 string root = "" ; 00122 string extension = "" ; 00123 while ((dirp = readdir(dp)) != NULL) { 00124 fn = string(dirp->d_name) ; 00125 foundslash = fn.find_last_of("/"); 00126 found = fn.find_last_of("."); 00127 if(found > 0 && found <1000){ 00128 extension = fn.substr(found) ; 00129 root = fn.substr(foundslash+1 , imname.size()) ; 00130 if(root.compare(imname)== 0 ) 00131 files.push_back(dir+"/"+fn); 00132 } 00133 } 00134 closedir(dp); 00135 return 0; 00136 } 00137 00138 00139 00140 00141 string getDataDirName(string prefix ,int i){ 00142 string s = stringify(i); 00143 switch( s.size() ){ 00144 case 1 : s = prefix+"00"+s; break ; 00145 case 2 : s = prefix+"0"+s; break ; 00146 } 00147 return s ; 00148 } 00149 00150 string getDataDirPath(string dir , string prefix, int i){ 00151 string s = dir+"/"+getDataDirName(prefix,i)+"/" ; 00152 return s ; 00153 } 00154 00155 string getCorrespondingDataFile(string fn, vector<string> files){ 00156 uint pos = fn.find_last_of("/"); 00157 string lp = fn.substr(pos+1) ; 00158 lp = lp.substr(0,lp.find(".")); 00159 for( uint i = 0 ; i < files.size() ; i++ ){ 00160 uint posd = files[i].find_last_of("/"); 00161 string lpd = files[i].substr(posd+1) ; 00162 lpd = lpd.substr(0,lpd.find(".")); 00163 if(lpd.compare(lp) == 0) return files[i] ; 00164 } 00165 return "" ; 00166 } 00167 void overlay_circle(SDL_Surface* surf,Point2D<int> location ,int r , Uint32 bc){ 00168 if (location.i - r >=0 && location.i + r <= surf->w && location.j-r>= 0 && location.j+r <= surf->h) 00169 drawCircle(surf,bc,location.i,location.j,r,1); 00170 00171 } 00172 00173 00174 int addArgument(const string st,const string delim="="){ 00175 int i = st.find(delim) ; 00176 argMap[st.substr(0,i)] = st.substr(i+1); 00177 00178 return 0 ; 00179 } 00180 00181 std::string getArgumentValue(string arg){ 00182 return argMap[arg] ; 00183 } 00184 00185 std::string getUsageComment(){ 00186 00187 string com = string("\nlist of arguments : \n"); 00188 com += "\nlogfile=[logfilename.psy] {default = fixationmarkup.psy}\n" ; 00189 com += "\nimage=[path to the image]\n" ; 00190 com += "\ndata-dir=[path to directory of containing directories of subjects]{default=/lab/nnoori/works/data/concurrent/digicon}\n" ; 00191 com += "\nprefix=[cs or ms or any prefix used for storing subject data]{default=cs}\n" ; 00192 com += "\nlast-subject-num=[>0]{default=50}\n" ; 00193 com += "\nmax-saccade=[>1](maximum number of saccade end points to be overlayed){default=20}\n"; 00194 return com ; 00195 } 00196 00197 extern "C" int main(const int argc, char** argv) 00198 { 00199 ModelManager manager("Psycho Skin"); 00200 nub::soft_ref<PsychoDisplay> d(new PsychoDisplay(manager)); 00201 00202 MYLOGVERB = LOG_INFO; // suppress debug messages 00203 argMap["logfile"] = "fixationmarkup.psy" ; 00204 argMap["data-dir"] = "/lab/nnoori/works/data/concurrent/digicon" ; 00205 argMap["last-subject-num"] = "50" ; 00206 argMap["prefix"]="" ; 00207 argMap["max-saccade"]="20" ; 00208 manager.addSubComponent(d); 00209 nub::soft_ref<EventLog> el(new EventLog(manager)); 00210 manager.addSubComponent(el); 00211 d->setEventLog(el); 00212 if (manager.parseCommandLine(argc, argv, 00213 "at least one argument needed", 1, -1)==false){ 00214 cout<<getUsageComment()<<endl; 00215 return(1); 00216 } 00217 for(uint i = 0 ; i < manager.numExtraArgs() ; i++){ 00218 addArgument(manager.getExtraArg(i),std::string("=")) ; 00219 } 00220 // Parse command-line: 00221 manager.setOptionValString(&OPT_EventLogFileName, argMap["logfile"]); 00222 manager.start(); 00223 string imfilename = argMap["image"]; 00224 string imagename = imfilename.substr(imfilename.find_last_of("/")+1, imfilename.find_last_of(".") - imfilename.find_last_of("/") -1 ); 00225 vector<string> datafiles = vector<string>(); 00226 00227 getdatafiles(argMap["data-dir"],datafiles,".e-ceyeS",imagename); 00228 // string ts ; 00229 // for( uint i = 1 ; i < (uint)atoi(argMap["last-subject-num"].c_str()); i++){ 00230 // ts = getDataDirPath( argMap["data-dir"], argMap["prefix"], i) + imagename+".e-ceyeS" ; 00231 // datafiles.push_back(ts); 00232 // LINFO(ts.c_str()) ; 00233 // } 00234 00235 00236 SDL_Surface* im = load_image(imfilename) ; 00237 float rsf = min((float)d->getWidth()/(float)im->w , (float)d->getHeight()/(float)im->h ) ; 00238 im = SDL_Resize(im , rsf, 5) ; 00239 SDL_Rect offset ; 00240 offset.x= (d->getWidth() - im->w) /2; 00241 offset.y=(d-> getHeight() - im->h) /2; 00242 00243 Uint32 blue = d->getUint32color(PixRGB<byte>(0, 0, 255)); 00244 Uint32 green = d->getUint32color(PixRGB<byte>(0,255,0) ); 00245 Uint32 red = d->getUint32color(PixRGB<byte>(255,0,0) ); 00246 Uint32 saccade_green = d->getUint32color(PixRGB<byte>(0,150,0) ); 00247 Uint32 magenta = d->getUint32color(PixRGB<byte>(0,255,255) ); 00248 Uint32 black = d->getUint32color(PixRGB<byte>(0,0,0) ); 00249 map<string,Uint32> colormap = map<string,Uint32>() ; 00250 colormap["0"] = blue ; colormap["1"] = green ;colormap["2"] = red ; 00251 colormap["3"] = saccade_green ; colormap["4"]=magenta ; colormap["5"]= black ; 00252 00253 for( uint i = 0 ; i < datafiles.size() ; i++ ){ 00254 string datafilename = datafiles[i] ; 00255 00256 ifstream inFile( datafilename.c_str() , ios::in); 00257 if (! inFile) 00258 { 00259 LINFO("profile '%s' not found!" , datafilename.c_str()); 00260 //return -1; 00261 }else { 00262 Point2D<int> loc ; 00263 char ch[1000]; 00264 int c = 0 ; 00265 int cmax = atoi(argMap["max-saccade"].c_str()) ; 00266 while (inFile.getline(ch , 1000) ){ 00267 string line = ch; 00268 if(line.substr(line.size() - 13 ).compare("0.0 0.0 0.0 0") != 0 ){ 00269 //LINFO("reads : %s", line.c_str()); 00270 uint pos = line.find(" "); 00271 loc.i = (int) (rsf*atof(line.substr(0,pos).c_str())) ; 00272 line = line.substr(pos+1); 00273 pos = line.find(" "); 00274 loc.j = (int) (rsf*atof(line.substr(0,pos).c_str())) ; 00275 line = line.substr(pos+1); 00276 pos = line.find(" "); 00277 line = line.substr(pos+1); 00278 pos = line.find(" "); 00279 string colorcode = line.substr(0,pos) ; 00280 line = line.substr(pos+1); 00281 pos = line.find(" "); 00282 loc.i = (int) (rsf*atof(line.substr(0,pos).c_str())) ; 00283 line = line.substr(pos+1); 00284 pos = line.find(" "); 00285 loc.j = (int) (rsf*atof(line.substr(0,pos).c_str())) ; 00286 if(colorcode.compare("1")==0 && c < cmax){ 00287 int clt = max(0,255-20*c) ; 00288 Uint32 color = d->getUint32color(PixRGB<byte>(clt,clt,clt) ); 00289 overlay_circle(im,loc,(int)(rsf*30),color); 00290 c++ ; 00291 } 00292 00293 00294 00295 } 00296 00297 00298 } 00299 00300 } 00301 } 00302 00303 d->displaySDLSurfacePatch(im , &offset,NULL , -2,false, true) ; 00304 d->waitForMouseClick() ; 00305 dumpSurface(im) ; 00306 00307 // while(imfiles.size() > 0){ 00308 // string imfilename = imfiles[0] ; 00309 // imfiles.erase(imfiles.begin()); 00310 // LINFO(imfilename.c_str()); 00311 // 00312 // //let's define a bunch of colors for different events and put them in a map 00313 // // fixation: 0 blue 00314 // // saccade: 1 green 00315 // // blink/Artifact: 2 red 00316 // // Saccade during Blink: 3 green .- 00317 // // smooth pursuit: 4 magenta 00318 // // drift/misclassification: 5 black 00319 // Uint32 blue = d->getUint32color(PixRGB<byte>(0, 0, 255)); 00320 // Uint32 green = d->getUint32color(PixRGB<byte>(0,255,0) ); 00321 // Uint32 red = d->getUint32color(PixRGB<byte>(255,0,0) ); 00322 // Uint32 saccade_green = d->getUint32color(PixRGB<byte>(0,150,0) ); 00323 // Uint32 magenta = d->getUint32color(PixRGB<byte>(0,255,255) ); 00324 // Uint32 black = d->getUint32color(PixRGB<byte>(0,0,0) ); 00325 // map<string,Uint32> colormap = map<string,Uint32>() ; 00326 // colormap["0"] = blue ; colormap["1"] = green ;colormap["2"] = red ; 00327 // colormap["3"] = saccade_green ; colormap["4"]=magenta ; colormap["5"]= black ; 00328 // 00329 // //now let's take in the corresponding .ceyeS file 00330 // string datafilename = getCorrespondingDataFile(imfilename,datafiles); 00331 // if(datafilename.size()!=0){ 00332 // 00333 // SDL_Surface* im = load_image(imfilename) ; 00334 // float rsf = min((float)d->getWidth()/(float)im->w , (float)d->getHeight()/(float)im->h ) ; 00335 // im = SDL_Resize(im , rsf, 5) ; 00336 // SDL_Rect offset ; 00337 // offset.x= (d->getWidth() - im->w) /2; 00338 // offset.y=(d-> getHeight() - im->h) /2; 00339 // 00340 // ifstream inFile( datafilename.c_str() , ios::in); 00341 // if (! inFile) 00342 // { 00343 // LINFO("profile '%s' not found!" , datafilename.c_str()); 00344 // return -1; 00345 // } 00346 // Point2D<int> rectsize = Point2D<int>(6,6) ; 00347 // Point2D<int> loc ; 00348 // char ch[1000]; 00349 // 00350 // while (inFile.getline(ch , 1000) ){ 00351 // string line = ch; 00352 // //LINFO("reads : %s", line.c_str()); 00353 // uint pos = line.find(" "); 00354 // loc.i = (int) (rsf*atof(line.substr(0,pos).c_str())) ; 00355 // line = line.substr(pos+1); 00356 // pos = line.find(" "); 00357 // loc.j = (int) (rsf*atof(line.substr(0,pos).c_str())) ; 00358 // string colorcode = line.substr(line.size()-1) ; 00359 // if (loc.i > 4 && loc.j > 4 ) 00360 // overlay_circle(im,loc,10,colormap[colorcode]); 00361 // if(argMap["mode"].compare("2")==0) 00362 // d->waitFrames(atoi(argMap["delay"].c_str())); 00363 // d->displaySDLSurfacePatch(im , &offset,NULL , -2,false, true) ; 00364 // } 00365 // d->waitForMouseClick() ; 00366 // dumpSurface(im) ; 00367 // 00368 // } 00369 // 00370 // 00371 // 00372 // 00373 // } 00374 manager.stop(); 00375 return 0 ; 00376 } 00377