00001 /*!@file AppPsycho/gaborSearch.C */ 00002 // //////////////////////////////////////////////////////////////////// // 00003 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the // 00004 // University of Southern California (USC) and the iLab at USC. // 00005 // See http://iLab.usc.edu for information about this project. // 00006 // //////////////////////////////////////////////////////////////////// // 00007 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00008 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00009 // in Visual Environments, and Applications'' by Christof Koch and // 00010 // Laurent Itti, California Institute of Technology, 2001 (patent // 00011 // pending; application number 09/912,225 filed July 23, 2001; see // 00012 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00013 // //////////////////////////////////////////////////////////////////// // 00014 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00015 // // 00016 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00017 // redistribute it and/or modify it under the terms of the GNU General // 00018 // Public License as published by the Free Software Foundation; either // 00019 // version 2 of the License, or (at your option) any later version. // 00020 // // 00021 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00022 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00023 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00024 // PURPOSE. See the GNU General Public License for more details. // 00025 // // 00026 // You should have received a copy of the GNU General Public License // 00027 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00028 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00029 // Boston, MA 02111-1307 USA. // 00030 // //////////////////////////////////////////////////////////////////// // 00031 // 00032 // Primary maintainer for this file: Elnaz Nouri <enouri@usc.edu> 00033 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/AppPsycho/gaborSearch_elno.C $ 00034 // $Id: gaborSearch_elno.C 12962 2010-03-06 02:13:53Z irock $ 00035 // 00036 00037 //generate random search arrays of colored gabor patches using the gaborfilterRGB function 00038 00039 #include "Component/ModelManager.H" 00040 #include "GUI/XWinManaged.H" 00041 #include "Image/CutPaste.H" 00042 #include "Image/DrawOps.H" 00043 #include "Image/FourierEngine.H" 00044 #include "Image/Image.H" 00045 #include "Image/Kernels.H" // for gaborFilter() 00046 #include "Image/MathOps.H" 00047 #include "Image/ShapeOps.H" 00048 #include "Image/DrawOps.H" 00049 #include "Image/Transforms.H" 00050 #include "Raster/PngWriter.H" 00051 #include "Raster/Raster.H" 00052 #include "Util/FileUtil.H" 00053 #include "Util/log.H" 00054 #include <stdio.h> 00055 #include <algorithm> 00056 #include <time.h> 00057 00058 typedef std::complex<float> complexf; 00059 00060 //! Return a noise added version of inputImg 00061 Image<PixRGB<byte> > addNoise(const Image<PixRGB<byte> >& inputImg, int beta, float blendFactor, double *meanGray) 00062 { 00063 00064 //beta = 2 for random noise 00065 //beta = -2 pink(1/f) noise 00066 //beta = -4 brown noise 00067 00068 bool owned; 00069 FILE* x = stdOutputFileOpen("testnoise",&owned); 00070 FILE* y = stdOutputFileOpen("testnoise_v",&owned); 00071 Image< PixRGB<byte> > theInputImg = inputImg; 00072 int inputW = theInputImg.getWidth(), inputH = theInputImg.getHeight(), squareDim; 00073 LINFO("input image inputW = %d h = %d",inputW,inputH); 00074 complexf il(0.0, 1.0); 00075 00076 if(inputW > inputH) 00077 squareDim = inputW; 00078 else 00079 squareDim = inputH; 00080 00081 std::vector<float> u(squareDim*squareDim), v(squareDim*squareDim), spectrum(squareDim*squareDim),phi(squareDim*squareDim), resultVec(squareDim*squareDim); 00082 std::vector<complexf> sfRoot(squareDim*squareDim), cosPart(squareDim*squareDim), sinPart(squareDim*squareDim), cmplxResult(squareDim*squareDim); 00083 00084 Dims slightlyBigger ((squareDim*2)-1, squareDim); 00085 00086 FourierInvEngine<double> ieng(slightlyBigger); 00087 00088 int crnt = 0, v_cnt = 0; 00089 //create u and v vectors (matrix abstractions) where v = transpose of u 00090 00091 for(int i=0; i < squareDim/2; i++) 00092 { 00093 u[i] = i+1; 00094 crnt = crnt + 1; 00095 } 00096 00097 00098 for(int j = - squareDim/2; j < 0; j++) 00099 u[crnt++] = j; 00100 00101 for(int i=1; i<squareDim; i++) 00102 for(int j=0; j<squareDim; j++) 00103 { 00104 u[crnt++] = u[j]; 00105 v[v_cnt] = u[i-1]; 00106 v_cnt = v_cnt + 1; 00107 } 00108 00109 00110 for(int j=0; j<squareDim ;j++) 00111 { 00112 v[v_cnt] = u[squareDim-1]; 00113 v_cnt = v_cnt + 1; 00114 } 00115 00116 Image<std::complex<float> > tempCmplxImg(squareDim,squareDim,NO_INIT); 00117 Image <complexf>::iterator cmplxItr =tempCmplxImg.beginw(); 00118 00119 00120 00121 complexf tempcf; 00122 for(int i=0; i< (squareDim*squareDim); i++) 00123 { 00124 spectrum[i] = pow((u[i]*u[i]) + (v[i]*v[i]),(beta/2)); 00125 srand(time(NULL) + 10*i); 00126 phi[i] = ((double)rand()/((double)(RAND_MAX)+(double)(1)) ); 00127 sfRoot[i] = complexf(pow(spectrum[i],0.5),0.0); 00128 cosPart[i] = complexf(cos(2*M_PI*phi[i]), 0.0); 00129 sinPart[i] = complexf(sin(2*M_PI*phi[i]), 0.0); 00130 tempcf = (cosPart[i] + il*sinPart[i]); 00131 cmplxResult[i] = sfRoot[i]*tempcf ; 00132 *cmplxItr++ = cmplxResult[i]; 00133 00134 } 00135 00136 00137 crnt =0; 00138 for(int i=0; i<squareDim; i++) 00139 { fprintf(x,"\n"); 00140 for(int j=0; j<squareDim; j++) 00141 { 00142 fprintf(x,"\tu[%d]=%f",crnt,u[crnt]); 00143 crnt = crnt +1; 00144 } 00145 } 00146 00147 00148 Image<double> res = ieng.ifft(tempCmplxImg); 00149 Image <double>::iterator apItr = res.beginw(); 00150 00151 double imgMax,imgMin; 00152 getMinMax(res,imgMin,imgMax); 00153 00154 apItr = res.beginw(); 00155 00156 for(int i=0; i<slightlyBigger.w()*slightlyBigger.h(); i++) 00157 { 00158 *apItr = ((*apItr - imgMin)/(imgMax - imgMin))*255; 00159 apItr++; 00160 } 00161 00162 apItr = res.beginw(); 00163 crnt = 0; 00164 for(int i=0; i<squareDim; i++) 00165 { fprintf(y,"\n"); 00166 for(int j=0; j<squareDim; j++) 00167 { 00168 fprintf(y,"\tv[%d]=%f",crnt,v[crnt]); 00169 crnt = crnt +1; 00170 } 00171 } 00172 00173 *meanGray = mean(res); 00174 Image<PixRGB<byte> > resPixRGB = res; 00175 00176 resPixRGB = rescale(resPixRGB,Dims (inputW,inputH)); 00177 00178 LINFO("input image w = %d h = %d",resPixRGB.getWidth(),resPixRGB.getHeight()); 00179 00180 blendFactor=0; 00181 Image<PixRGB<byte> > resByte = theInputImg + resPixRGB*blendFactor; 00182 // Image<PixRGB<byte> > resByte = theInputImg + resPixRGB*blendFactor; 00183 00184 00185 fclose(x); 00186 fclose(y); 00187 return resByte; 00188 00189 } 00190 00191 00192 int main(int argc, char** argv) 00193 { 00194 00195 00196 clock_t t1= clock(); 00197 //instantiate a model manager 00198 ModelManager manager("AppPsycho: gabor search stimuli"); 00199 00200 //dimensions of window 00201 //Dims dims(1920,1080); 00202 Dims dims(1920,1080); 00203 00204 float stddev = 150.0; 00205 float freq = 5.0; 00206 float theta1 = 10; 00207 float hueShift= 5.0; 00208 float f,t,h; 00209 int gaborSize = 240; 00210 int n_gabors_w = dims.w()/gaborSize; 00211 int n_gabors_h = dims.h()/gaborSize; 00212 int totalGabors = n_gabors_w * n_gabors_h; 00213 char filename[255],fname[255]; 00214 00215 Image<PixRGB<byte> > dispImg(1920,1080,NO_INIT); 00216 00217 if (manager.parseCommandLine(argc, argv,"<name>", 1, 1) == false) 00218 return(1); 00219 00220 manager.start(); 00221 00222 // get command line parameters 00223 sscanf(argv[1],"%s",fname); 00224 00225 sprintf(filename, "/lab/elno/research/exp1/spec/%sSPEC.dat",fname); 00226 FILE* specFile = fopen(filename, "w+"); 00227 if(specFile==0) 00228 LFATAL("couldnt open file:%s", filename); 00229 00230 fprintf(specFile,"stddev = %g; freq = %g; theta = %g; hueShift = %g",stddev,freq,theta1,hueShift); 00231 00232 //make a 2d vector of images// 00233 00234 std::vector< Image<PixRGB<byte> > > ivector(totalGabors + 1); 00235 std::vector< Image<PixRGB<byte> > > jvector(totalGabors + 1); 00236 std::vector< Image<PixRGB<byte> > > constructArray(totalGabors + 1); 00237 std::vector<Point2D<int> > gaborItems(totalGabors + 1); //vector to hold xy coordinates of the gabor Patches 00238 std::vector<Point2D<int> > circleItems(totalGabors + 1); //vector to hold xy coordinates of the circle 00239 std::vector<Point2D<int> > randPos(totalGabors + 1); //vector to hold xy coordinates of the gabor Patches 00240 std::vector<int> used (totalGabors + 1); 00241 Dims standarddims(gaborSize,gaborSize); 00242 00243 srand(time(NULL)); 00244 //lets create some random positions 00245 int cnt =1; 00246 int yOffset =50; //yOffset required to compensate for the gaborSize/2 freespace 00247 for(int j = 1; j <= n_gabors_h; j++) 00248 for (int i = 1; i <= n_gabors_w; i++) 00249 { 00250 if(i>1 && i<n_gabors_w-1 && j>1 && j<n_gabors_h-1) 00251 randPos[cnt] = Point2D<int>((i*gaborSize-gaborSize) + 00252 (rand()*10)%(75),(j*gaborSize-gaborSize) + (rand()*10)%(75) + yOffset); 00253 else 00254 randPos[cnt] = Point2D<int>(i*gaborSize-gaborSize,j*gaborSize-gaborSize + yOffset); 00255 cnt++; 00256 } 00257 00258 00259 //create gabor patches and assign pseudorandom xy positions. 00260 00261 std::vector<int>::iterator result; 00262 srand(time(NULL)); 00263 int randIndex = rand() % totalGabors + 1; 00264 used.push_back(randIndex); 00265 result = used.end(); 00266 00267 00268 cnt=1; 00269 for(int j = 1; j <= n_gabors_h; j++) 00270 for (int i = 1; i <= n_gabors_w; i++) 00271 { 00272 00273 //frequencies can vary between 0.0075 and 0.0225 (0.0065-0.0075, and 0.0225-0.0250 reserved for post-training testing) 00274 f = ((rand()*(float(225-75)/RAND_MAX)) + 75)/10000; 00275 //orientation can vary between 15-75 deg (0-15 deg and 75-90 reserved for post-training testing) 00276 t = (rand()*(float(155-25)/RAND_MAX)) + 25; 00277 //hue shifts can vary between 0-360 00278 h = (rand()*(((float)360/RAND_MAX))); 00279 00280 00281 ivector[cnt] = Image<PixRGB<byte> >(gaborSize,gaborSize,NO_INIT); 00282 //drawDisk(constructArray[cnt], gaborItems[cnt]+gaborSize/2 ,gaborSize/4 , PixRGB<byte>(255,255, 0)); 00283 drawDisk(ivector[cnt], Point2D<int> (0,0)+gaborSize/2 ,gaborSize/3 , PixRGB<byte>(128,128,128)); 00284 00285 ivector[cnt] = rescale(ivector[cnt],standarddims); 00286 ivector[cnt] = ivector[cnt]+ rescale(gaborFilterRGB(stddev, f,t,h),standarddims); 00287 00288 // jvector[cnt] = gaborFilterRGB(stddev, f,t,h); 00289 // jvector[cnt] = rescale(ivector[cnt],standarddims); 00290 00291 00292 00293 00294 while(result!=used.end()) 00295 { 00296 srand(time(NULL)); 00297 randIndex = rand() % totalGabors + 1; 00298 result = find(used.begin(),used.end(),randIndex); 00299 } 00300 00301 used.push_back(randIndex); 00302 gaborItems[cnt] = randPos[randIndex]; 00303 fprintf(specFile,"\n\nGabor %d",cnt); 00304 fprintf(specFile,"\nXpos\t%d\nYpos\t%d\nstddev\t%.0f\nHueShift\t%.0f\nfrequency\t%f\nOrientation\t%.0f", 00305 gaborItems[cnt].i,gaborItems[cnt].j,stddev,h,f*1000,t); 00306 cnt++; 00307 } 00308 00309 00310 //lets paste the gabors into one big image 00311 cnt=1; 00312 for(int j = 1; j <= n_gabors_h; j++) 00313 for (int i = 1; i <= n_gabors_w; i++) 00314 { 00315 constructArray[cnt] = Image<PixRGB<byte> >(1920,1080,NO_INIT); 00316 //drawDisk(constructArray[cnt], gaborItems[cnt]+gaborSize/2 ,gaborSize/4 , PixRGB<byte>(255,255, 0)); 00317 inplacePaste(constructArray[cnt],ivector[cnt],gaborItems[cnt]); 00318 cnt++; 00319 } 00320 00321 //lets put them together 00322 for (int i=1; i < cnt; i++) 00323 dispImg = dispImg + constructArray[i]*1; 00324 00325 00326 00327 00328 //lets add some noise to the image and save it 00329 Image <PixRGB<byte> > myResult; 00330 00331 cnt=1; 00332 for(int j = 1; j <= n_gabors_h; j++) 00333 for (int i = 1; i <= n_gabors_w; i++) 00334 { 00335 //drawDisk(dispImg, gaborItems[cnt],gaborSize/2 , PixRGB<byte>(255,255, 0)); 00336 } 00337 00338 00339 double meanGray=0.0; 00340 myResult = addNoise(dispImg,-2,0.75, &meanGray); 00341 fprintf(specFile,"\nGray %f",meanGray); 00342 sprintf(filename, "/lab/elno/research/exp1/stim/%sARRAY.png",fname); 00343 00344 cnt=1; 00345 for(int j = 1; j <= n_gabors_h; j++) 00346 for (int i = 1; i <= n_gabors_w; i++) 00347 { 00348 //drawDisk(myResult, gaborItems[cnt],gaborSize/2 , PixRGB<byte>(255,255, 0)); 00349 } 00350 Raster::WriteRGB(myResult,filename); 00351 00352 //create save the target image 00353 00354 Image<double> target(1920,1080,ZEROS); 00355 Image<PixRGB<byte> > targetBkg(1920,1080,ZEROS); 00356 00357 srand(time(NULL)); 00358 randIndex = rand() % totalGabors + 1; 00359 fprintf(specFile,"\n\ntarget %d",randIndex); 00360 00361 inplacePaste(targetBkg, ivector[randIndex],Point2D<int>((1920/2)-(gaborSize/2),(1080/2)-(gaborSize/2))); 00362 Image<double>::iterator aptr= target.beginw(); 00363 00364 while(aptr!=target.endw()) 00365 *aptr++ = meanGray; 00366 00367 Image<PixRGB<byte> > targetRGB = target; 00368 targetRGB = targetRGB + targetBkg; 00369 00370 00371 // cnt=1; 00372 // for(int j = 1; j <= n_gabors_h; j++) 00373 // for (int i = 1; i <= n_gabors_w; i++) 00374 // {drawDisk(targetRGB, gaborItems[cnt],gaborSize/2 , PixRGB<byte>(0,0,0)); 00375 // } 00376 00377 00378 char targetFileName[255]; 00379 sprintf(targetFileName, "/lab/elno/research/exp1/stim/%sTARGET.png",fname); 00380 Raster::WriteRGB(targetRGB,targetFileName); 00381 00382 //create the screen for reporting position of target gabor 00383 00384 Image<PixRGB<byte> > reportDot(1920,1080,ZEROS); 00385 reportDot = target; 00386 00387 for(int i=1;i<=totalGabors;i++) 00388 { 00389 // drawDisk(reportDot, gaborItems[i]+(gaborSize/2), 10,PixRGB<byte>(255,255,255)); 00390 writeText(reportDot, gaborItems[i]+(gaborSize/2)-10, sformat("%d",i).c_str(), 00391 PixRGB<byte>(0,0,0),PixRGB<byte>(0),SimpleFont::FIXED(12) ,true); 00392 } 00393 00394 char reportDotFile[255]; 00395 sprintf(reportDotFile, "/lab/elno/research/exp1/stim/%sREPORT.png",fname); 00396 Raster::WriteRGB(reportDot, reportDotFile); 00397 00398 clock_t t2= clock(); 00399 LINFO("generated search array in %fs", double(t2-t1)/CLOCKS_PER_SEC); 00400 00401 fclose(specFile); 00402 //finish all 00403 manager.stop(); 00404 00405 return 0; 00406 00407 } 00408 00409 // ###################################################################### 00410 /* So things look consistent in everyone's emacs... */ 00411 /* Local Variables: */ 00412 /* indent-tabs-mode: nil */ 00413 /* End: */