00001 /*!@file Gist/extractGist.C Extract gist features 00002 from MPEGStream or gistList file */ 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: Christian Siagian <siagian@usc.edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Gist/extractGist.C $ 00035 // $Id: extractGist.C 14376 2011-01-11 02:44:34Z pez $ 00036 // 00037 00038 #include "Channels/ChannelOpts.H" 00039 #include "Component/GlobalOpts.H" 00040 #include "Component/ModelManager.H" 00041 #include "Component/ModelOptionDef.H" 00042 #include "Image/CutPaste.H" 00043 #include "Image/Dims.H" 00044 #include "Image/DrawOps.H" 00045 #include "Image/Pixels.H" 00046 #include "Media/MPEGStream.H" 00047 #include "Media/MediaOpts.H" 00048 #include "Media/MediaSimEvents.H" 00049 #include "Neuro/GistEstimatorStd.H" 00050 #include "Neuro/NeuroOpts.H" 00051 #include "Neuro/SpatialMetrics.H" 00052 #include "Neuro/StdBrain.H" 00053 #include "Neuro/gistParams.H" 00054 #include "Raster/Raster.H" 00055 #include "Simulation/SimEventQueueConfigurator.H" 00056 00057 #include "GUI/XWinManaged.H" 00058 00059 #define SQ_SIZE 20 //the size of a square in the histogram 00060 00061 CloseButtonListener wList; 00062 XWinManaged *inputWin; 00063 XWinManaged *gistWin; 00064 00065 // ###################################################################### 00066 void getGistFileList(std::string fName, 00067 std::vector<std::string>& tag, 00068 std::vector<int>& start, 00069 std::vector<int>& num); 00070 00071 void saveData(Image<double> data, std::string fName, int num); 00072 // ###################################################################### 00073 00074 // Main function 00075 int main(const int argc, const char **argv) 00076 { 00077 00078 MYLOGVERB = LOG_INFO; // suppress debug messages 00079 00080 // Instantiate a ModelManager: 00081 ModelManager manager("Gist Features Extraction"); 00082 00083 // we cannot use saveResults() on our various ModelComponent objects 00084 // here, so let's not export the related command-line options. 00085 manager.allowOptions(OPTEXP_ALL & (~OPTEXP_SAVE)); 00086 00087 // Instantiate our various ModelComponents: 00088 nub::soft_ref<SimEventQueueConfigurator> 00089 seqc(new SimEventQueueConfigurator(manager)); 00090 manager.addSubComponent(seqc); 00091 00092 nub::soft_ref<InputMPEGStream> 00093 ims(new InputMPEGStream(manager, "Input MPEG Stream", "InputMPEGStream")); 00094 manager.addSubComponent(ims); 00095 00096 nub::soft_ref<StdBrain> brain(new StdBrain(manager)); 00097 manager.addSubComponent(brain); 00098 00099 nub::ref<SpatialMetrics> metrics(new SpatialMetrics(manager)); 00100 manager.addSubComponent(metrics); 00101 00102 manager.exportOptions(MC_RECURSE); 00103 metrics->setFOAradius(30); // FIXME 00104 metrics->setFoveaRadius(30); // FIXME 00105 00106 // setting up the GIST ESTIMATOR 00107 manager.setOptionValString(&OPT_GistEstimatorType,"Std"); 00108 //manager.setOptionValString(&OPT_GistEstimatorType,"FFT"); 00109 00110 // Request a bunch of option aliases (shortcuts to lists of options): 00111 REQUEST_OPTIONALIAS_NEURO(manager); 00112 00113 // Parse command-line: 00114 if (manager.parseCommandLine(argc, argv, "<*.mpg or *_gistList.txt>", 00115 1, 1) == false) 00116 return(1); 00117 00118 nub::soft_ref<SimEventQueue> seq = seqc->getQ(); 00119 00120 // if the file passed ends with _gistList.txt 00121 // we have a different protocol 00122 bool isGistListInput = false; 00123 int ifLen = manager.getExtraArg(0).length(); 00124 if(ifLen > 13 && 00125 manager.getExtraArg(0).find("_gistList.txt",ifLen - 13) != 00126 std::string::npos) 00127 isGistListInput = true; 00128 00129 // NOTE: this could now be controlled by a command-line option 00130 // --preload-mpeg=true 00131 manager.setOptionValString(&OPT_InputMPEGStreamPreload, "true"); 00132 00133 // do post-command-line configs: 00134 std::vector<std::string> tag; 00135 std::vector<int> start; 00136 std::vector<int> num; 00137 unsigned int cLine = 0; int cIndex = 0; 00138 if(isGistListInput) 00139 { 00140 LINFO("we have a gistList input"); 00141 getGistFileList(manager.getExtraArg(0).c_str(), tag, start, num); 00142 cIndex = start[0]; 00143 } 00144 else 00145 { 00146 LINFO("we have an mpeg input"); 00147 ims->setFileName(manager.getExtraArg(0)); 00148 manager.setOptionValString(&OPT_InputFrameDims, 00149 convertToString(ims->peekDims())); 00150 } 00151 00152 // frame delay in seconds 00153 //double fdelay = 33.3667/1000.0; // real time 00154 double fdelay = 3.3667/1000.0; 00155 00156 // let's get all our ModelComponent instances started: 00157 manager.start(); 00158 00159 // get the GistEstimator 00160 nub::soft_ref<GistEstimatorStd> ge;////// = 00161 /////// dynCastWeak<GistEstimatorStd>(brain->getGE()); 00162 LFATAL("fixme"); 00163 if (ge.isInvalid()) LFATAL("I am useless without a GistEstimator"); 00164 00165 // MAIN LOOP 00166 SimTime prevstime = SimTime::ZERO(); 00167 int fNum = 0; 00168 Image< PixRGB<byte> > inputImg; Image< PixRGB<byte> > dispImg; 00169 Image<double> cgist; 00170 std::string folder = ""; 00171 std::string::size_type sPos = manager.getExtraArg(0).rfind("/",ifLen); 00172 if(sPos != std::string::npos) 00173 folder = manager.getExtraArg(0).substr(0,sPos+1); 00174 00175 LINFO("let's start"); 00176 while(1) 00177 { 00178 // has the time come for a new frame? 00179 if (fNum == 0 || 00180 (seq->now() - 0.5 * (prevstime - seq->now())).secs() - fNum * fdelay > fdelay) 00181 { 00182 // load new frame 00183 std::string fName; 00184 if(isGistListInput) 00185 { 00186 if (cLine >= tag.size()) break; // end of input list 00187 00188 // open the current file 00189 char tNumStr[100]; sprintf(tNumStr,"%06d",cIndex); 00190 fName = folder + tag[cLine] + std::string(tNumStr) + ".ppm"; 00191 00192 inputImg = Raster::ReadRGB(fName); 00193 cIndex++; 00194 00195 if(cIndex >= start[cLine] + num[cLine]) 00196 { 00197 cLine++; 00198 if (cLine < tag.size()) cIndex = start[cLine]; 00199 } 00200 00201 // reformat the file name to a gist name 00202 int fNameLen = fName.length(); 00203 unsigned int uPos = fName.rfind("_",fNameLen); 00204 fName = fName.substr(0,uPos)+ ".ppm"; 00205 00206 } 00207 else 00208 { 00209 fName = manager.getExtraArg(0); 00210 inputImg = ims->readRGB(); //Raster::ReadRGB(manager.getExtraArg(1)); 00211 if (inputImg.initialized() == false) break; // end of input stream 00212 // format new frame 00213 inputImg = crop(inputImg, 00214 Rectangle(Point2D<int>(0,25), 00215 Dims(inputImg.getHeight(), 00216 inputImg.getWidth()-25+1))); 00217 cIndex = fNum+1; 00218 } 00219 00220 dispImg = inputImg; 00221 LINFO("\nnew frame :%d",fNum); 00222 00223 // pass input to brain: 00224 rutz::shared_ptr<SimEventInputFrame> 00225 e(new SimEventInputFrame(brain.get(), GenericFrame(inputImg), 0)); 00226 seq->post(e); // post the image to the brain 00227 00228 // get the gist feature vector 00229 cgist = ge->getGist(); 00230 //for(uint k = 0; k < cgist.getSize(); k++) LINFO("%d: %f",k, cgist.getVal(0,k)); 00231 00232 // // setup display at the start of stream 00233 // if (fNum == 0) 00234 // { 00235 // int s = SQ_SIZE; 00236 // inputWin = new XWinManaged(Dims(w, h), 0, 0, manager.getExtraArg(0).c_str()); 00237 // wList.add(inputWin); 00238 // gistWin = new XWinManaged(Dims(NUM_GIST_COL * s, NUM_GIST_FEAT * s), 0,0, "Gist"); 00239 // wList.add(gistWin); 00240 // } 00241 00242 // // display the input image and the gist histogram 00243 // drawGrid(dispImg, w/4,h/4,1,1,PixRGB<byte>(255,255,255)); 00244 // inputWin->drawImage(dispImg,0,0); 00245 // gistWin->drawImage(ge->getGistHistogram(SQ_SIZE),0,0); 00246 00247 // SAVE GIST FEATURES TO A FILE 00248 saveData(cgist, fName, cIndex-1); 00249 //LINFO("\nFrame number just saved:%d",fNum);Raster::waitForKey(); 00250 00251 // increase frame count 00252 fNum++; 00253 } 00254 00255 // evolve brain: 00256 prevstime = seq->now(); // time before current step 00257 const SimStatus status = seq->evolve(); 00258 if (SIM_BREAK == status) // Brain decided it's time to quit 00259 break; 00260 00261 } 00262 00263 // stop all our ModelComponents 00264 manager.stop(); 00265 00266 // all done! 00267 return 0; 00268 } 00269 00270 // ###################################################################### 00271 void getGistFileList(std::string fName, std::vector<std::string>& tag, 00272 std::vector<int>& start, std::vector<int>& num) 00273 { 00274 char comment[200]; FILE *fp; char inLine[100]; 00275 00276 // open the file 00277 if((fp = fopen(fName.c_str(),"rb")) == NULL) 00278 LFATAL("samples file: %s not found",fName.c_str()); 00279 LINFO("fName: %s",fName.c_str()); 00280 00281 // get number of samples 00282 int nSamples; if (fgets(inLine, 1000, fp) == NULL) LFATAL("fgets failed"); sscanf(inLine, "%d %s", &nSamples, comment); 00283 00284 // the number of categories 00285 int tNcat; if (fgets(inLine, 1000, fp) == NULL) LFATAL("fgets failed"); sscanf(inLine, "%d %s", &tNcat, comment); 00286 00287 // get the type of ground truth 00288 char gtOpt[100]; if (fgets(inLine, 1000, fp) == NULL) LFATAL("fgets failed"); sscanf(inLine, "%s %s", gtOpt, comment); 00289 00290 // skip column headers 00291 if (fgets(inLine, 1000, fp) == NULL) LFATAL("fgets failed"); 00292 00293 char cName[100]; char ext[100]; int cStart, cNum; int gTruth; 00294 while(fgets(inLine, 1000, fp) != NULL) 00295 { 00296 // get the files in this category and ground truth 00297 sscanf(inLine, "%s %d %d %d %s", cName, &cStart, &cNum, &gTruth, ext); 00298 LINFO(" sName: %s %d %d %d %s",cName, cStart, cNum, gTruth, ext); 00299 00300 tag.push_back(cName); 00301 start.push_back(cStart); 00302 num.push_back(cNum); 00303 } 00304 fclose(fp); 00305 } 00306 00307 // ###################################################################### 00308 // save the gist feature vector to a file 00309 void saveData(Image<double> data, std::string fName, int num) 00310 { 00311 // change the extension to .gist 00312 char temp[100]; char gName[100]; 00313 int tp = strcspn(fName.c_str(),"."); 00314 strncpy(temp, fName.c_str(), tp); temp[tp] = '\0'; 00315 //sprintf(gName,"%s_FFT_%03d%s", temp,num,".gist"); 00316 sprintf(gName,"%s_%03d%s", temp,num,".gist"); 00317 LINFO("gist file name: %s", gName); 00318 00319 // write the data to the gist file 00320 Image<double>::iterator aptr = data.beginw(); 00321 FILE *gfp; if((gfp = fopen(gName,"wb")) != NULL) 00322 { 00323 for(int i = 0; i < data.getSize(); i++) 00324 { double val = *aptr++; fwrite(&val, sizeof(double), 1, gfp); } 00325 fclose(gfp); 00326 } 00327 else LFATAL("can't write: %s", gName); 00328 } 00329 00330 // ###################################################################### 00331 /* So things look consistent in everyone's emacs... */ 00332 /* Local Variables: */ 00333 /* indent-tabs-mode: nil */ 00334 /* End: */ 00335