00001 /*!@file CINNIC/CINNIC.C CINNIC classes */ 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: T Nathan Mundhenk <mundhenk@usc.edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/CINNIC/CINNIC.C $ 00035 // $Id: CINNIC.C 9412 2008-03-10 23:10:15Z farhan $ 00036 // 00037 00038 #include "CINNIC/CINNIC.H" 00039 00040 #include "Image/ColorOps.H" 00041 #include "Image/CutPaste.H" // for inplacePaste() 00042 #include "Image/Kernels.H" // for gaborFilter2() 00043 #include "Image/MathOps.H" 00044 #include "Image/Transforms.H" 00045 #include "Util/Timer.H" 00046 00047 #include <cmath> 00048 #include <fstream> 00049 00050 00051 // ###################################################################### 00052 //! Brute force, super inefficient 2D convolution (truncated filter boundary) 00053 /*! check for zero pixels and skip */ 00054 template <class T> static 00055 Image<typename promote_trait<T, float>::TP> 00056 convolveCleanZero(const Image<T>& src, const Image<float>& filter) 00057 { 00058 return convolveCleanZero(src, filter.getArrayPtr(), 00059 filter.getWidth(), filter.getHeight()); 00060 } 00061 00062 // ###################################################################### 00063 //! Brute force, super inefficient 2D convolution (truncated filter boundary) 00064 /*! check for zero pixels and skip */ 00065 template <class T> static 00066 Image<typename promote_trait<T, float>::TP> 00067 convolveCleanZero(const Image<T>& src, const float* filter, 00068 const int Nx, const int Ny) 00069 { 00070 ASSERT(src.initialized()); ASSERT((Nx & 1) && (Ny & 1)); 00071 const int w = src.getWidth(), h = src.getHeight(); 00072 // promote the source image to float if necessary, so that we do the 00073 // promotion only once for all, rather than many times as we access 00074 // the pixels of the image; if no promotion is necessary, "source" 00075 // will just point to the original data of "src" through the 00076 // copy-on-write/ref-counting behavior of Image: 00077 typedef typename promote_trait<T, float>::TP TF; 00078 const Image<TF> source = src; 00079 Image<TF> result(w, h, NO_INIT); 00080 typename Image<TF>::const_iterator sptr = source.begin(); 00081 typename Image<TF>::iterator dptr = result.beginw(); 00082 00083 int kkk = Nx * Ny - 1; 00084 int Nx2 = (Nx - 1) / 2, Ny2 = (Ny - 1) / 2; 00085 00086 const TF zero(0); 00087 00088 // very inefficient implementation; one has to be crazy to use non 00089 // separable filters anyway... 00090 for (int j = 0; j < h; ++j) 00091 for (int i = 0; i < w; ++i) 00092 { 00093 if((src.getVal(i,j) > 0.001F) || (src.getVal(i,j) < -0.001F)) 00094 { 00095 TF sum = TF(); float sumw = 0.0F; 00096 for (int kj = 0; kj < Ny; ++kj) 00097 { 00098 int kjj = kj + j - Ny2; 00099 if (kjj >= 0 && kjj < h) 00100 for (int ki = 0; ki < Nx; ++ki) 00101 { 00102 int kii = ki + i - Nx2; 00103 if (kii >= 0 && kii < w) 00104 { 00105 float fil = filter[kkk - ki - Nx*kj]; 00106 sum += sptr[kii + w * kjj] * fil; 00107 sumw += fil; 00108 } 00109 } 00110 } 00111 *dptr++ = sum / sumw; 00112 } 00113 else 00114 *dptr++ = zero; 00115 } 00116 return result; 00117 } 00118 00119 00120 // ############################################################ 00121 // ############################################################ 00122 // ##### ---CINNIC--- 00123 // ##### Contour Integration: 00124 // ##### T. Nathan Mundhenk nathan@mundhenk.com 00125 // ############################################################ 00126 // ############################################################ 00127 00128 void CINNIC::viewNeuronTemplate(ContourNeuronCreate<float> &NeuronTemplate 00129 ,readConfig &config) 00130 { 00131 00132 max = 0; 00133 min = 0; 00134 avg = 0; 00135 float maxhold = 0,minhold = 0,avghold = 0; 00136 int n = AnglesUsed*AnglesUsed; 00137 00138 for (int i = 0; i < AnglesUsed; i++) 00139 { 00140 for (int j = 0; j < AnglesUsed; j++) 00141 { 00142 output[i][j] = Image<float>(XSize+1,YSize+1, NO_INIT); 00143 for (int k = 0; k <= XSize; k++) 00144 { 00145 for (int l = 0; l <= YSize; l++) 00146 { 00147 output[i][j].setVal(k,l 00148 ,NeuronTemplate.FourDNeuralMap[i][j][k][l].angABD); 00149 } 00150 } 00151 getMinMaxAvg(output[i][j], min,max,avg); 00152 if(min < minhold){minhold = min;} //store total max value 00153 if(max > maxhold){maxhold = max;} //store total min value 00154 avghold += avg; //add to avg just for shits and grins 00155 } 00156 } 00157 Image<PixRGB<float> > theImage; 00158 theImage.resize(((XSize+1)*AnglesUsed),((YSize+1)*AnglesUsed)); 00159 00160 for (int i = 0; i < AnglesUsed; i++) 00161 { 00162 for (int j = 0; j < AnglesUsed; j++) 00163 { 00164 Poutput[i][j] = Image< PixRGB<float> >((XSize+1),(YSize+1), NO_INIT); 00165 Poutput[i][j] = normalizeRGPolar(output[i][j], max,min); 00166 inplacePaste(theImage, Poutput[i][j],Point2D<int>((i*XSize),(j*YSize))); 00167 //Raster::VisuRGB(Poutput[i][j], sformat("mask_out.%f.%f.ppm" 00168 // ,NeuralAngles[i],NeuralAngles[j])); 00169 00170 } 00171 } 00172 Raster::VisuRGB(theImage,"ANGLE_IMAGE.ppm"); 00173 avg = avghold/n; 00174 } 00175 00176 //***************************************************************** 00177 00178 void CINNIC::convolveTest(ContourNeuronCreate<float> &NeuronTemplate 00179 ,readConfig &config, Image<float> &testImage) 00180 { 00181 float total = 0.0F; 00182 float pos = 0.0F; 00183 float neg = 0.0F; 00184 int InspX, InspY; 00185 Image<float> output; 00186 output.resize(testImage.getWidth(),testImage.getHeight()); 00187 for(int x = 0; x < testImage.getWidth(); x++) 00188 { 00189 for(int y = 0; y < testImage.getHeight(); y++) 00190 { 00191 output.setVal(x,y,0); 00192 for (int k = 0; k <= XSize; k++) 00193 { 00194 for (int l = 0; l <= YSize; l++) 00195 { 00196 float temp; 00197 InspX = x + (k-(int)XCenter); 00198 InspY = y - (l-(int)YCenter); 00199 if((InspX >= 0) && (InspY >= 0) && (InspX < testImage.getWidth()) && 00200 (InspY < testImage.getHeight())) 00201 { 00202 temp = testImage.getVal(x,y)* 00203 testImage.getVal(InspX,InspY)* 00204 NeuronTemplate.FourDNeuralMap[0][0][k][l].angABD; 00205 float hold = output.getVal(x,y); 00206 hold += temp; 00207 output.setVal(x,y,hold); 00208 if(temp > 0) 00209 pos += temp; 00210 else 00211 neg += temp; 00212 total += temp; 00213 } 00214 } 00215 } 00216 } 00217 } 00218 LINFO("TOTAL VALUE IS %f, Pos %f, Neg %f",total,pos,neg); 00219 float pixTotal = 0.0F; 00220 for(int y = 0; y < testImage.getHeight(); y++) 00221 { 00222 for(int x = 0; x < testImage.getWidth(); x++) 00223 { 00224 if(output.getVal(x,y) > 0) 00225 { 00226 printf("%f ",output.getVal(x,y)); 00227 pixTotal += output.getVal(x,y); 00228 } 00229 else 00230 { 00231 printf("%f ",output.getVal(x,y)); 00232 } 00233 } 00234 printf("\n"); 00235 } 00236 LINFO("TOTAL PIX VALUE IS %f",pixTotal); 00237 } 00238 00239 //***************************************************************** 00240 00241 void CINNIC::configLoad(readConfig &config) 00242 { 00243 iterations = (int)config.getItemValueF("iterations"); 00244 edge = (int)config.getItemValueF("edgeAtten"); 00245 Amp = (int)config.getItemValueF("edgeAmp"); 00246 dev = config.getItemValueF("devMult"); 00247 cheatVal = (int)config.getItemValueF("cheatVal"); 00248 Gnum = (int)config.getItemValueF("Gnum"); 00249 cheatNum = (int)config.getItemValueF("cheatNum"); 00250 logto = config.getItemValueC("logOutDir"); 00251 saveto = config.getItemValueC("imageOutDir"); 00252 dumpImage = (int)config.getItemValueF("dumpImage"); 00253 redOrder = (int)config.getItemValueF("redOrder"); 00254 lPass = (int)config.getItemValueF("lPass"); 00255 reduction = (int)config.getItemValueF("reduction"); 00256 groupSize = (int)config.getItemValueF("groupSize"); 00257 scalesNumber = (int)config.getItemValueF("scalesNumber"); 00258 GroupTop = config.getItemValueF("GroupTop"); 00259 lastIterOnly = (int)config.getItemValueF("lastIterOnly"); 00260 addNoise = (int)config.getItemValueF("addNoise"); 00261 preOrientFilterNoise = config.getItemValueF("preOrientFilterNoise"); 00262 storeArraySize = (int)config.getItemValueF("storeArraySize"); 00263 BiasDiff = config.getItemValueF("BiasDiff"); 00264 GridBias = config.getItemValueF("GridBias"); 00265 doNerdCam = (int)config.getItemValueF("doNerdCam"); 00266 doBias = (int)config.getItemValueF("doBias"); 00267 doGaborFilter = (int)config.getItemValueF("doGaborFilter"); 00268 Gstddev = config.getItemValueF("Gstddev"); 00269 Gperiod = config.getItemValueF("Gperiod"); 00270 Gphase = config.getItemValueF("Gphase"); 00271 GsigMod = config.getItemValueF("GsigMod"); 00272 Gamplitude = config.getItemValueF("Gamplitude"); 00273 doTableOnly = (int)config.getItemValueF("doTableOnly"); 00274 compGain = config.getItemValueF("compGain"); 00275 scale1 = config.getItemValueF("scale1"); 00276 scale2 = config.getItemValueF("scale2"); 00277 scale3 = config.getItemValueF("scale3"); 00278 } 00279 00280 /*! This is a simple ramp (up then down) function to bias the 00281 oriented images from vertical 00282 filter more then horizontal filter. This is to adjust and create a linear 00283 function observed on Polat and Sagi Spat. Vis. 1994 00284 ALSO: add a bias for 45 degree angles due to the effect of the images 00285 grid shape. 00286 */ 00287 00288 void CINNIC::findNeuralAnglesBias() 00289 { 00290 int lastAngle = 0; 00291 for(int i = 0; i < AnglesUsed/2; i++) 00292 { 00293 NeuralAnglesBias[i] = 00294 1-((BiasDiff/(AnglesUsed/2))*((AnglesUsed/2)-i)); 00295 LINFO("BIAS1 %f",NeuralAnglesBias[i]); 00296 if(i <= (AnglesUsed/4)) 00297 NeuralAnglesBias[i] += (GridBias/(AnglesUsed/4))*i; 00298 else 00299 NeuralAnglesBias[i] += (GridBias/(AnglesUsed/4))*((AnglesUsed/2)-i); 00300 LINFO("BIAS2 %f",NeuralAnglesBias[i]); 00301 lastAngle++; 00302 } 00303 for(int i = lastAngle; i < AnglesUsed; i++) 00304 { 00305 NeuralAnglesBias[i] = 1-((BiasDiff/(AnglesUsed/2))*(i-(AnglesUsed/2))); 00306 LINFO("BIAS1 %f",NeuralAnglesBias[i]); 00307 if(i <= ((3*AnglesUsed)/4)) 00308 NeuralAnglesBias[i] += (GridBias/(AnglesUsed/4))*(i-(AnglesUsed/2)); 00309 else 00310 NeuralAnglesBias[i] += (GridBias/(AnglesUsed/4))*(AnglesUsed-i); 00311 LINFO("BIAS2 %f",NeuralAnglesBias[i]); 00312 } 00313 } 00314 00315 //***************************************************************** 00316 //***************************************************************** 00317 // START HERE 00318 //***************************************************************** 00319 //***************************************************************** 00320 00321 void CINNIC::RunSimpleImage(ContourNeuronCreate<float> &NeuronTemplate, 00322 Image<byte> &input, readConfig &config) 00323 { 00324 origX = input.getWidth();origY = input.getHeight(); 00325 orientComposite.resize(256,256,0.0F); 00326 Original = input; 00327 // Loads the config file for CINNIC params 00328 LINFO("LOAD CONFIG"); 00329 configLoad(config); 00330 std::ofstream outfile("CINNICtimer.log",std::ios::app); 00331 Timer tim; 00332 tim.reset(); 00333 // resize and do orientation filtering on input image 00334 LINFO("PRE-PROCESS IMAGE"); 00335 preProcessImage(NeuronTemplate,input,config); 00336 // set up image vectors and group sising 00337 LINFO("PRE-IMAGE"); 00338 preImage(VFinput,config,input.getWidth(),input.getHeight()); 00339 // actaully run the image for x number of iterations 00340 LINFO("RUN IMAGE"); 00341 runImage(NeuronTemplate,VFinput,config,groupTopVec); 00342 uint64 t0 = tim.get(); 00343 // get and output results 00344 LINFO("GET RESULTS"); 00345 getResults(config); 00346 00347 printf("\n*************************************\n"); 00348 printf("Time to convolve, %llums seconds\n",t0); 00349 printf("*************************************\n\n"); 00350 outfile << t0 << "\t"; 00351 outfile.close(); 00352 } 00353 00354 //***************************************************************** 00355 00356 void CINNIC::preProcessImage(ContourNeuronCreate<float> &NeuronTemplate 00357 ,Image<byte> &input,readConfig &config) 00358 { 00359 if(doGaborFilter == 0) 00360 { 00361 if((input.getWidth() > 256) || (input.getHeight() > 256)) 00362 input = rescale(input,256,256); 00363 } 00364 00365 floatImage = input; 00366 if(addNoise == 1) 00367 { 00368 LINFO("ADDING noise %f",preOrientFilterNoise); 00369 inplaceAddBGnoise2(input, preOrientFilterNoise); 00370 Raster::VisuGray(input, sformat("post_noise_image_in_%d.pgm", 0)); 00371 } 00372 00373 // Resize and filter image into oriented images 00374 00375 if(doBias == 1) 00376 findNeuralAnglesBias(); 00377 Finput.resize(AnglesUsed,input); 00378 VFinput.resize(scalesNumber,Finput); 00379 for(int i = 0; i < AnglesUsed; i++) 00380 { 00381 Finput[i] = Image<float>(input.getDims(),ZEROS); 00382 Finput[i] = input; // convert input to float 00383 Image<float> i2 = Finput[i]; 00384 if(redOrder == 0) 00385 { 00386 LINFO("REDUCTION USING decXY"); 00387 while(Finput[i].getWidth() > reduction) 00388 { 00389 Finput[i] = decXY(Finput[i]); 00390 } 00391 } 00392 00393 if(lPass == 0) 00394 { 00395 i2 = lowPass9(i2); 00396 Finput[i] -= i2; 00397 } 00398 if(lPass == 1) 00399 { 00400 i2 = lowPass5(i2); 00401 Finput[i] -= i2; 00402 } 00403 if(lPass == 2) 00404 { 00405 i2 = lowPass3(i2); 00406 Finput[i] -= i2; 00407 } 00408 00409 if(doGaborFilter == 0) 00410 { 00411 float mpi = M_PI / Gnum; 00412 Finput[i] = orientedFilter(Finput[i],mpi,NeuralAngles[i]); 00413 inplaceAttenuateBorders(Finput[i], edge); 00414 } 00415 else 00416 { 00417 LINFO("Using gabor filter"); 00418 // use this is you want accuracy, but not speed 00419 Gtheta = NeuralAngles[i]; 00420 Image<float> filter; 00421 filter = gaborFilter2<float>(Gstddev, 00422 Gperiod,Gphase,Gtheta, 00423 GsigMod,Gamplitude); 00424 // NOTE: added an extra 'i' at the end of sformat(), because 00425 // there were only three format parameters and the final %d was 00426 // unmatched. 00427 Raster::VisuFloat((filter+128),0, 00428 sformat("%s%s.filter_bias.image_%f_%d.pgm",saveto 00429 ,savefilename,NeuralAngles[i], i)); 00430 Finput[i] = convolveCleanZero(Finput[i],filter); 00431 // NOTE: added an extra 'i' at the end of sformat(), because 00432 // there were only three format parameters and the final %d was 00433 // unmatched. 00434 Raster::VisuFloat((Finput[i]+128),0, 00435 sformat("%s%s.pre_bias.image_%f_%d.pgm",saveto 00436 ,savefilename,NeuralAngles[i], i)); 00437 rescale(Finput[i],256,256); 00438 } 00439 Image<float> tempSizer = Finput[i]; 00440 rescale(tempSizer,256,256); // <--- FIX HERE 00441 orientComposite += tempSizer; 00442 if(doBias == 1) 00443 { 00444 LINFO("NEURALANGLEBIAS %f",NeuralAnglesBias[i]); 00445 for(int x = 0; x < Finput[i].getWidth(); x++) 00446 { 00447 for(int y = 0; y < Finput[i].getHeight(); y++) 00448 { 00449 Finput[i].setVal(x,y,(Finput[i].getVal(x,y)*NeuralAnglesBias[i])); 00450 } 00451 } 00452 } 00453 00454 // resize images into different scales 00455 00456 if(redOrder == 1) 00457 { 00458 int WHold = Finput[i].getWidth(); 00459 int HHold = Finput[i].getHeight(); 00460 while((WHold >= ImageSizeX) || (HHold >= ImageSizeY)) 00461 { 00462 WHold = WHold/2; 00463 HHold = HHold/2; 00464 } 00465 for(int s = 0; s < scalesNumber; s++) 00466 { 00467 VFinput[s][i] = Finput[i]; 00468 LINFO("Image Scale %d %d", WHold, HHold); 00469 VFinput[s][i] = rescale(VFinput[s][i], WHold,HHold); 00470 WHold = WHold/2; 00471 HHold = HHold/2; 00472 //uncomment this line to see all scale maps 00473 //Raster::VisuFloat(VFinput[s][i], FLOAT_NORM_0_255, sformat("%s%s.image_%f_%d_%d.pgm" 00474 // ,saveto,savefilename,NeuralAngles[i],s)); 00475 } 00476 } 00477 00478 //uncomment these three lines to view the oriented filter output 00479 //Raster::WriteGray(Finput[i], 00480 // sformat("%s%s.image_%f_%d.pgm",saveto,savefilename 00481 // ,NeuralAngles[i])); 00482 SY = Finput[i].getHeight(); 00483 SX = Finput[i].getWidth(); 00484 mean = ::mean(Finput[i]); 00485 std = ::stdev(Finput[i]); 00486 getMinMaxAvg(Finput[i], min,max,avg); 00487 } 00488 if(doGaborFilter == 1) 00489 { 00490 if((input.getWidth() > 256) || (input.getHeight() > 256)) 00491 input = rescale(input,256,256); 00492 } 00493 } 00494 00495 //***************************************************************** 00496 00497 void CINNIC::preImage(std::vector< std::vector<Image<float> > > &input 00498 ,readConfig &config,int sizeX, int sizeY) 00499 { 00500 orientComposite = (orientComposite/AnglesUsed)*compGain; 00501 SIZEX = sizeX; SIZEY = sizeY; 00502 Image<float> foo(SIZEX,SIZEY,ZEROS); 00503 group.resize(scalesNumber,foo); 00504 groupCount.resize(scalesNumber); 00505 groupTopVec.resize(scalesNumber); 00506 00507 contourRun *CR = new contourRun[scalesNumber](); 00508 00509 RN = CR; 00510 00511 combinedSalMap.resize(iterations,foo); 00512 combinedSalMapMax.resize(iterations,foo); 00513 combinedSalMapMin.resize(iterations,foo); 00514 //LINFO("Resizing combined sal map"); 00515 for(int i = 0; i < iterations; i++) 00516 { 00517 combinedSalMap[i] = Image<byte>(SIZEX,SIZEY,ZEROS); 00518 combinedSalMapMax[i] = Image<byte>(SIZEX,SIZEY,ZEROS); 00519 combinedSalMapMin[i] = Image<byte>(SIZEX,SIZEY,ZEROS); 00520 //LINFO("RESIZED %d:%d at %d",SIZEX,SIZEY,i); 00521 } 00522 00523 int GS = groupSize; 00524 int size = storeArraySize; 00525 00526 // size and label groups 00527 00528 for(int s = 0; s < scalesNumber; s++) 00529 { 00530 RN[s].setArraySize(size); 00531 size = size/4; 00532 if(s > 0) 00533 { 00534 GS = GS/2; 00535 } 00536 groupCount[s] = 0; 00537 groupTopVec[s] = GroupTop; 00538 GroupTop = GroupTop/4; 00539 00540 group[s] = Image<float>(input[s][0].getDims(),ZEROS); 00541 int Hmod,Wmod; 00542 int Wtemp = input[s][0].getWidth()/GS; 00543 if((Wmod = (input[s][0].getWidth()%GS)) != 0){Wtemp++;} 00544 int Htemp = input[s][0].getHeight()/GS; 00545 if((Hmod = (input[s][0].getHeight()%GS)) != 0){Htemp++;} 00546 00547 for(int x = 0; x < Wtemp; x++) 00548 { 00549 for(int y = 0; y < Htemp; y++) 00550 { 00551 for(int i = 0; i < GS; i++) 00552 { 00553 for(int j = 0; j < GS; j++) 00554 { 00555 int intx = i+(GS*x); 00556 int inty = j+(GS*y); 00557 if((intx < group[s].getWidth()) && (inty < group[s].getHeight())) 00558 { 00559 group[s].setVal(intx,inty,(float)groupCount[s]); 00560 } 00561 } 00562 } 00563 groupCount[s]++; 00564 } 00565 } 00566 } 00567 }; 00568 00569 //***************************************************************** 00570 00571 void CINNIC::runImage(ContourNeuronCreate<float> &NeuronTemplate, 00572 std::vector< std::vector<Image<float> > > &input 00573 ,readConfig &config, std::vector<float> >V) 00574 { 00575 //SIZEX = SIZEX * 2; // <--- FIX HERE 00576 //SIZEY = SIZEY * 2; // <--- FIX HERE 00577 Image<float> floatTemp; 00578 Image<float> floatTemp2; 00579 Image<byte> floatByte; 00580 Image<float> temp; 00581 Image<float> tempT; 00582 Image<float> temp2; 00583 Image<float> tempMax; 00584 Image<float> tempMin; 00585 char avgFileName[100]; 00586 sprintf(avgFileName,"%s%s.table.out.txt" 00587 ,saveto,savefilename); 00588 std::ofstream avgFile(avgFileName,std::ios::out); 00589 00590 //optimize this dammit!!!! 00591 for(int t = 0; t < iterations; t++) 00592 { 00593 floatTemp2 = Image<float>(SIZEX,SIZEY,ZEROS); 00594 temp2 = Image<float>(SIZEX,SIZEY,ZEROS); 00595 tempMax = Image<float>(SIZEX,SIZEY,ZEROS); 00596 tempMin = Image<float>(SIZEX,SIZEY,ZEROS); 00597 for(int s = 0; s < scalesNumber; s++) 00598 { 00599 // weighted average bias for scales output 00600 float bias; 00601 switch(s) 00602 { 00603 case 0: 00604 bias = scale1; 00605 break; 00606 case 1: 00607 bias = scale2; 00608 break; 00609 case 2: 00610 bias = scale3; 00611 break; 00612 default: 00613 bias = 1.0F; 00614 break; 00615 } 00616 00617 // ********************** 00618 // ** Do the fun stuff ** 00619 // ********************** 00620 // see: contourRun.* 00621 RN[s].contourRunMain(VFinput[s],NeuronTemplate,config,group[s], 00622 groupCount[s],t,GTV[s]); 00623 // ********************** 00624 // Post process results for this iteration 00625 00626 tempT = RN[s].getSMI(t); 00627 temp.resize(tempT.getWidth(),tempT.getHeight()); 00628 00629 // bump the sal map over a pixel 00630 for(int i = 0; i < tempT.getWidth(); i++) 00631 { 00632 for(int j = 0; j < tempT.getHeight(); j++) 00633 { 00634 if((j == 0) || (i == 0)) 00635 { 00636 temp.setVal(i,j,0); 00637 } 00638 else 00639 { 00640 temp.setVal(i,j,tempT.getVal(i-1,j-1)); 00641 } 00642 } 00643 } 00644 00645 floatTemp = rescale(temp,SIZEX,SIZEY); 00646 temp = rescale(temp,SIZEX,SIZEY); 00647 00648 00649 //set a bias for scales if needed in avg map 00650 for(int i = 1; i < temp.getWidth(); i++) 00651 { 00652 for(int j = 1; j < temp.getHeight(); j++) 00653 { 00654 float foo = temp.getVal(i,j)*bias; 00655 temp.setVal(i,j,foo); 00656 } 00657 } 00658 if(t == (iterations - 1)) 00659 { 00660 for(int i = 0; i < floatTemp.getWidth(); i++) 00661 { 00662 for(int j = 0; j < floatTemp.getHeight(); j++) 00663 { 00664 float foo = floatTemp.getVal(i,j)*bias; 00665 floatTemp.setVal(i,j,foo); 00666 } 00667 } 00668 floatByte = floatTemp; 00669 if(doTableOnly == 0) 00670 { 00671 Raster::WriteGray(floatByte, 00672 sformat("%s%s.minimum.out.%d.pgm" 00673 ,saveto,savefilename,s)); 00674 } 00675 floatTemp2 += floatTemp; 00676 } 00677 00678 //set min or max for each scale 00679 //reset min matrix 00680 for(int i = 0; i < temp.getWidth(); i++) 00681 { 00682 for(int j = 0; j < temp.getHeight(); j++) 00683 { 00684 tempMin.setVal(i,j,255); 00685 } 00686 } 00687 00688 for(int i = 0; i < temp.getWidth(); i++) 00689 { 00690 for(int j = 0; j < temp.getHeight(); j++) 00691 { 00692 if(temp.getVal(i,j) > tempMax.getVal(i,j)) 00693 { 00694 //set max pixel 00695 tempMax.setVal(i,j,temp.getVal(i,j)); 00696 } 00697 if(temp.getVal(i,j) < tempMin.getVal(i,j)) 00698 { 00699 tempMin.setVal(i,j,temp.getVal(i,j)); 00700 } 00701 } 00702 } 00703 temp2+=temp; 00704 } 00705 00706 //divide image by group numbers so that the output fits in 256 greys 00707 double mint; 00708 00709 if(t == (iterations - 1)) 00710 { 00711 avgFile << floatTemp2.getWidth() << "\t" << floatTemp2.getHeight() << "\n"; 00712 for(int i = 0; i < floatTemp2.getWidth(); i++) 00713 { 00714 for(int j = 0; j < floatTemp2.getHeight(); j++) 00715 { 00716 mint = floatTemp2.getVal(i,j)/scalesNumber; 00717 avgFile << mint << "\t"; 00718 floatTemp2.setVal(i,j,mint); 00719 } 00720 avgFile << "\n"; 00721 } 00722 floatByte = floatTemp2; 00723 if(doTableOnly == 0) 00724 { 00725 Raster::WriteGray(floatByte, 00726 sformat("%s%s.minimumSize.out.pgm" 00727 ,saveto,savefilename)); 00728 } 00729 } 00730 00731 for(int i = 0; i < temp2.getWidth(); i++) 00732 { 00733 for(int j = 0; j < temp2.getHeight(); j++) 00734 { 00735 mint = temp2.getVal(i,j)/scalesNumber; 00736 temp2.setVal(i,j,mint); 00737 } 00738 } 00739 int xx = temp2.getWidth(); 00740 int yy = temp2.getHeight(); 00741 combinedSalMap[t] = temp2; 00742 combinedSalMapMax[t] = tempMax; 00743 combinedSalMapMin[t] = tempMin; 00744 if(((lastIterOnly == 0) || (t == (iterations - 1))) && (doTableOnly == 0)) 00745 { 00746 //Raster::VisuGray(combinedSalMap[t],sformat("combined_map_%d.pgm",t)); 00747 if(doNerdCam == 1) 00748 { 00749 combinedSalMap[t] = rescale(combinedSalMap[t],origX,origY); 00750 Image<float> nerd; 00751 nerd = combinedSalMap[t]; 00752 char savename[100]; 00753 sprintf(savename,"%s%s.sal.out.%d.%d.%d.%d",saveto,savefilename 00754 ,0,t,xx,yy); 00755 cinnicStats.pointAndFloodImage(Original,nerd,6,savename,24.0F,48.0F); 00756 inplaceNormalize(combinedSalMap[t], byte(0), byte(255)); 00757 } 00758 00759 Raster::WriteRGB(Image<PixRGB<byte> >(combinedSalMap[t]) 00760 ,sformat("%s%s.avg.out.%d.%d.%d.%d.ppm" 00761 ,saveto,savefilename,0,t,xx,yy)); 00762 00763 if(doNerdCam == 0) 00764 { 00765 //Raster::WriteRGB(Image<PixRGB<byte> >(combinedSalMap[t]+orientComposite) 00766 // ,sformat("%s%s.Compavg.out.%d.%d.%d.%d.ppm" 00767 // ,saveto,savefilename,0,t,xx,yy)); 00768 00769 //Raster::VisuGray(combinedSalMapMax[t],sformat("max_map_%d.pgm",t)); 00770 Raster::WriteRGB(Image<PixRGB<byte> >(combinedSalMapMax[t]) 00771 ,sformat("%s%s.max.out.%d.%d.%d.%d.ppm" 00772 ,saveto,savefilename,0,t,xx,yy)); 00773 00774 //Raster::VisuGray(combinedSalMapMin[t],sformat("min_map_%d.pgm",t)); 00775 Raster::WriteRGB(Image<PixRGB<byte> >(combinedSalMapMin[t]) 00776 ,sformat("%s%s.min.out.%d.%d.%d.%d.ppm" 00777 ,saveto,savefilename,0,t,xx,yy)); 00778 Image<float> floatTempT; 00779 } 00780 } 00781 } 00782 std::ofstream propFile("CINNIC2.prop",std::ios::out); 00783 propFile << "type avg\n"; 00784 propFile << "type max\n"; 00785 propFile << "type min\n"; 00786 propFile.close(); 00787 avgFile.close(); 00788 }; 00789 00790 void CINNIC::getResults(readConfig &config) 00791 { 00792 00793 for(int i = 0; i < scalesNumber; i++) 00794 { 00795 LINFO("DUMPING ENERGY MAP"); 00796 char holder[256]; 00797 strcpy(holder,logto); 00798 RN[i].dumpEnergySigmoid(strcat(holder,"energy"), 00799 savefilename,config,floatImage,i,scalesNumber); 00800 LINFO("Unique iterations at scale %d = %ld",i,RN[i].iterCounter); 00801 } 00802 LINFO("FINISHED"); 00803 }; 00804 00805 // ###################################################################### 00806 /* So things look consistent in everyone's emacs... */ 00807 /* Local Variables: */ 00808 /* indent-tabs-mode: nil */ 00809 /* End: */