00001 /*!@file Surprise/SurpriseImage.C a 2D array of SurpriseModel objects */ 00002 00003 // //////////////////////////////////////////////////////////////////// // 00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2003 // 00005 // by the 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: Laurent Itti <itti@usc.edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Surprise/SurpriseImage.C $ 00035 // $Id: SurpriseImage.C 11562 2009-08-08 00:35:40Z dberg $ 00036 // 00037 00038 #include "Surprise/SurpriseImage.H" 00039 00040 #include "Image/Kernels.H" // for gaussianBlob() 00041 #include "Util/Assert.H" 00042 00043 // ###################################################################### 00044 template <class T> 00045 SurpriseImage<T>::SurpriseImage() : 00046 Image<T>() 00047 { } 00048 00049 // ###################################################################### 00050 template <class T> 00051 SurpriseImage<T>::SurpriseImage(const Dims& dims) : 00052 Image<T>(dims, NO_INIT) 00053 { } 00054 00055 // ###################################################################### 00056 template <class T> 00057 SurpriseImage<T>::SurpriseImage(const double updfac, 00058 const Image<double>& sampleval, 00059 const Image<double>& samplevar) : 00060 Image<T>(sampleval.getDims(), NO_INIT) 00061 { init(updfac, sampleval, samplevar); } 00062 00063 // ###################################################################### 00064 template <class T> 00065 SurpriseImage<T>::~SurpriseImage() 00066 { } 00067 00068 // ###################################################################### 00069 template <class T> 00070 void SurpriseImage<T>::reset() 00071 { 00072 typename SurpriseImage<T>::iterator 00073 itr = this->beginw(), stop = this->endw(); 00074 while (itr != stop) (itr++)->reset(); 00075 } 00076 00077 // ###################################################################### 00078 template <class T> 00079 void SurpriseImage<T>::init(const double updfac, 00080 const Image<double>& sampleval, 00081 const Image<double>& samplevar) 00082 { 00083 ASSERT(this->isSameSize(sampleval) && this->isSameSize(samplevar)); 00084 00085 typename SurpriseImage<T>::iterator 00086 itr = this->beginw(), stop = this->endw(); 00087 Image<double>::const_iterator s = sampleval.begin(), se = samplevar.begin(); 00088 00089 while (itr != stop) (itr++)->init(updfac, *s++, *se++); 00090 } 00091 00092 // ###################################################################### 00093 template <class T> 00094 void SurpriseImage<T>::resetUpdFac(const double updfac) 00095 { 00096 typename SurpriseImage<T>::iterator i = this->beginw(), stop = this->endw(); 00097 while(i != stop) (i++)->resetUpdFac(updfac); 00098 } 00099 00100 // ###################################################################### 00101 template <class T> 00102 Image<double> SurpriseImage<T>::surprise(const SurpriseImage<T>& other) 00103 { 00104 ASSERT(this->isSameSize(other)); 00105 00106 Image<double> ret(this->getDims(), NO_INIT); 00107 00108 typename SurpriseImage<T>::iterator i = this->beginw(), stop = this->endw(); 00109 typename SurpriseImage<T>::const_iterator o = other.begin(); 00110 Image<double>::iterator r = ret.beginw(); 00111 00112 while(i != stop) *r++ = (i++)->surprise(*o++); 00113 00114 return ret; 00115 } 00116 // ###################################################################### 00117 template <class T> 00118 void SurpriseImage<T>::preComputeHyperParams(const SurpriseImage<T>& models) 00119 { 00120 typename SurpriseImage<T>::iterator i = this->beginw(), stop = this->endw(); 00121 typename SurpriseImage<T>::const_iterator m = models.begin(); 00122 00123 while(i != stop) (i++)->preComputeHyperParams(*m++); 00124 } 00125 00126 // ###################################################################### 00127 template <class T> 00128 void SurpriseImage<T>::neighborhoods(const SurpriseImage<T>& models, 00129 const float neighsigma) 00130 { 00131 *this = models; // set us to same size as models and inherit their params 00132 00133 // this is a very inefficient implementation... will be optimized some day: 00134 const int w = this->getWidth(), h = this->getHeight(); Point2D<int> pos; 00135 typename SurpriseImage<T>::iterator itr = this->beginw(); 00136 for (pos.j = 0; pos.j < h; pos.j ++) 00137 for (pos.i = 0; pos.i < w; pos.i ++) 00138 { 00139 const Image<float> g = 00140 gaussianBlob<float>(this->getDims(), pos, neighsigma, neighsigma); 00141 (itr++)->combineFrom(models, g); 00142 } 00143 } 00144 00145 // ###################################################################### 00146 template <class T> 00147 void SurpriseImage<T>::neighborhoods(const SurpriseImage<T>& models, 00148 const Image<float>& weights) 00149 { 00150 ASSERT(weights.getWidth() == 2 * models.getWidth() + 1); 00151 ASSERT(weights.getHeight() == 2 * models.getHeight() + 1); 00152 00153 *this = models; // set us to same size as models and inherit their params 00154 00155 const int w = this->getWidth(), h = this->getHeight(); Point2D<int> pos; 00156 typename SurpriseImage<T>::iterator itr = this->beginw(); 00157 for (pos.j = 0; pos.j < h; pos.j ++) 00158 { 00159 const int o = w + (2 * w + 1) * (h - pos.j); 00160 for (pos.i = 0; pos.i < w; pos.i ++) 00161 (itr++)->combineFrom(models, weights, pos, w, h, o); 00162 } 00163 } 00164 00165 // ###################################################################### 00166 template <> 00167 void SurpriseImage<SurpriseModelSP>::neighborhoods( 00168 const SurpriseImage<SurpriseModelSP>& models, 00169 const Image<float>& weights) 00170 { 00171 ASSERT(weights.getWidth() == 2 * models.getWidth() + 1); 00172 ASSERT(weights.getHeight() == 2 * models.getHeight() + 1); 00173 00174 *this = models; // set us to same size as models and inherit their params 00175 00176 const int w = this->getWidth(), h = this->getHeight(); Point2D<int> pos; 00177 00178 // get a copy of the models then pre-compute alpha/beta 00179 SurpriseImage<SurpriseModelSP> models2 = models; 00180 SurpriseImage<SurpriseModelSP>::iterator itr = models2.beginw(); 00181 for (pos.j = 0; pos.j < h; pos.j ++) 00182 for (pos.i = 0; pos.i < w; pos.i ++) 00183 (itr++)->preSetAlpha(); 00184 00185 itr = this->beginw(); 00186 for (pos.j = 0; pos.j < h; pos.j ++) 00187 { 00188 const int o = w + (2 * w + 1) * (h - pos.j); 00189 for (pos.i = 0; pos.i < w; pos.i ++) 00190 (itr++)->combineFrom(models2, weights, pos, w, h, o); 00191 } 00192 } 00193 00194 // ###################################################################### 00195 template <> 00196 void SurpriseImage<SurpriseModelSP1>::neighborhoods( 00197 const SurpriseImage<SurpriseModelSP1>& models, 00198 const Image<float>& weights) 00199 { 00200 ASSERT(weights.getWidth() == 2 * models.getWidth() + 1); 00201 ASSERT(weights.getHeight() == 2 * models.getHeight() + 1); 00202 00203 *this = models; // set us to same size as models and inherit their params 00204 00205 const int w = this->getWidth(), h = this->getHeight(); Point2D<int> pos; 00206 00207 // get a copy of the models then pre-compute alpha/beta 00208 SurpriseImage<SurpriseModelSP1> models2 = models; 00209 SurpriseImage<SurpriseModelSP1>::iterator itr = models2.beginw(); 00210 for (pos.j = 0; pos.j < h; pos.j ++) 00211 for (pos.i = 0; pos.i < w; pos.i ++) 00212 (itr++)->preSetAlpha(); 00213 00214 itr = this->beginw(); 00215 for (pos.j = 0; pos.j < h; pos.j ++) 00216 { 00217 const int o = w + (2 * w + 1) * (h - pos.j); 00218 for (pos.i = 0; pos.i < w; pos.i ++) 00219 (itr++)->combineFrom(models2, weights, pos, w, h, o); 00220 } 00221 } 00222 00223 // ###################################################################### 00224 template <> 00225 void SurpriseImage<SurpriseModelSPC>::neighborhoods( 00226 const SurpriseImage<SurpriseModelSPC>& models, 00227 const Image<float>& weights) 00228 { 00229 ASSERT(weights.getWidth() == 2 * models.getWidth() + 1); 00230 ASSERT(weights.getHeight() == 2 * models.getHeight() + 1); 00231 00232 *this = models; // set us to same size as models and inherit their params 00233 00234 const int w = this->getWidth(), h = this->getHeight(); Point2D<int> pos; 00235 00236 // get a copy of the models then pre-compute alpha/beta 00237 SurpriseImage<SurpriseModelSPC> models2 = models; 00238 SurpriseImage<SurpriseModelSPC>::iterator itr = models2.beginw(); 00239 for (pos.j = 0; pos.j < h; pos.j ++) 00240 for (pos.i = 0; pos.i < w; pos.i ++) 00241 (itr++)->preSetAlpha(); 00242 00243 itr = this->beginw(); 00244 for (pos.j = 0; pos.j < h; pos.j ++) 00245 { 00246 const int o = w + (2 * w + 1) * (h - pos.j); 00247 for (pos.i = 0; pos.i < w; pos.i ++) 00248 (itr++)->combineFrom(models2, weights, pos, w, h, o); 00249 } 00250 } 00251 00252 // ###################################################################### 00253 template <> 00254 void SurpriseImage<SurpriseModelSPF>::neighborhoods( 00255 const SurpriseImage<SurpriseModelSPF>& models, 00256 const Image<float>& weights) 00257 { 00258 ASSERT(weights.getWidth() == 2 * models.getWidth() + 1); 00259 ASSERT(weights.getHeight() == 2 * models.getHeight() + 1); 00260 00261 *this = models; // set us to same size as models and inherit their params 00262 00263 const int w = this->getWidth(), h = this->getHeight(); Point2D<int> pos; 00264 00265 // get a copy of the models then pre-compute alpha/beta 00266 SurpriseImage<SurpriseModelSPF> models2 = models; 00267 SurpriseImage<SurpriseModelSPF>::iterator itr = models2.beginw(); 00268 for (pos.j = 0; pos.j < h; pos.j ++) 00269 for (pos.i = 0; pos.i < w; pos.i ++) 00270 (itr++)->preSetAlpha(); 00271 00272 itr = this->beginw(); 00273 for (pos.j = 0; pos.j < h; pos.j ++) 00274 { 00275 const int o = w + (2 * w + 1) * (h - pos.j); 00276 for (pos.i = 0; pos.i < w; pos.i ++) 00277 (itr++)->combineFrom(models2, weights, pos, w, h, o); 00278 } 00279 } 00280 00281 // ###################################################################### 00282 template <class T> 00283 void SurpriseImage<T>::neighborhoods(const SurpriseImage<T>& models, 00284 const Image<float>& weights, 00285 const bool NO_INIT) 00286 { 00287 ASSERT(weights.getWidth() == 2 * models.getWidth() + 1); 00288 ASSERT(weights.getHeight() == 2 * models.getHeight() + 1); 00289 00290 if(!NO_INIT) 00291 *this = models; // set us to same size as models and inherit their params 00292 00293 const int w = this->getWidth(), h = this->getHeight(); Point2D<int> pos; 00294 typename SurpriseImage<T>::iterator itr = this->beginw(); 00295 for (pos.j = 0; pos.j < h; pos.j ++) 00296 { 00297 const int o = w + (2 * w + 1) * (h - pos.j); 00298 for (pos.i = 0; pos.i < w; pos.i ++) 00299 (itr++)->combineFrom(models, weights, pos, w, h, o); 00300 } 00301 } 00302 00303 // ###################################################################### 00304 template <> 00305 void SurpriseImage<SurpriseModelSP>::neighborhoods( 00306 const SurpriseImage<SurpriseModelSP>& models, 00307 const Image<float>& weights, 00308 const bool NO_INIT) 00309 { 00310 ASSERT(weights.getWidth() == 2 * models.getWidth() + 1); 00311 ASSERT(weights.getHeight() == 2 * models.getHeight() + 1); 00312 00313 if(!NO_INIT) 00314 *this = models; // set us to same size as models and inherit their params 00315 00316 const int w = this->getWidth(), h = this->getHeight(); Point2D<int> pos; 00317 00318 // get a copy of the models then pre-compute alpha/beta 00319 SurpriseImage<SurpriseModelSP> models2 = models; 00320 SurpriseImage<SurpriseModelSP>::iterator itr = models2.beginw(); 00321 for (pos.j = 0; pos.j < h; pos.j ++) 00322 for (pos.i = 0; pos.i < w; pos.i ++) 00323 (itr++)->preSetAlpha(); 00324 00325 itr = this->beginw(); 00326 for (pos.j = 0; pos.j < h; pos.j ++) 00327 { 00328 const int o = w + (2 * w + 1) * (h - pos.j); 00329 for (pos.i = 0; pos.i < w; pos.i ++) 00330 (itr++)->combineFrom(models2, weights, pos, w, h, o); 00331 } 00332 } 00333 00334 00335 // ###################################################################### 00336 template <> 00337 void SurpriseImage<SurpriseModelSP1>::neighborhoods( 00338 const SurpriseImage<SurpriseModelSP1>& models, 00339 const Image<float>& weights, 00340 const bool NO_INIT) 00341 { 00342 ASSERT(weights.getWidth() == 2 * models.getWidth() + 1); 00343 ASSERT(weights.getHeight() == 2 * models.getHeight() + 1); 00344 00345 if(!NO_INIT) 00346 *this = models; // set us to same size as models and inherit their params 00347 00348 const int w = this->getWidth(), h = this->getHeight(); Point2D<int> pos; 00349 00350 // get a copy of the models then pre-compute alpha/beta 00351 SurpriseImage<SurpriseModelSP1> models2 = models; 00352 SurpriseImage<SurpriseModelSP1>::iterator itr = models2.beginw(); 00353 for (pos.j = 0; pos.j < h; pos.j ++) 00354 for (pos.i = 0; pos.i < w; pos.i ++) 00355 (itr++)->preSetAlpha(); 00356 00357 itr = this->beginw(); 00358 for (pos.j = 0; pos.j < h; pos.j ++) 00359 { 00360 const int o = w + (2 * w + 1) * (h - pos.j); 00361 for (pos.i = 0; pos.i < w; pos.i ++) 00362 (itr++)->combineFrom(models2, weights, pos, w, h, o); 00363 } 00364 } 00365 00366 // ###################################################################### 00367 template <> 00368 void SurpriseImage<SurpriseModelSPC>::neighborhoods( 00369 const SurpriseImage<SurpriseModelSPC>& models, 00370 const Image<float>& weights, 00371 const bool NO_INIT) 00372 { 00373 ASSERT(weights.getWidth() == 2 * models.getWidth() + 1); 00374 ASSERT(weights.getHeight() == 2 * models.getHeight() + 1); 00375 00376 if(!NO_INIT) 00377 *this = models; // set us to same size as models and inherit their params 00378 00379 const int w = this->getWidth(), h = this->getHeight(); Point2D<int> pos; 00380 00381 // get a copy of the models then pre-compute alpha/beta 00382 SurpriseImage<SurpriseModelSPC> models2 = models; 00383 SurpriseImage<SurpriseModelSPC>::iterator itr = models2.beginw(); 00384 for (pos.j = 0; pos.j < h; pos.j ++) 00385 for (pos.i = 0; pos.i < w; pos.i ++) 00386 (itr++)->preSetAlpha(); 00387 00388 itr = this->beginw(); 00389 for (pos.j = 0; pos.j < h; pos.j ++) 00390 { 00391 const int o = w + (2 * w + 1) * (h - pos.j); 00392 for (pos.i = 0; pos.i < w; pos.i ++) 00393 (itr++)->combineFrom(models2, weights, pos, w, h, o); 00394 } 00395 } 00396 00397 // ###################################################################### 00398 template <> 00399 void SurpriseImage<SurpriseModelSPF>::neighborhoods( 00400 const SurpriseImage<SurpriseModelSPF>& models, 00401 const Image<float>& weights, 00402 const bool NO_INIT) 00403 { 00404 ASSERT(weights.getWidth() == 2 * models.getWidth() + 1); 00405 ASSERT(weights.getHeight() == 2 * models.getHeight() + 1); 00406 00407 if(!NO_INIT) 00408 *this = models; // set us to same size as models and inherit their params 00409 00410 const int w = this->getWidth(), h = this->getHeight(); Point2D<int> pos; 00411 00412 // get a copy of the models then pre-compute alpha/beta 00413 SurpriseImage<SurpriseModelSPF> models2 = models; 00414 SurpriseImage<SurpriseModelSPF>::iterator itr = models2.beginw(); 00415 for (pos.j = 0; pos.j < h; pos.j ++) 00416 for (pos.i = 0; pos.i < w; pos.i ++) 00417 (itr++)->preSetAlpha(); 00418 00419 itr = this->beginw(); 00420 for (pos.j = 0; pos.j < h; pos.j ++) 00421 { 00422 const int o = w + (2 * w + 1) * (h - pos.j); 00423 for (pos.i = 0; pos.i < w; pos.i ++) 00424 (itr++)->combineFrom(models2, weights, pos, w, h, o); 00425 } 00426 } 00427 00428 // ###################################################################### 00429 template <class T> 00430 Image<double> SurpriseImage<T>::getMean() const 00431 { 00432 Image<double> ret(this->getDims(), NO_INIT); 00433 00434 typename SurpriseImage<T>::const_iterator 00435 i = this->begin(), stop = this->end(); 00436 Image<double>::iterator r = ret.beginw(); 00437 00438 while(i != stop) *r++ = (i++)->getMean(); 00439 00440 return ret; 00441 } 00442 00443 // ###################################################################### 00444 template <class T> 00445 Image<double> SurpriseImage<T>::getVar() const 00446 { 00447 Image<double> ret(this->getDims(), NO_INIT); 00448 00449 typename SurpriseImage<T>::const_iterator 00450 i = this->begin(), stop = this->end(); 00451 Image<double>::iterator r = ret.beginw(); 00452 00453 while(i != stop) *r++ = (i++)->getVar(); 00454 00455 return ret; 00456 } 00457 00458 // ###################################################################### 00459 // explicit instantiations: 00460 template class SurpriseImage<SurpriseModelSG>; 00461 template class SurpriseImage<SurpriseModelSP>; 00462 template class SurpriseImage<SurpriseModelSP1>; 00463 template class SurpriseImage<SurpriseModelSPC>; 00464 template class SurpriseImage<SurpriseModelSPF>; 00465 template class SurpriseImage<SurpriseModelCS>; 00466 template class SurpriseImage<SurpriseModelGG>; 00467 template class SurpriseImage<SurpriseModelPM>; 00468 template class SurpriseImage<SurpriseModelOD>; 00469 00470 // ###################################################################### 00471 /* So things look consistent in everyone's emacs... */ 00472 /* Local Variables: */ 00473 /* indent-tabs-mode: nil */ 00474 /* End: */