Weights.H

Go to the documentation of this file.
00001 /*!@file ModelNeuron/Weights.H Class A class to compute interactions
00002   between neurons. */
00003 
00004 // //////////////////////////////////////////////////////////////////// //
00005 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the //
00006 // University of Southern California (USC) and the iLab at USC.         //
00007 // See http://iLab.usc.edu for information about this project.          //
00008 // //////////////////////////////////////////////////////////////////// //
00009 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00010 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00011 // in Visual Environments, and Applications'' by Christof Koch and      //
00012 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00013 // pending; application number 09/912,225 filed July 23, 2001; see      //
00014 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00015 // //////////////////////////////////////////////////////////////////// //
00016 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00017 //                                                                      //
00018 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00019 // redistribute it and/or modify it under the terms of the GNU General  //
00020 // Public License as published by the Free Software Foundation; either  //
00021 // version 2 of the License, or (at your option) any later version.     //
00022 //                                                                      //
00023 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00024 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00025 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00026 // PURPOSE.  See the GNU General Public License for more details.       //
00027 //                                                                      //
00028 // You should have received a copy of the GNU General Public License    //
00029 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00030 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00031 // Boston, MA 02111-1307 USA.                                           //
00032 // //////////////////////////////////////////////////////////////////// //
00033 //
00034 // Primary maintainer for this file: David Berg <dberg@usc.edu>
00035 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/ModelNeuron/Weights.H $
00036 
00037 #ifndef MODELNEURON_WEIGHTS_H_DEFINED
00038 #define MODELNEURON_WEIGHTS_H_DEFINED
00039 
00040 #include "Image/Image.H"
00041 #include "Image/LowPassLpt.H"
00042 #include "Image/Convolutions.H"
00043 
00044 #include <vector>
00045 
00046 // ######################################################################
00047 // Policies for different weighting schemes to be used as a template
00048 // argument by Layer. A valid policy should have at least:
00049 //
00050 // a default constructor.
00051 // Image<double> compute(const Image<double>& in);
00052 // const bool initialized() const;
00053 //
00054 // All equations for the below classes are inspired by Neural Field
00055 // dynamics: Amari & Arbib, 77; Coombs, 05; Erlhagen & Bicho, 2006
00056 // ######################################################################
00057 
00058 // ######################################################################
00059 // A weight class that defines minimum interface and can be used virtually
00060 // ######################################################################
00061 struct Weights
00062 {
00063 public:
00064   Weights() : itsInit(false) { };
00065   virtual ~Weights() { };
00066   virtual Image<double> compute(const Image<double>& in) = 0;
00067   virtual Weights* clone() const = 0;
00068   virtual const bool initialized() const { return itsInit; };
00069 protected:
00070   bool itsInit;
00071 };
00072 
00073 // ######################################################################
00074 //! A class to derive from to create new Weightss. New
00075 //! Weights derived types can derive from this class to inherit
00076 //! the clone() function if desired.
00077 /*
00078   Programmer Note: This class uses the 'quriously recursive template
00079   pattern' to simplify creation of new classes for the programmer. As
00080   such, to create a new simulation module, classes should adhear the
00081   following convention:
00082   
00083   class mymodule : public WeightsDerived<mymodule>
00084   {
00085       mymodule(//params//) : Weights<mymodule>(//params//) { };
00086       //...rest of functions
00087   };
00088 */
00089 // ######################################################################
00090 template <class Derived>
00091 class WeightsDerived : public Weights
00092 {
00093 public:
00094   Weights* clone() const 
00095   { return new Derived(dynamic_cast<const Derived&>(*this)); };               
00096 protected:
00097   WeightsDerived() : Weights() { };
00098   virtual ~WeightsDerived() { };
00099 };
00100 
00101 
00102 // ######################################################################
00103 // A simple weights configuration that just multiplies the input by a
00104 // constant.
00105 // ######################################################################
00106 class WeightsEmpty : public WeightsDerived<WeightsEmpty>
00107 {
00108 public:
00109   //default constructor
00110   WeightsEmpty() : WeightsDerived<WeightsEmpty>() { itsInit = true; };
00111 
00112   //destructor
00113   ~WeightsEmpty() { };  
00114 
00115   //compute the spread of activity
00116   Image<double> compute(const Image<double>& in) {return Image<double>(in.getDims(), ZEROS); };
00117 };
00118 
00119 // ######################################################################
00120 // A weights configuration where the every neural connects to every
00121 // other neuron.
00122 // ######################################################################
00123 class WeightsAll : public WeightsDerived<WeightsAll>
00124 {
00125 public:
00126   //default constructor
00127   WeightsAll();
00128 
00129   //constructor
00130   WeightsAll(const double& weight);
00131 
00132   //destructor
00133   ~WeightsAll() { };  
00134 
00135   //compute the spread of activity
00136   Image<double> compute(const Image<double>& in);
00137   
00138 private:
00139   double itsW;
00140 };
00141 
00142 // ######################################################################
00143 // A simple weights configuration that just multiplies the input by a
00144 // constant.
00145 // ######################################################################
00146 class WeightsUniform : public WeightsDerived<WeightsUniform>
00147 {
00148 public:
00149   //default constructor
00150   WeightsUniform();
00151 
00152   //constructor
00153   WeightsUniform(const double& weight);
00154 
00155   //destructor
00156   ~WeightsUniform() { };  
00157 
00158   //compute the spread of activity
00159   Image<double> compute(const Image<double>& in);
00160 
00161 private:
00162   double itsW;
00163 };
00164 
00165 // ######################################################################
00166 // A weight configuration that uses a 1D binomial kernel
00167 //
00168 // Iterative seperable convolution is applied to achieve the desired
00169 // standard deviation. The output is then scaled so that the response
00170 // to an impulse is unity at the center. Self activation is optionally
00171 // subtracted. This object state is set to initialzed after
00172 // its first call.
00173 //
00174 // Several convolution strategies are supported. If the BorderType ==
00175 // 0, then clean convolution will be performed. The filter is
00176 // truncated and normalized at the image edge.
00177 
00178 // Other border types listed below, were designed for radially
00179 // transformed (RT) images that represent visual space in
00180 // hemifields. Only 3 and 5-tap binomial filtering is
00181 // implemented. Three boundary conditions are supported for these
00182 // images:
00183 //
00184 // 1) SEPARATE_HEMI 
00185 //   No hemifield interactions. Clean (normalized energy) border
00186 //   conditions apply at each hemifild in both directions.
00187 // 2) CROSS_HEMI
00188 //   Convolutions will cross hemifields in both the R (ring) and W
00189 //   (wedge) dirctions.
00190 // 3) CROSS_ANGLE
00191 //   Convolutions will only cross hemifields in the W (wedge)
00192 //   direction. Clean (normalized energy) border condition will be
00193 //   applied in the R (ring) dircection.
00194 // ######################################################################
00195 class WeightsBinomial  : public WeightsDerived<WeightsBinomial>
00196 {
00197 public:
00198   //default constructor
00199   WeightsBinomial();
00200 
00201   //constructor
00202   WeightsBinomial(const double& std,  const double& weight,
00203                   const bool doSubCenter, 
00204                   const BorderPolicy bp,
00205                   const uint taps = 3);
00206   //destructor
00207   ~WeightsBinomial() { };  
00208 
00209   //compute the spread of activity
00210   Image<double> compute(const Image<double>& in);
00211   
00212 private:
00213   uint itsTaps;
00214   uint itsIter;
00215   bool subCenter;
00216   double itsCenter;
00217   double itsWeight;
00218   BorderPolicy itsBp;
00219   bool itsSetup;
00220 };
00221 
00222 // ######################################################################
00223 // a simple center surround pattern using a gaussian minus a constant
00224 // ######################################################################
00225 class WeightsCS  : public WeightsDerived<WeightsCS>
00226 {
00227 public:
00228   //default constructor
00229   WeightsCS();
00230 
00231   //constructor
00232   WeightsCS(const double& estd, const double& eweight, 
00233             const double& inhibit, const bool doSubCenter,
00234             const BorderPolicy bp, const uint taps = 3);
00235   
00236   //destructor
00237   ~WeightsCS() { };  
00238 
00239   //compute the spread of activity
00240   Image<double> compute(const Image<double>& in);
00241 
00242 private:
00243   WeightsBinomial itsW;
00244   double itsInh;
00245 };
00246 
00247 // ######################################################################
00248 // A weight configuration that uses 1D binomial kernels to approximate
00249 // a difference of gaussians
00250 //
00251 // Iterative seperable convolution is applied to achieve the desired
00252 // standard deviation. The output is then scaled so that the response
00253 // to an impulse is the desired weight. 
00254 // ######################################################################
00255 class WeightsDoG  : public WeightsDerived<WeightsDoG>
00256 {
00257 public:
00258   //default constructor
00259   WeightsDoG();
00260 
00261   //constructor
00262   WeightsDoG(const double& estd, const double& istd,  
00263              const double& eweight, const double& iweight,
00264              const bool subCenter, const BorderPolicy bp,
00265              const uint taps = 3);
00266   //destructor
00267   ~WeightsDoG() { };  
00268 
00269   //compute the spread of activity
00270   Image<double> compute(const Image<double>& in);
00271   
00272 private:
00273   WeightsBinomial itsE, itsI;
00274 };
00275 
00276 // ######################################################################
00277 // A weight configuration that uses 1D seperable kernels
00278 //
00279 // If more than one filter set (x and y filters) is added then filters
00280 // are applied in the order they were added and other processing (such
00281 // as subtracting self activation).
00282 // ######################################################################
00283 class Weights1D : public WeightsDerived<Weights1D>
00284 {
00285 public:
00286   //default constructor
00287   Weights1D();
00288 
00289   //constructor
00290   Weights1D(const bool doSubCenter,
00291             const ConvolutionBoundaryStrategy strat = CONV_BOUNDARY_CLEAN);
00292   
00293   //destructor
00294   ~Weights1D() { };  
00295   
00296   //add a kernel to the bank, to be used in both x and y direction
00297   void addWeight(const Image<double>& wxy);
00298 
00299   //add the kernels to be used in the x and y direction
00300   void addWeight(const Image<double>& wx, const Image<double>& wy);
00301 
00302   //!clear our weights  
00303   void clear();
00304 
00305   //compute weighted output
00306   Image<double> compute(const Image<double>& in);
00307   
00308 private:
00309   bool subCenter;
00310   double itsCenter;
00311   ConvolutionBoundaryStrategy itsStrat;
00312   std::vector<Image<double> > itsX;
00313   std::vector<Image<double> > itsY;
00314   bool itsSetup;
00315 };
00316 
00317 // ######################################################################
00318 // A weight configuration that uses a 2D kernel
00319 //
00320 // If more than one filter is added the filter are applied in the order
00321 // they were added.
00322 //######################################################################
00323 class Weights2D  : public WeightsDerived<Weights2D>
00324 {
00325 public:
00326   //constructor
00327   Weights2D(const ConvolutionBoundaryStrategy strat = CONV_BOUNDARY_CLEAN);
00328   
00329   //destructor
00330   ~Weights2D() { };  
00331 
00332   //add a kernel to the bank
00333   void addWeight(const Image<double>& w);
00334   
00335   //!clear our weights  
00336   void clear();
00337   
00338   //compute weighted output
00339   Image<double> compute(const Image<double>& in);
00340 
00341 private:
00342   ConvolutionBoundaryStrategy itsStrat;
00343   std::vector<Image<double> > itsW;
00344 };
00345 
00346 // ######################################################################
00347 // A weight configuration that uses a Mask
00348 //
00349 // In this weight scheme the connection pattern is fully
00350 // specified. That means that you must add a seperate Image<double>
00351 // for each pixels which describes which other pixels contribute to
00352 // its response. The objects state is set to initialzed when the
00353 // object is constructed, but calls to compute will return images of
00354 // zeros unless one weight mask has been added for every pixel in the
00355 // input.
00356 // ######################################################################
00357 class WeightsMask  : public WeightsDerived<WeightsMask>
00358 {
00359 public:
00360   //constructor
00361   WeightsMask();
00362 
00363   //destructor
00364   ~WeightsMask() { };  
00365   
00366   //add a kernel to the bank
00367   void addWeight(const Image<double>& w);
00368   
00369   //!clear our weights  
00370   void clear();
00371   
00372   //compute weighted output
00373   Image<double> compute(const Image<double>& in);
00374 
00375 private:
00376   std::vector<Image<double> > itsW;
00377 };
00378 
00379 // ######################################################################
00380 //helper functions
00381 // ######################################################################
00382 
00383 // for weights that use binomial
00384 Image<double> filterBinomial(const Image<double>& in, const uint iterations, 
00385                              const uint taps, const BorderPolicy bp);
00386 
00387 //print the impulse response of a weight 
00388 template<class W>
00389 void printImpulse(const uint w, const uint h,  W& weights);
00390 
00391 //print the image 
00392 void printImage(const Image<double>& in);
00393 
00394 
00395 #endif
00396 
00397 // ######################################################################
00398 /* So things look consistent in everyone's emacs... */
00399 /* Local Variables: */
00400 /* indent-tabs-mode: nil */
00401 /* End: */
Generated on Sun May 8 08:41:02 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3