00001 /*!@file Neuro/ScaleSurpriseControl.C attempt to remove surprise from 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: T. Nathan Mundhenk <mundhenk@usc.edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Neuro/ScaleSurpriseControl.C $ 00035 // $Id: ScaleSurpriseControl.C 10845 2009-02-13 08:49:12Z itti $ 00036 // 00037 00038 #ifndef SCALE_SURPRISE_CONTROL_C_DEFINED 00039 #define SCALE_SURPRISE_CONTROL_C_DEFINED 00040 00041 #include "Neuro/ScaleSurpriseControl.H" 00042 #include "Image/ColorOps.H" 00043 00044 /*************************************************************************/ 00045 00046 template <class FLOAT> 00047 ScaleSurpriseControl<FLOAT>::ScaleSurpriseControl(const ushort sizeX, 00048 const ushort sizeY, 00049 const string confFile) 00050 { 00051 itsLevelSpecSet = false; 00052 SSCreadConfig(confFile); 00053 SSCinit(sizeX,sizeY); 00054 } 00055 00056 /*************************************************************************/ 00057 00058 template <class FLOAT> 00059 ScaleSurpriseControl<FLOAT>::ScaleSurpriseControl() 00060 { 00061 itsLevelSpecSet = false; 00062 } 00063 00064 /*************************************************************************/ 00065 00066 template <class FLOAT> 00067 ScaleSurpriseControl<FLOAT>::~ScaleSurpriseControl() 00068 {} 00069 00070 /*************************************************************************/ 00071 template <class FLOAT> inline 00072 void ScaleSurpriseControl<FLOAT>::SSCsetLevelSpecInfo(const uint levMin, 00073 const uint levMax, 00074 const uint delMin, 00075 const uint delMax, 00076 const uint mapLevel, 00077 const uint maxIndex, 00078 const uint maxDepth) 00079 { 00080 itsLevMin = static_cast<ushort>(levMin); 00081 itsLevMax = static_cast<ushort>(levMax); 00082 itsDelMin = static_cast<ushort>(delMin); 00083 itsDelMax = static_cast<ushort>(delMax); 00084 itsMapLevel = static_cast<ushort>(mapLevel); 00085 itsMaxIndex = static_cast<ushort>(maxIndex); 00086 itsMaxDepth = static_cast<ushort>(maxDepth); 00087 00088 itsLevelSpecSet = true; 00089 } 00090 00091 /*************************************************************************/ 00092 template <class FLOAT> 00093 void ScaleSurpriseControl<FLOAT>::SSCreadConfig(const string confFile) 00094 { 00095 LINFO("Reading config file %s",confFile.c_str()); 00096 itsReadConfig.openFile(confFile.c_str()); 00097 00098 // get basic information and biases 00099 itsAxisBiasX = itsReadConfig.getItemValueF("itsAxisBiasX"); 00100 itsAxisBiasY = itsReadConfig.getItemValueF("itsAxisBiasY"); 00101 itsAxisBiasZ = itsReadConfig.getItemValueF("itsAxisBiasZ"); 00102 00103 itsConspicMapBias[SC_DR0] = itsReadConfig.getItemValueF("itsDRConBias0"); 00104 itsConspicMapBias[SC_DR1] = itsReadConfig.getItemValueF("itsDRConBias1"); 00105 itsConspicMapBias[SC_DR2] = itsReadConfig.getItemValueF("itsDRConBias2"); 00106 itsConspicMapBias[SC_DR3] = itsReadConfig.getItemValueF("itsDRConBias3"); 00107 00108 itsConspicMapBias[SC_GA0] = itsReadConfig.getItemValueF("itsGAConBias0"); 00109 itsConspicMapBias[SC_GA1] = itsReadConfig.getItemValueF("itsGAConBias1"); 00110 itsConspicMapBias[SC_GA2] = itsReadConfig.getItemValueF("itsGAConBias2"); 00111 itsConspicMapBias[SC_GA3] = itsReadConfig.getItemValueF("itsGAConBias3"); 00112 00113 itsConspicMapBias[SC_IN] = itsReadConfig.getItemValueF("itsINConBias"); 00114 itsConspicMapBias[SC_FL] = itsReadConfig.getItemValueF("itsFLConBias"); 00115 itsConspicMapBias[SC_RG] = itsReadConfig.getItemValueF("itsRGConBias"); 00116 itsConspicMapBias[SC_BY] = itsReadConfig.getItemValueF("itsBYConBias"); 00117 00118 itsConspicMapBias[SC_H1] = itsReadConfig.getItemValueF("itsH1ConBias"); 00119 itsConspicMapBias[SC_H2] = itsReadConfig.getItemValueF("itsH2ConBias"); 00120 itsConspicMapBias[SC_HS] = itsReadConfig.getItemValueF("itsHSConBias"); 00121 itsConspicMapBias[SC_HV] = itsReadConfig.getItemValueF("itsHVConBias"); 00122 00123 itsLambda = itsReadConfig.getItemValueF("itsLambda"); 00124 itsStdSize = itsReadConfig.getItemValueF("itsStdSize"); 00125 itsZSigma = itsReadConfig.getItemValueF("itsZSigma"); 00126 itsUseMaxLevel = itsReadConfig.getItemValueB("itsUseMaxLevel"); 00127 itsH1Bias = itsReadConfig.getItemValueF("itsH1Bias"); 00128 itsH2Bias = itsReadConfig.getItemValueF("itsH2Bias"); 00129 itsSBias = itsReadConfig.getItemValueF("itsSBias"); 00130 itsVBias = itsReadConfig.getItemValueF("itsVBias"); 00131 00132 itsOriginalImageWeight = 00133 itsReadConfig.getItemValueF("itsOriginalImageWeight"); 00134 00135 itsMasterConspicBias = 00136 itsReadConfig.getItemValueF("itsMasterConspicBias"); 00137 00138 itsSharpFactorH1 = 00139 itsReadConfig.getItemValueF("itsSharpFactorH1"); 00140 itsSharpFactorH2 = 00141 itsReadConfig.getItemValueF("itsSharpFactorH2"); 00142 itsSharpFactorS = 00143 itsReadConfig.getItemValueF("itsSharpFactorS"); 00144 itsSharpFactorV = 00145 itsReadConfig.getItemValueF("itsSharpFactorV"); 00146 00147 itsGetReduced = 00148 itsReadConfig.getItemValueB("itsGetReduced"); 00149 00150 itsUseAndersonSeperable = 00151 itsReadConfig.getItemValueB("itsUseAndersonSeperable"); 00152 00153 itsUseTemporal = 00154 itsReadConfig.getItemValueB("itsUseTemporal"); 00155 00156 itsNormalizeBiasWithScale = 00157 itsReadConfig.getItemValueB("itsNormalizeBiasWithScale"); 00158 00159 itsBaseFilterSize = (ushort)itsReadConfig.getItemValueF("itsBaseFilterSize"); 00160 00161 00162 // get LevelSpec information from file if not already supplied 00163 if(!itsLevelSpecSet) 00164 { 00165 LINFO("NOTICE: Setting LevelSpec info from config file"); 00166 itsLevMin = (ushort)itsReadConfig.getItemValueF("itsLevMin"); 00167 itsLevMax = (ushort)itsReadConfig.getItemValueF("itsLevMax"); 00168 itsDelMin = (ushort)itsReadConfig.getItemValueF("itsDelMin"); 00169 itsDelMax = (ushort)itsReadConfig.getItemValueF("itsDelMax"); 00170 itsMapLevel = (ushort)itsReadConfig.getItemValueF("itsMapLevel"); 00171 itsMaxIndex = (ushort)itsReadConfig.getItemValueF("itsMaxIndex"); 00172 itsMaxDepth = (ushort)itsReadConfig.getItemValueF("itsMaxDepth"); 00173 00174 itsLevelSpecSet = true; 00175 } 00176 itsScaleBias.resize(itsMaxIndex,0.0F); 00177 00178 std::string baseScale = "itsScaleBias_"; 00179 00180 // read in each scale bias 00181 for(ushort i = 0; i < itsMaxIndex; i++) 00182 { 00183 char temp[100]; 00184 sprintf(temp,"%s%d",baseScale.c_str(),i); 00185 itsScaleBias[i] = itsReadConfig.getItemValueF(static_cast<string>(temp)); 00186 } 00187 00188 itsScalePower.resize(itsMaxIndex,0.0F); 00189 baseScale = "itsScalePower_"; 00190 00191 // read in each scale power 00192 for(ushort i = 0; i < itsMaxIndex; i++) 00193 { 00194 char temp[100]; 00195 sprintf(temp,"%s%d",baseScale.c_str(),i); 00196 itsScalePower[i] = itsReadConfig.getItemValueF(static_cast<string>(temp)); 00197 } 00198 } 00199 00200 /*************************************************************************/ 00201 00202 template <class FLOAT> 00203 void ScaleSurpriseControl<FLOAT>::SSCinit(const ushort sizeX, 00204 const ushort sizeY) 00205 { 00206 LINFO("INIT"); 00207 00208 if(!itsLevelSpecSet) 00209 LFATAL("LevelSpec not yet set. It must be set before calling init"); 00210 00211 itsFrameCounter = 0; 00212 00213 itsImageSizeX = sizeX; 00214 itsImageSizeY = sizeY; 00215 00216 // create a SurpriseControl for each scale 00217 LINFO("Creating temp object"); 00218 SurpriseControl<PIX_H2SV_TYPE<FLOAT>,PixHyper<FLOAT,SC_MAX_CHANNELS>,FLOAT> 00219 tempSC(sizeX,sizeY); 00220 itsSurpriseControl.resize(itsMaxIndex,tempSC); 00221 itsFinalImage.resize(sizeX,sizeY); 00222 00223 itsImageSizesX.resize(itsMaxIndex,0); 00224 itsImageSizesY.resize(itsMaxIndex,0); 00225 itsFilterSizesX.resize(itsMaxIndex,0); 00226 itsFilterSizesY.resize(itsMaxIndex,0); 00227 itsFilterSizesZ.resize(itsMaxIndex,0); 00228 itsResultImages.resize(itsMaxIndex,itsFinalImage); 00229 00230 itsImageBaseX = itsImageSizeX/(ushort)(pow(2.0F,(FLOAT)itsLevMin)); 00231 itsImageBaseY = itsImageSizeY/(ushort)(pow(2.0F,(FLOAT)itsLevMin)); 00232 00233 LINFO("Base Image Size %d x %d",itsImageBaseX,itsImageBaseY); 00234 00235 uint indx = 0; 00236 00237 // determine the pyramid sizes used and store 00238 // also determin how large the feature filter would be on a non-reduced image 00239 LINFO("Setting up filters"); 00240 for(ushort i = 0; i < (itsDelMax - itsDelMin + 1); i++) 00241 { 00242 ushort bx = itsImageBaseX; 00243 ushort by = itsImageBaseY; 00244 FLOAT fz = itsZSigma; 00245 for(ushort j = 0; j < (itsLevMax - itsLevMin + 1); j++) 00246 { 00247 itsImageSizesX[indx] = bx; 00248 itsFilterSizesX[indx] = (ushort)round(((FLOAT)itsBaseFilterSize/ 00249 (FLOAT)itsImageSizesX[indx]) * 00250 (FLOAT)itsImageSizeX); 00251 LINFO("%d : Filter Size X %d",indx,itsFilterSizesX[indx]); 00252 itsImageSizesY[indx] = by; 00253 itsFilterSizesY[indx] = (ushort)round(((FLOAT)itsBaseFilterSize/ 00254 (FLOAT)itsImageSizesY[indx]) * 00255 (FLOAT)itsImageSizeY); 00256 LINFO("%d : Filter Size Y %d",indx,itsFilterSizesY[indx]); 00257 itsFilterSizesZ[indx] = fz; 00258 LINFO("%d : Filter Size Z %f",indx,itsFilterSizesZ[indx]); 00259 bx = bx/2; by = by/2; // fz = fz*2; 00260 indx++; 00261 } 00262 } 00263 00264 // set up each SurpriseControl 00265 for(ushort i = 0; i < itsMaxIndex; i++) 00266 { 00267 LINFO("Setting up RemoveSaliency for scale %d",i); 00268 itsSurpriseControl[i].SCsetAxisBias(itsAxisBiasX, 00269 itsAxisBiasY, 00270 itsAxisBiasZ); 00271 // we try to fit something close to the orignal filters used 00272 const FLOAT sigma = itsFilterSizesX[i]/5; 00273 const FLOAT z_sigma = itsFilterSizesZ[i]; 00274 LINFO("%d Sigma %f Z Sigma %f StdDev %f",i,sigma,z_sigma,itsStdSize); 00275 if(itsUseAndersonSeperable) 00276 itsSurpriseControl[i].SCcreateAndersonSepFilters(itsFilterSizesX[i]); 00277 else 00278 itsSurpriseControl[i].SCcreateSepFilters(sigma,z_sigma,itsStdSize); 00279 itsSurpriseControl[i].SCfindConvolutionEndPoints(); 00280 LINFO("%d Scale Power %f",i,itsScalePower[i]); 00281 LINFO("%d Bias H1 %f H2 %f S %f V %f",i, 00282 itsH1Bias,itsH2Bias,itsSBias,itsVBias); 00283 itsSurpriseControl[i].SCsetH2SVBias(itsH1Bias,itsH2Bias,itsSBias,itsVBias); 00284 itsSurpriseControl[i].SCuseMaxLevel(itsUseMaxLevel); 00285 itsSurpriseControl[i].SCuseTemporal(itsUseTemporal); 00286 itsSurpriseControl[i].SCnormalizeBiasWithScale(itsNormalizeBiasWithScale); 00287 LINFO("%d Lambda %f",i,itsLambda); 00288 itsSurpriseControl[i].SCsetLambda(itsLambda); 00289 LINFO("%d Original Image Weight %f",i,itsOriginalImageWeight); 00290 itsSurpriseControl[i].SCsetOriginalImageWeight(itsOriginalImageWeight); 00291 LINFO("%d Master Conspic Map Bias %f",i,itsMasterConspicBias); 00292 itsSurpriseControl[i].SCsetMasterConspicBias(itsMasterConspicBias); 00293 itsSurpriseControl[i].SCsetMyScale(i); 00294 00295 } 00296 } 00297 00298 /*************************************************************************/ 00299 00300 template <class FLOAT> inline 00301 void ScaleSurpriseControl<FLOAT>::SSCinputRawImage( 00302 const Image<PixRGB<FLOAT> >& rawImage) 00303 { 00304 itsRawImage = rawImage; 00305 } 00306 00307 /*************************************************************************/ 00308 00309 template <class FLOAT> inline 00310 void ScaleSurpriseControl<FLOAT>::SSCinputSalMap(const Image<FLOAT>& salMap) 00311 { 00312 itsSalMap = salMap; 00313 } 00314 00315 /*************************************************************************/ 00316 00317 template <class FLOAT> inline 00318 void ScaleSurpriseControl<FLOAT>::SSCinputBayesWeightImage( 00319 const Image<FLOAT>& bayesImage) 00320 { 00321 itsBayesWeightImage = bayesImage; 00322 for(ushort i = 0; i < itsMaxIndex; i++) 00323 { 00324 itsSurpriseControl[i].SCinputBayesWeightImage(itsBayesWeightImage); 00325 } 00326 } 00327 00328 /*************************************************************************/ 00329 00330 template <class FLOAT> inline 00331 void ScaleSurpriseControl<FLOAT>::SSCinputMaskImage( 00332 const Image<FLOAT>& maskImage) 00333 { 00334 itsMaskImage = maskImage; 00335 for(ushort i = 0; i < itsMaxIndex; i++) 00336 { 00337 itsSurpriseControl[i].SCinputMaskImage(itsMaskImage); 00338 } 00339 } 00340 00341 /*************************************************************************/ 00342 00343 template <class FLOAT> 00344 void ScaleSurpriseControl<FLOAT>::SSCprocessFrame(Brain* brain) 00345 { 00346 ////////itsSalMap = brain->getSM()->getV(true); 00347 LFATAL("FIXME PLEASE!"); 00348 /* 00349 itsSalMap = rescale(itsSalMap,itsImageSizeX,itsImageSizeY); 00350 // get each brain conspicuity map if we have one 00351 nub::soft_ref<VisualCortex> vc;///////////FIXME = brain->getVC(); 00352 00353 nub::soft_ref<ColorChannel> cc; 00354 nub::soft_ref<IntensityChannel> ic; 00355 nub::soft_ref<FlickerChannel> fc; 00356 nub::soft_ref<MotionChannel> mc; 00357 nub::soft_ref<OrientationChannel> oc; 00358 nub::soft_ref<H2SVChannel> hc; 00359 00360 // process over each scale type from the image pyramid 00361 00362 for(ushort i = 0; i < itsMaxIndex; i++) 00363 { 00364 itsSurpriseControl[i].SCinputRawImage(itsRawImage); 00365 itsSurpriseControl[i].SCinputSalMap(itsSalMap); 00366 } 00367 00368 // set up biases durring the first frame, maybe change this later 00369 if(itsFrameCounter == 0) 00370 { 00371 if(vc->hasSubChan("H2SVcolor")) 00372 { 00373 LINFO("INPUT H2SV Bias"); 00374 for(ushort i = 0; i < itsMaxIndex; i++) 00375 { 00376 itsSurpriseControl[i].SCsetConspicBias(itsConspicMapBias[SC_H1] 00377 *itsScalePower[i],SC_H1); 00378 itsSurpriseControl[i].SCsetConspicBias(itsConspicMapBias[SC_H2] 00379 *itsScalePower[i],SC_H2); 00380 itsSurpriseControl[i].SCsetConspicBias(itsConspicMapBias[SC_HS] 00381 *itsScalePower[i],SC_HS); 00382 itsSurpriseControl[i].SCsetConspicBias(itsConspicMapBias[SC_HV] 00383 *itsScalePower[i],SC_HV); 00384 } 00385 } 00386 else if(vc->hasSubChan("intensity")) 00387 { 00388 LINFO("INPUT Intensity Bias"); 00389 for(ushort i = 0; i < itsMaxIndex; i++) 00390 { 00391 itsSurpriseControl[i].SCsetConspicBias(itsConspicMapBias[SC_IN] 00392 *itsScalePower[i],SC_IN); 00393 } 00394 } 00395 if(vc->hasSubChan("color")) 00396 { 00397 LINFO("INPUT Color Bias"); 00398 for(ushort i = 0; i < itsMaxIndex; i++) 00399 { 00400 itsSurpriseControl[i].SCsetConspicBias(itsConspicMapBias[SC_RG] 00401 *itsScalePower[i],SC_RG); 00402 itsSurpriseControl[i].SCsetConspicBias(itsConspicMapBias[SC_BY] 00403 *itsScalePower[i],SC_BY); 00404 } 00405 } 00406 if(vc->hasSubChan("flicker")) 00407 { 00408 LINFO("INPUT Flicker Bias"); 00409 for(ushort i = 0; i < itsMaxIndex; i++) 00410 { 00411 itsSurpriseControl[i].SCsetConspicBias(itsConspicMapBias[SC_FL] 00412 *itsScalePower[i],SC_FL); 00413 } 00414 } 00415 if(vc->hasSubChan("orientation")) 00416 { 00417 LINFO("INPUT Orientation Bias"); 00418 for(ushort i = 0; i < itsMaxIndex; i++) 00419 { 00420 itsSurpriseControl[i].SCsetConspicBias(itsConspicMapBias[SC_GA0] 00421 *itsScalePower[i],SC_GA0); 00422 itsSurpriseControl[i].SCsetConspicBias(itsConspicMapBias[SC_GA1] 00423 *itsScalePower[i],SC_GA1); 00424 itsSurpriseControl[i].SCsetConspicBias(itsConspicMapBias[SC_GA2] 00425 *itsScalePower[i],SC_GA2); 00426 itsSurpriseControl[i].SCsetConspicBias(itsConspicMapBias[SC_GA3] 00427 *itsScalePower[i],SC_GA3); 00428 } 00429 } 00430 if(vc->hasSubChan("motion")) 00431 { 00432 LINFO("INPUT Motion Bias"); 00433 for(ushort i = 0; i < itsMaxIndex; i++) 00434 { 00435 itsSurpriseControl[i].SCsetConspicBias(itsConspicMapBias[SC_DR0] 00436 *itsScalePower[i],SC_DR0); 00437 itsSurpriseControl[i].SCsetConspicBias(itsConspicMapBias[SC_DR1] 00438 *itsScalePower[i],SC_DR1); 00439 itsSurpriseControl[i].SCsetConspicBias(itsConspicMapBias[SC_DR2] 00440 *itsScalePower[i],SC_DR2); 00441 itsSurpriseControl[i].SCsetConspicBias(itsConspicMapBias[SC_DR3] 00442 *itsScalePower[i],SC_DR3); 00443 } 00444 } 00445 } 00446 00447 Image<FLOAT> ftmp; 00448 00449 // ### H2SV 00450 if(vc->hasSubChan("H2SVcolor")) 00451 { 00452 LINFO("INPUT H2SV Channel"); 00453 dynCastWeakToFrom(hc, vc->subChan("H2SVcolor")); 00454 00455 if(hc->H1().numSubmaps() != itsMaxIndex) 00456 LFATAL("Expected %d scales from brain in h1 H2SV color channel, got %d", 00457 itsMaxIndex,hc->H1().numSubmaps()); 00458 if(hc->H2().numSubmaps() != itsMaxIndex) 00459 LFATAL("Expected %d scales from brain in h2 H2SV color channel, got %d", 00460 itsMaxIndex,hc->H2().numSubmaps()); 00461 if(hc->S().numSubmaps() != itsMaxIndex) 00462 LFATAL("Expected %d scales from brain in s H2SV color channel, got %d", 00463 itsMaxIndex,hc->S().numSubmaps()); 00464 if(hc->V().numSubmaps() != itsMaxIndex) 00465 LFATAL("Expected %d scales from brain in v H2SV color channel, got %d", 00466 itsMaxIndex,hc->V().numSubmaps()); 00467 for(ushort i = 0; i < itsMaxIndex; i++) 00468 { 00469 ftmp = hc->H1().getSubmap(i); 00470 ftmp = rescale(ftmp,itsImageSizeX,itsImageSizeY); 00471 itsSurpriseControl[i].SCinputConspicMap(ftmp,SC_H1); 00472 00473 ftmp = hc->H2().getSubmap(i); 00474 ftmp = rescale(ftmp,itsImageSizeX,itsImageSizeY); 00475 itsSurpriseControl[i].SCinputConspicMap(ftmp,SC_H2); 00476 00477 ftmp = hc->S().getSubmap(i); 00478 ftmp = rescale(ftmp,itsImageSizeX,itsImageSizeY); 00479 itsSurpriseControl[i].SCinputConspicMap(ftmp,SC_HS); 00480 00481 ftmp = hc->V().getSubmap(i); 00482 ftmp = rescale(ftmp,itsImageSizeX,itsImageSizeY); 00483 itsSurpriseControl[i].SCinputConspicMap(ftmp,SC_HV); 00484 } 00485 } 00486 // ### Intensity 00487 // Since H2SV V is the same as intensity, do not include this twice 00488 else if(vc->hasSubChan("intensity")) 00489 { 00490 LINFO("INPUT Intensity Channel"); 00491 dynCastWeakToFrom(ic, vc->subChan("intensity")); 00492 if(ic->numSubmaps() != itsMaxIndex) 00493 LFATAL("Expected %d scales from brain in intensity channel, got %d", 00494 itsMaxIndex,ic->numSubmaps()); 00495 for(ushort i = 0; i < itsMaxIndex; i++) 00496 { 00497 ftmp = ic->getSubmap(i); 00498 ftmp = rescale(ftmp,itsImageSizeX,itsImageSizeY); 00499 itsSurpriseControl[i].SCinputConspicMap(ftmp,SC_IN); 00500 } 00501 } 00502 00503 // ### Color 00504 if(vc->hasSubChan("color")) 00505 { 00506 LINFO("INPUT Color Channel"); 00507 dynCastWeakToFrom(cc, vc->subChan("color")); 00508 if(cc->rg().numSubmaps() != itsMaxIndex) 00509 LFATAL("Expected %d scales from brain in rg color channel, got %d", 00510 itsMaxIndex,cc->rg().numSubmaps()); 00511 if(cc->by().numSubmaps() != itsMaxIndex) 00512 LFATAL("Expected %d scales from brain in by color channel, got %d", 00513 itsMaxIndex,cc->by().numSubmaps()); 00514 for(ushort i = 0; i < itsMaxIndex; i++) 00515 { 00516 ftmp = cc->rg().getSubmap(i); 00517 ftmp = rescale(ftmp,itsImageSizeX,itsImageSizeY); 00518 itsSurpriseControl[i].SCinputConspicMap(ftmp,SC_RG); 00519 00520 ftmp = cc->by().getSubmap(i); 00521 ftmp = rescale(ftmp,itsImageSizeX,itsImageSizeY); 00522 itsSurpriseControl[i].SCinputConspicMap(ftmp,SC_BY); 00523 } 00524 } 00525 00526 // ### flicker 00527 if(vc->hasSubChan("flicker")) 00528 { 00529 LINFO("INPUT Flicker Channel"); 00530 dynCastWeakToFrom(fc, vc->subChan("flicker")); 00531 if(fc->numSubmaps() != itsMaxIndex) 00532 LFATAL("Expected %d scales from brain in flicker channel, got %d", 00533 itsMaxIndex,fc->numSubmaps()); 00534 for(ushort i = 0; i < itsMaxIndex; i++) 00535 { 00536 //Do we have a pyramid yet? If not just fill up with zeros 00537 if(fc->hasPyramid()) 00538 { 00539 ftmp = fc->getSubmap(i); 00540 } 00541 else 00542 { 00543 typename Image<FLOAT>::iterator ftmpItr = ftmp.beginw(); 00544 while(ftmpItr != ftmp.endw()) 00545 { 00546 *ftmpItr = 0; 00547 ++ftmpItr; 00548 } 00549 } 00550 ftmp = rescale(ftmp,itsImageSizeX,itsImageSizeY); 00551 itsSurpriseControl[i].SCinputConspicMap(ftmp,SC_FL); 00552 } 00553 } 00554 00555 // ### Orientation 00556 if(vc->hasSubChan("orientation")) 00557 { 00558 LINFO("INPUT Orientation Channel"); 00559 dynCastWeakToFrom(oc, vc->subChan("orientation")); 00560 const uint imi = (uint)(itsMaxIndex*4); 00561 if(oc->numSubmaps() != imi) 00562 LFATAL("Expected %d scales from brain in orientation channel, got %d", 00563 imi,oc->numSubmaps()); 00564 if(oc->numChans() != 4) 00565 LFATAL("I only work with a 4-gabor orientation channels!"); 00566 for(ushort i = 0; i < itsMaxIndex; i++) 00567 { 00568 ftmp = oc->gabor(0).getSubmap(i); 00569 ftmp = rescale(ftmp,itsImageSizeX,itsImageSizeY); 00570 itsSurpriseControl[i].SCinputConspicMap(ftmp,SC_GA0); 00571 00572 ftmp = oc->gabor(1).getSubmap(i); 00573 ftmp = rescale(ftmp,itsImageSizeX,itsImageSizeY); 00574 itsSurpriseControl[i].SCinputConspicMap(ftmp,SC_GA1); 00575 00576 ftmp = oc->gabor(2).getSubmap(i); 00577 ftmp = rescale(ftmp,itsImageSizeX,itsImageSizeY); 00578 itsSurpriseControl[i].SCinputConspicMap(ftmp,SC_GA2); 00579 00580 ftmp = oc->gabor(3).getSubmap(i); 00581 ftmp = rescale(ftmp,itsImageSizeX,itsImageSizeY); 00582 itsSurpriseControl[i].SCinputConspicMap(ftmp,SC_GA3); 00583 } 00584 } 00585 00586 // ### Motion 00587 if(vc->hasSubChan("motion")) 00588 { 00589 LINFO("INPUT Motion Channel"); 00590 dynCastWeakToFrom(mc, vc->subChan("motion")); 00591 const uint imi = (uint)(itsMaxIndex*4); 00592 if(mc->numSubmaps() != imi) 00593 LFATAL("Expected %d scales from brain in motion channel, got %d", 00594 imi,oc->numSubmaps()); 00595 if(mc->numChans() != 4) 00596 LFATAL("I only work with a 4-direction motion channels!"); 00597 for(ushort i = 0; i < itsMaxIndex; i++) 00598 { 00599 ftmp = mc->dirChan(0).getSubmap(i); 00600 ftmp = rescale(ftmp,itsImageSizeX,itsImageSizeY); 00601 itsSurpriseControl[i].SCinputConspicMap(ftmp,SC_DR0); 00602 00603 ftmp = mc->dirChan(1).getSubmap(i); 00604 ftmp = rescale(ftmp,itsImageSizeX,itsImageSizeY); 00605 itsSurpriseControl[i].SCinputConspicMap(ftmp,SC_DR1); 00606 00607 ftmp = mc->dirChan(2).getSubmap(i); 00608 ftmp = rescale(ftmp,itsImageSizeX,itsImageSizeY); 00609 itsSurpriseControl[i].SCinputConspicMap(ftmp,SC_DR2); 00610 00611 ftmp = mc->dirChan(3).getSubmap(i); 00612 ftmp = rescale(ftmp,itsImageSizeX,itsImageSizeY); 00613 itsSurpriseControl[i].SCinputConspicMap(ftmp,SC_DR3); 00614 } 00615 } 00616 00617 for(ushort i = 0; i < itsMaxIndex; i++) 00618 { 00619 // process this scale 00620 itsSurpriseControl[i].SCprocessFrameSeperable(); 00621 00622 if(itsGetReduced) 00623 { 00624 // get result image for this scale 00625 itsResultImages[i] = itsSurpriseControl[i].SCgetFrame(); 00626 } 00627 else 00628 { 00629 PIX_H2SV_TYPE<float> pix(itsSharpFactorH1,itsSharpFactorH2, 00630 itsSharpFactorS, itsSharpFactorV); 00631 itsResultImages[i] = itsSurpriseControl[i].SCgetSharpened(pix); 00632 } 00633 LINFO("done"); 00634 } 00635 00636 // zero it out before we store new values here 00637 FLOAT norm = 0.0F; 00638 typename Image<PixRGB<FLOAT> >::iterator finalImageItr = 00639 itsFinalImage.beginw(); 00640 while(finalImageItr != itsFinalImage.endw()) 00641 { 00642 *finalImageItr = PixRGB<FLOAT>(0,0,0); 00643 ++finalImageItr; 00644 } 00645 00646 // first form a biased sum over each scale 00647 for(ushort i = 0; i < itsMaxIndex; i++) 00648 { 00649 finalImageItr = itsFinalImage.beginw(); 00650 typename Image<PixRGB<FLOAT> >::const_iterator resultImageItr = 00651 itsResultImages[i].beginw(); 00652 const FLOAT bias = itsScaleBias[i]; 00653 norm += bias; 00654 while(finalImageItr != itsFinalImage.endw()) 00655 { 00656 *finalImageItr += (*resultImageItr) * bias; 00657 ++finalImageItr; ++resultImageItr; 00658 } 00659 } 00660 00661 // then normalize into the final image 00662 for(typename Image<PixRGB<FLOAT> >::iterator finalImageItr = 00663 itsFinalImage.beginw(); 00664 finalImageItr != itsFinalImage.endw(); 00665 ++finalImageItr) 00666 { 00667 *finalImageItr = (*finalImageItr)/norm; 00668 } 00669 itsFrameCounter++; 00670 */ 00671 } 00672 00673 /*************************************************************************/ 00674 00675 template <class FLOAT> inline 00676 void ScaleSurpriseControl<FLOAT>::SSCprocessFrame(const uint frame) 00677 { 00678 itsFrameCounter++; 00679 } 00680 /*************************************************************************/ 00681 00682 template <class FLOAT> inline 00683 Image<PixRGB<FLOAT> > ScaleSurpriseControl<FLOAT>::SSCgetFrame() const 00684 { 00685 return itsFinalImage; 00686 } 00687 00688 /*************************************************************************/ 00689 00690 template <class FLOAT> inline Image<PixRGB<FLOAT> > 00691 ScaleSurpriseControl<FLOAT>::SSCgetDiffImage(const bool normalize) const 00692 { 00693 Image<PixRGB<float> > diffImage; 00694 diffImage.resize(itsImageSizeX,itsImageSizeY); 00695 00696 const Image<PixRGB<float> > inImage = itsSurpriseControl[0].SCgetInImage(); 00697 00698 typename Image<PixRGB<float> >::const_iterator finalImageItr = 00699 itsFinalImage.begin(); 00700 00701 typename Image<PixRGB<float> >::const_iterator rawImageItr = 00702 inImage.begin(); 00703 00704 typename Image<PixRGB<float> >::iterator diffImageItr = 00705 diffImage.beginw(); 00706 00707 while(rawImageItr != inImage.end()) 00708 { 00709 //*diffImageItr = (*rawImageItr); 00710 //*diffImageItr = (*finalImageItr); 00711 *diffImageItr = abs((*rawImageItr) - (*finalImageItr)); 00712 ++diffImageItr; ++rawImageItr; ++finalImageItr; 00713 } 00714 00715 if(normalize) diffImage = normalizeRGB(diffImage,PixRGB<FLOAT>(0,0,0), 00716 PixRGB<FLOAT>(255,255,255)); 00717 00718 return diffImage; 00719 } 00720 00721 /*************************************************************************/ 00722 00723 template <class FLOAT> std::vector<Image<PixRGB<FLOAT> > > 00724 ScaleSurpriseControl<FLOAT>::SSCgetDiffParts() const 00725 { 00726 Image<PIX_H2SV_TYPE<FLOAT> > rawDiffImage; 00727 rawDiffImage.resize(itsImageSizeX,itsImageSizeY); 00728 00729 typename Image<PIX_H2SV_TYPE<FLOAT> >::iterator rawDiffImageItr = 00730 rawDiffImage.beginw(); 00731 00732 while(rawDiffImageItr != rawDiffImage.end()) 00733 { 00734 (*rawDiffImageItr) = PIX_H2SV_TYPE<FLOAT>(0); 00735 ++rawDiffImageItr; 00736 } 00737 00738 for(ushort i = 0; i < itsMaxIndex; i++) 00739 //for(ushort i = 0; i < 1; i++) 00740 { 00741 const Image<PIX_H2SV_TYPE<FLOAT> > outImage = 00742 itsSurpriseControl[i].SCgetRawOutImage(); 00743 const Image<PIX_H2SV_TYPE<FLOAT> > inImage = 00744 itsSurpriseControl[i].SCgetRawInImage(); 00745 00746 typename Image<PIX_H2SV_TYPE<FLOAT> >::const_iterator outImageItr = 00747 outImage.begin(); 00748 typename Image<PIX_H2SV_TYPE<FLOAT> >::const_iterator inImageItr = 00749 inImage.begin(); 00750 00751 rawDiffImageItr = rawDiffImage.beginw(); 00752 00753 //while(outImageItr != outImage.end()) 00754 while(inImageItr != inImage.end()) 00755 { 00756 //*rawDiffImageItr += (*outImageItr); 00757 //*rawDiffImageItr += (*inImageItr); 00758 (*rawDiffImageItr) += (*outImageItr) - (*inImageItr); 00759 ++outImageItr; ++inImageItr; ++rawDiffImageItr; 00760 } 00761 } 00762 00763 while(rawDiffImageItr != rawDiffImage.end()) 00764 { 00765 (*rawDiffImageItr) = (*rawDiffImageItr)/itsMaxIndex; 00766 ++rawDiffImageItr; 00767 } 00768 00769 Image<FLOAT> baseImage; 00770 baseImage.resize(itsImageSizeX,itsImageSizeY); 00771 std::vector<Image<FLOAT> > outImageVec(4,baseImage); 00772 00773 00774 for(ushort x = 0; x < itsImageSizeX; x++) 00775 { 00776 for(ushort y = 0; y < itsImageSizeY; y++) 00777 { 00778 outImageVec[0].setVal(x,y,rawDiffImage.getVal(x,y).p[0]); 00779 outImageVec[1].setVal(x,y,rawDiffImage.getVal(x,y).p[1]); 00780 outImageVec[2].setVal(x,y,rawDiffImage.getVal(x,y).p[2]); 00781 outImageVec[3].setVal(x,y,rawDiffImage.getVal(x,y).p[3]); 00782 } 00783 } 00784 00785 Image<PixRGB<FLOAT> > baseImageRGB; 00786 baseImageRGB.resize(itsImageSizeX,itsImageSizeY); 00787 std::vector<Image<PixRGB<FLOAT> > > outImageRGVec(4,baseImageRGB); 00788 00789 (outImageRGVec[0]) = normalizeRGPolarAuto(outImageVec[0]); 00790 00791 (outImageRGVec[1]) = normalizeRGPolarAuto(outImageVec[1]); 00792 00793 (outImageRGVec[2]) = normalizeRGPolarAuto(outImageVec[2]); 00794 00795 (outImageRGVec[3]) = normalizeRGPolarAuto(outImageVec[3]); 00796 00797 return outImageRGVec; 00798 } 00799 00800 /*************************************************************************/ 00801 00802 template <class FLOAT> inline std::vector<Image<FLOAT> > 00803 ScaleSurpriseControl<FLOAT>::SSCgetBetaParts(const bool normalize) const 00804 { 00805 Image<PixHyper<FLOAT,SC_MAX_CHANNELS> > outBetaImage; 00806 outBetaImage.resize(itsImageSizeX,itsImageSizeY); 00807 00808 /* 00809 for(typename Image<PixHyper<FLOAT,SC_MAX_CHANNELS> >::iterator bptr 00810 = outBetaImage.beginw(); 00811 bptr != outBetaImage.endw(); 00812 ++bptr) 00813 { 00814 for(ushort i = 0; i < SC_MAX_CHANNELS; i++) 00815 { 00816 bptr->p[i] = 0; 00817 } 00818 } 00819 */ 00820 00821 for(ushort i = 0; i < itsMaxIndex; i++) 00822 { 00823 const Image<PixHyper<FLOAT,SC_MAX_CHANNELS> > betaImage = 00824 itsSurpriseControl[i].SCgetBetaImage(); 00825 00826 typename Image<PixHyper<FLOAT,SC_MAX_CHANNELS> >::const_iterator 00827 betaImageItr = betaImage.begin(); 00828 typename Image<PixHyper<FLOAT,SC_MAX_CHANNELS> >::iterator 00829 outBetaImageItr = outBetaImage.beginw(); 00830 00831 PixHyper<FLOAT,SC_MAX_CHANNELS> pIndex((FLOAT)itsMaxIndex); 00832 00833 while(betaImageItr != betaImage.end()) 00834 { 00835 (*outBetaImageItr) += (*betaImageItr)/pIndex; 00836 ++betaImageItr; ++outBetaImageItr; 00837 } 00838 } 00839 00840 Image<FLOAT> baseImage; 00841 baseImage.resize(itsImageSizeX,itsImageSizeY); 00842 std::vector<Image<FLOAT> > outImageVec(SC_MAX_CHANNELS,baseImage); 00843 00844 for(ushort x = 0; x < itsImageSizeX; x++) 00845 { 00846 for(ushort y = 0; y < itsImageSizeY; y++) 00847 { 00848 for(ushort i = 0; i < SC_MAX_CHANNELS; i++) 00849 { 00850 outImageVec[i].setVal(x,y,outBetaImage.getVal(x,y).p[i]); 00851 } 00852 } 00853 } 00854 00855 if(normalize) 00856 { 00857 for(ushort i = 0; i < SC_MAX_CHANNELS; i++) 00858 { 00859 outImageVec[i] = normalizeFloat(outImageVec[i],FLOAT_NORM_0_255); 00860 } 00861 } 00862 return outImageVec; 00863 } 00864 00865 /*************************************************************************/ 00866 00867 template <class FLOAT> inline void 00868 ScaleSurpriseControl<FLOAT>::SSCgetBiasParts( 00869 std::vector<Image<PixRGB<FLOAT> > > &H1, 00870 std::vector<Image<PixRGB<FLOAT> > > &H2, 00871 std::vector<Image<PixRGB<FLOAT> > > &S, 00872 std::vector<Image<PixRGB<FLOAT> > > &V) const 00873 { 00874 Image<PixRGB<FLOAT> > baseImage; 00875 baseImage.resize(itsImageSizeX,itsImageSizeY); 00876 /* 00877 for(typename Image<PixRGB<FLOAT> >::iterator bptr = baseImage.beginw(); 00878 bptr != baseImage.endw(); 00879 ++bptr) 00880 { 00881 *bptr = PixRGB<FLOAT>(0); 00882 } 00883 */ 00884 std::vector<Image<PixRGB<FLOAT> > > outH1(itsMaxIndex,baseImage); 00885 std::vector<Image<PixRGB<FLOAT> > > outH2(itsMaxIndex,baseImage); 00886 std::vector<Image<PixRGB<FLOAT> > > outS(itsMaxIndex, baseImage); 00887 std::vector<Image<PixRGB<FLOAT> > > outV(itsMaxIndex, baseImage); 00888 00889 for(ushort i = 0; i < itsMaxIndex; i++) 00890 { 00891 Image<FLOAT> h1; Image<FLOAT> h2; Image<FLOAT> s; Image<FLOAT> v; 00892 itsSurpriseControl[i].SCgetLocalBiasImages(h1, h2, s, v); 00893 00894 outH1[i] = normalizeScaleRainbow(h1,0,1); 00895 outH2[i] = normalizeScaleRainbow(h2,0,1); 00896 outS[i] = normalizeScaleRainbow(s, 0,1); 00897 outV[i] = normalizeScaleRainbow(v, 0,1); 00898 //outH1[i] = h1; 00899 } 00900 H1 = outH1; H2 = outH2; S = outS; V = outV; 00901 } 00902 00903 /*************************************************************************/ 00904 00905 template <class FLOAT> inline void 00906 ScaleSurpriseControl<FLOAT>::SSCgetSeperableParts( 00907 std::vector<Image<PixRGB<FLOAT> > > &Zimgs, 00908 std::vector<Image<PixRGB<FLOAT> > > &Yimgs, 00909 const bool normalize) const 00910 { 00911 Image<PixRGB<FLOAT> > baseImage; 00912 baseImage.resize(itsImageSizeX,itsImageSizeY); 00913 /* 00914 for(typename Image<PixRGB<FLOAT> >::iterator bptr = baseImage.beginw(); 00915 bptr != baseImage.endw(); 00916 ++bptr) 00917 { 00918 *bptr = PixRGB<FLOAT>(0); 00919 } 00920 */ 00921 std::vector<Image<PixRGB<FLOAT> > > outZ(itsMaxIndex,baseImage); 00922 std::vector<Image<PixRGB<FLOAT> > > outY(itsMaxIndex,baseImage); 00923 00924 for(ushort i = 0; i < itsMaxIndex; i++) 00925 { 00926 Image<PIX_H2SV_TYPE<FLOAT> > Zimg, Yimg; 00927 00928 itsSurpriseControl[i].SCgetSeperableParts(Zimg,Yimg); 00929 00930 outZ[i] = static_cast<Image<PixRGB<FLOAT> > >(Zimg); 00931 outY[i] = static_cast<Image<PixRGB<FLOAT> > >(Yimg); 00932 00933 if(normalize) 00934 { 00935 outZ[i] = normalizeRGB(outZ[i],PixRGB<FLOAT>(0,0,0), 00936 PixRGB<FLOAT>(255,255,255)); 00937 outY[i] = normalizeRGB(outY[i],PixRGB<FLOAT>(0,0,0), 00938 PixRGB<FLOAT>(255,255,255)); 00939 } 00940 } 00941 00942 Zimgs = outZ; 00943 Yimgs = outY; 00944 } 00945 00946 /*************************************************************************/ 00947 template class ScaleSurpriseControl<float>; 00948 00949 #endif