00001 /*!@file AppPsycho/flyOver.C simulates a fly over satalite images 00002 */ 00003 00004 // //////////////////////////////////////////////////////////////////// // 00005 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the // 00006 // University of Southern California (USC) and the iLab at USC. // 00007 // See http://iLab.usc.edu for information about this project. // 00008 // //////////////////////////////////////////////////////////////////// // 00009 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00010 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00011 // in Visual Environments, and Applications'' by Christof Koch and // 00012 // Laurent Itti, California Institute of Technology, 2001 (patent // 00013 // pending; application number 09/912,225 filed July 23, 2001; see // 00014 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00015 // //////////////////////////////////////////////////////////////////// // 00016 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00017 // // 00018 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00019 // redistribute it and/or modify it under the terms of the GNU General // 00020 // Public License as published by the Free Software Foundation; either // 00021 // version 2 of the License, or (at your option) any later version. // 00022 // // 00023 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00024 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00025 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00026 // PURPOSE. See the GNU General Public License for more details. // 00027 // // 00028 // You should have received a copy of the GNU General Public License // 00029 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00030 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00031 // Boston, MA 02111-1307 USA. // 00032 // //////////////////////////////////////////////////////////////////// // 00033 // 00034 // Primary maintainer for this file: T. Nathan Mundhenk <mundhenk@usc.edu> 00035 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/AppPsycho/flyOver.C $ 00036 // $Id: flyOver.C 7157 2006-09-15 07:55:58Z itti $ 00037 // 00038 #include "GUI/XWindow.H" 00039 #include "Raster/Raster.H" 00040 #include "Util/Assert.H" 00041 #include "Util/Timer.H" 00042 #include "Util/log.H" 00043 #include "Image/Image.H" 00044 #include "Image/Pixels.H" 00045 00046 #include <fstream> 00047 #include <iostream> 00048 #include <math.h> 00049 #include <string> 00050 #include <vector> 00051 00052 using namespace std; 00053 00054 //********************************************************************** 00055 class projectIO 00056 { 00057 private: 00058 unsigned int inputX, inputY; 00059 // nested vector class container, this one holds integers 00060 std::vector<std::vector<int> > inputData; 00061 public: 00062 projectIO(); 00063 ~projectIO(); 00064 // Read in a project file 00065 std::vector<std::vector<int> > readFile(string infile); 00066 }; 00067 00068 //********************************************************************** 00069 projectIO::projectIO() 00070 {} 00071 00072 //********************************************************************** 00073 projectIO::~projectIO() 00074 {} 00075 00076 //********************************************************************** 00077 /* This is a blind file reader. While we can compute the file size on the 00078 fly by checking for EOL, this makes the file size explicite and readable. 00079 In general, it really doesn't matter which way its done. 00080 */ 00081 std::vector<std::vector<int> > projectIO::readFile(string infile) 00082 { 00083 00084 std::cerr << "Reading in file " << infile << "\n"; 00085 // Create a file handle and open a file for reading 00086 ifstream inputFile(infile.c_str(), ios::in); 00087 unsigned int marker = 0; 00088 string in, inX, inY, size; 00089 00090 // read in the first two tokens as a height 00091 // and width of this matrix 00092 // (1) atoi converts the char to an integer 00093 // (2) c_str() gets a char from a string 00094 inputFile >> inX >> inY >> size; 00095 // The X size of the matrix file 00096 inputX = 4; 00097 // The Y size of the matrix file 00098 inputY = atoi(size.c_str()); 00099 // resize the vector container 00100 std::vector<int> filler(inputY+2,0); 00101 inputData.resize(inputX,filler); 00102 00103 inputData[0][0] = atoi(inX.c_str()); 00104 inputData[1][0] = atoi(inY.c_str()); 00105 inputData[0][1] = atoi(size.c_str()); 00106 00107 // While not end of file, place each white space 00108 // seperated token into a string 00109 while(inputFile >> in) 00110 { 00111 // for each token, place it in the vector 00112 // at its X and Y position 00113 unsigned int currentX = marker % inputX; 00114 unsigned int currentY = marker / inputX; 00115 inputData[currentX][currentY+2] = atoi(in.c_str()); 00116 marker++; 00117 } 00118 00119 inputFile.close(); 00120 return inputData; 00121 } 00122 00123 //********************************************************************** 00124 00125 int main(const int argc, const char **argv) 00126 { 00127 00128 if(argc < 2) 00129 std::cerr << "USAGE: flyOver image.png path_file.txt\n"; 00130 string satImageFile = argv[1]; 00131 //string movieFile = argv[2]; 00132 string infile = argv[2]; 00133 uint fsizex, fsizey, tpoints; 00134 uint sizex,sizey; 00135 uint frameNumber = 0; 00136 00137 projectIO proj; 00138 std::vector<std::vector<int> > inputData; 00139 inputData = proj.readFile(infile); 00140 00141 Image<PixRGB<float> > satImage; 00142 00143 fsizex = inputData[0][0]; 00144 fsizey = inputData[1][0]; 00145 tpoints = inputData[0][1]; 00146 00147 std::cout << "Image Frame size (x,y) " << fsizex 00148 << " x " << fsizey 00149 << "\n" 00150 << "Travel Points " << tpoints 00151 << "\n"; 00152 00153 for(uint i = 0; i < tpoints; i++) 00154 { 00155 // center the frame 00156 inputData[0][i+2] = inputData[0][i+2] - (int)floor(fsizex/2); 00157 inputData[1][i+2] = inputData[1][i+2] - (int)floor(fsizey/2); 00158 00159 cout << "(" << inputData[0][i+2] << "," << inputData[1][i+2] << ")" 00160 << " Speed (pixels per frame) " << inputData[2][i+2] 00161 << " Ramp (frames) " << inputData[3][i+2] 00162 << "\n"; 00163 } 00164 00165 std::cerr << "READING IN SATALITE IMAGE\n" 00166 << "Depending on image size, this may take a while\n"; 00167 satImage = Raster::ReadRGB(satImageFile.c_str(), RASFMT_PNG); 00168 std::cerr << "Done\n"; 00169 00170 sizex = satImage.getWidth(); 00171 sizey = satImage.getHeight(); 00172 00173 std::cout << "Sat image size (" << sizex << "," << sizey << ")\n"; 00174 Image<PixRGB<float> > frame; 00175 frame.resize(fsizex,fsizey); 00176 for(uint i = 0; i < tpoints - 1; i++) 00177 { 00178 const float distx = inputData[0][i+2] - inputData[0][i+3]; 00179 const float disty = inputData[1][i+2] - inputData[1][i+3]; 00180 const float dist = sqrt(distx*distx + disty+disty); 00181 const float speed = inputData[2][i+2]; 00182 const float accel = inputData[3][i+2]; 00183 const float frames = dist/speed; 00184 float currx = inputData[0][i+2]; 00185 float curry = inputData[1][i+2]; 00186 //! current speed 00187 float currsp = 0; 00188 //! How far to travel so far 00189 float dtot = dist; 00190 //! at what point to begin to slow down (ramp function) 00191 //float slow = floor(((accel*(speed + 1))/(2*accel))*speed); 00192 // approx how far we are out when we need to begin to stop 00193 const float slow = floor(((0.5F + (speed/accel)) * 00194 (speed + (accel/2)))/2); 00195 float ndec = 0; 00196 bool stop = false; 00197 bool doStop = false; 00198 00199 std::cerr << "Position (" << currx << "," << curry << ")" 00200 << "Approx frames " << frames << "\n"; 00201 00202 // while we are one or more pixel from the target 00203 while(!stop) 00204 { 00205 uint fcurrx = (int)floor(currx); 00206 uint fcurry = (int)floor(curry); 00207 std::cerr << "Pos: " << fcurrx << "," << fcurry 00208 << " Spd: " << currsp 00209 << " Dst: " << dtot << "\n"; 00210 // from this position, get the current frame 00211 for(uint x = fcurrx; x < fcurrx + fsizex; x++) 00212 { 00213 for(uint y = fcurry; y < fcurry + fsizey; y++) 00214 { 00215 PixRGB<float> pix = satImage.getVal(x,y); 00216 frame.setVal(x - fcurrx,y - fcurry,pix); 00217 } 00218 } 00219 00220 // check to see if we need to slow down 00221 if(dtot < slow+speed) 00222 { 00223 if(!doStop) 00224 { 00225 // figure out decelleration from current position 00226 ndec = speed/(((2*dtot)/(speed + accel/2))-0.5F); 00227 doStop = true; 00228 } 00229 else 00230 { 00231 currsp = currsp - ndec; 00232 if(currsp < 1) 00233 currsp = 1; 00234 } 00235 } 00236 // else if we are below full speed, speed up 00237 else if(currsp < speed) 00238 { 00239 currsp = currsp + accel; 00240 if(currsp > speed) currsp = speed; 00241 } 00242 00243 // compute new x and new y based on distance to travel and 00244 // trajectory 00245 float ratio = disty/distx; 00246 00247 float movex = sqrt((currsp*currsp)/(1+(ratio*ratio))); 00248 float movey = fabs(ratio*movex); 00249 00250 // compute new x coord 00251 if(distx < 0) 00252 { 00253 currx = currx + movex; 00254 if(currx > inputData[0][i+3]) 00255 stop = true; 00256 } 00257 else 00258 { 00259 currx = currx - movex; 00260 if(currx < inputData[0][i+3]) 00261 stop = true; 00262 } 00263 00264 // compute new y coord 00265 if(disty < 0) 00266 { 00267 curry = curry + movey; 00268 if(curry > inputData[1][i+3]) 00269 stop = true; 00270 } 00271 else 00272 { 00273 curry = curry - movey; 00274 if(curry < inputData[1][i+3]) 00275 stop = true; 00276 } 00277 00278 // compute how much further we have to go 00279 float ndistx = currx - inputData[0][i+3]; 00280 float ndisty = curry - inputData[1][i+3]; 00281 dtot = sqrt(ndistx*ndistx + ndisty*ndisty); 00282 00283 // get the string for this frame 00284 char c[100]; 00285 string a = "frame"; 00286 string b = "."; 00287 if(frameNumber < 10) 00288 sprintf(c,"00000%d",frameNumber); 00289 else if(frameNumber < 100) 00290 sprintf(c,"0000%d",frameNumber); 00291 else if(frameNumber < 1000) 00292 sprintf(c,"000%d",frameNumber); 00293 else if(frameNumber < 10000) 00294 sprintf(c,"00%d",frameNumber); 00295 else if(frameNumber < 100000) 00296 sprintf(c,"0%d",frameNumber); 00297 else 00298 sprintf(c,"%d",frameNumber); 00299 string Myname = a + b + c; 00300 Raster::WriteRGB(frame,Myname,RASFMT_PNM); 00301 frameNumber++; 00302 } 00303 } 00304 } 00305 00306 00307 00308 00309 00310 00311 00312 00313