VisualBuffer.H

Go to the documentation of this file.
00001 /*!@file Neuro/VisualBuffer.H Grab ausio samples from /dev/dsp */
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: Laurent Itti <itti@usc.edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Neuro/VisualBuffer.H $
00035 // $Id: VisualBuffer.H 10779 2009-02-06 01:36:27Z itti $
00036 //
00037 
00038 #ifndef VISUALBUFFER_H_DEFINED
00039 #define VISUALBUFFER_H_DEFINED
00040 
00041 #include "Component/ModelComponent.H"
00042 #include "Component/ModelParam.H"
00043 #include "Image/Image.H"
00044 #include "Image/LevelSpec.H"
00045 #include "Image/fancynorm.H"
00046 #include "Neuro/WTAwinner.H"
00047 #include "Neuro/NeuroSimEvents.H"
00048 #include "Simulation/SimModule.H"
00049 #include "Util/SimTime.H"
00050 #include "Util/Types.H"
00051 
00052 // ######################################################################
00053 //! An integrative visual buffer, base class
00054 // ######################################################################
00055 /*! A world-centered Visual Buffer to accumulate interesting locations
00056   (each time a covert attention shift occurs), with internal
00057   competitive dynamics within the buffer. Base class does nothing. */
00058 class VisualBuffer : public SimModule
00059 {
00060 public:
00061   //! Constructor
00062   VisualBuffer(OptionManager& mgr,
00063                const std::string& descrName = "Visual Buffer",
00064                const std::string& tagName = "VisualBuffer");
00065 
00066   //! Destructor
00067   virtual ~VisualBuffer();
00068 };
00069 
00070 // ######################################################################
00071 //! An integrative visual buffer, stub implementation, does nothing
00072 // ######################################################################
00073 class VisualBufferStub : public VisualBuffer
00074 {
00075 public:
00076   //! Constructor
00077   VisualBufferStub(OptionManager& mgr,
00078                const std::string& descrName = "Visual Buffer Stub",
00079                const std::string& tagName = "VisualBufferStub");
00080 
00081   //! Destructor
00082   virtual ~VisualBufferStub();
00083 };
00084 
00085 // ######################################################################
00086 //! VisualBuffer configurator
00087 // ######################################################################
00088 /*! This will export the --vb-type=XX command-line option and will
00089   instantiate a VisualBuffer of the desired type as the option gets assigned a
00090   value. As this happens, new options may become available in the
00091   command-line. To see them, use --help AFTER you have chosen the type
00092   to use. The current VB may be retrieved using getVB(). */
00093 class VisualBufferConfigurator : public ModelComponent
00094 {
00095 public:
00096   //! Constructor
00097   VisualBufferConfigurator(OptionManager& mgr,
00098                           const std::string& descrName = "Visual Buffer Configurator",
00099                           const std::string& tagName = "VisualBufferConfigurator");
00100 
00101   //! destructor
00102   virtual ~VisualBufferConfigurator();
00103 
00104   //! Get the chosen VB
00105   /*! You should call this during start() of the ModelComponent that
00106       needs the VB. NOTE: this will never return a null pointer (since
00107       it's a nub::ref rather than a nub::soft_ref), but it may return
00108       a "stub" object (e.g. VisualBufferStub). */
00109   nub::ref<VisualBuffer> getVB() const;
00110 
00111 protected:
00112   OModelParam<std::string> itsVBtype; //!< type of buffer
00113 
00114   //! Intercept people changing our ModelParam
00115   /*! See ModelComponent.H; as parsing the command-line or reading a
00116     config file sets our name, we'll also here instantiate a
00117     buffer of the proper type (and export its options) */
00118   virtual void paramChanged(ModelParamBase* const param,
00119                             const bool valueChanged,
00120                             ParamClient::ChangeStatus* status);
00121 
00122 private:
00123   nub::ref<VisualBuffer> itsVB; // the buffer
00124 };
00125 
00126 // ######################################################################
00127 //! An integrative visual buffer, std implementation
00128 // ######################################################################
00129 /*! A world-centered Visual Buffer to accumulate interesting locations
00130   (each time a covert attention shift occurs), with internal
00131   competitive dynamics within the buffer. */
00132 class VisualBufferStd : public VisualBuffer
00133 {
00134 public:
00135   //! Constructor
00136   VisualBufferStd(OptionManager& mgr,
00137                const std::string& descrName = "Visual Buffer",
00138                const std::string& tagName = "VisualBuffer");
00139 
00140   //! Destructor
00141   virtual ~VisualBufferStd();
00142 
00143 protected:
00144   //! Callback for every agm
00145   SIMCALLBACK_DECLARE(VisualBufferStd, SimEventAttentionGuidanceMapOutput);
00146 
00147   //! Callback for every agm
00148   SIMCALLBACK_DECLARE(VisualBufferStd, SimEventRetinaImage);
00149 
00150   //! New input
00151   /*! Beware that the inputs here are matched to what Brain naturally
00152     provides, which is
00153     @param win the coordinates of an atteention shift at retinal resolution
00154     @param sm the saliency map at the maplevel resolution
00155     @param objmask a mask with (if initialized) the shape of the attended
00156     object at retinal resolution. */
00157   void input(const WTAwinner& win, const Image<float>& sm, const Image<byte>& objmask);
00158 
00159   //! Get saliency mask
00160   /*! This is mostly for display purposes. The mask is the one that
00161     was created at the last input() and has the same size/scale as the
00162     saliency map and is in retinal coordinates */
00163   Image<byte> getSaliencyMask() const;
00164 
00165   //! Get current buffer
00166   Image<float> getBuffer() const;
00167 
00168   //! evolve our internal dynamics
00169   void evolve(SimEventQueue& q);
00170 
00171   //! inhibit a location, given in retinotopic/retinal-scale coords
00172   /*! A disk of radius FOAradius will be used for inhibition */
00173   void inhibit(const Point2D<int>& loc);
00174 
00175   //! inhibit a location, using a mask of same dims/scale as the buffer
00176   /*! @param mask should have same dims as the buffer, and values
00177     between 0.0 (no inhibition) and 1.0 (full inhibition). */
00178   void inhibit(const Image<float>& mask);
00179 
00180   //! Decide on most interesting target location given current eye position
00181   /*! All coordinates are in world-centered/sm-scale. The algorithm
00182     used here is inspired from the area activation model; we threshold
00183     out regions lower than a fraction of the maximum activation, then
00184     aim for the centroid of the region that is closest to current eye
00185     position. */
00186   Point2D<int> findMostInterestingTarget(const Point2D<int>& p);
00187 
00188   //! Decide on most interesting target location given current eye position
00189   /*! All coordinates are in world-centered/sm-scale. The algorithm
00190     used here will aim for the local max above a threshold that is
00191     closest to current eye position. */
00192   Point2D<int> findMostInterestingTargetLocMax(const Point2D<int>& p);
00193 
00194   //! transform coord from retinotopic/retinal-scale to world-centered/sm-scale
00195   Point2D<int> retinalToBuffer(const Point2D<int>& p) const;
00196 
00197   //! transform coord from world-centered/sm-scale to retinotopic/retinal-scale
00198   Point2D<int> bufferToRetinal(const Point2D<int>& p) const;
00199 
00200   //! are we object-based?
00201   bool isObjectBased() const;
00202 
00203   OModelParam<int> itsFOAradius;        //!< FOA radius
00204   OModelParam<bool> itsIgnoreBoring;   //!< ignore boring attention shifts
00205   OModelParam<bool> itsObjectBased;    //!< true if doing object-based
00206   OModelParam<Dims> itsBufferDims;     //!< dims of our internal buffer
00207   OModelParam<LevelSpec> itsLevelSpec; //!< levelspec determines buffer scale
00208   OModelParam<Dims> itsInputDims;      //!< input image dims
00209   OModelParam<SimTime> itsTimePeriod;   //!< period at which to apply interaction
00210   OModelParam<float> itsDecayFactor;   //!< temporal decay factor
00211   OModelParam<MaxNormType> itsNormType;//!< maxnorm type for our internals
00212 
00213   //! get started (see ModelComponent.H)
00214   void start1();
00215 
00216 private:
00217   // apply one iteration of our internal dynamics
00218   void internalDynamics();
00219 
00220   Image<float> itsBuffer;
00221   Dims itsSMdims;
00222   Image<byte> itsSaliencyMask;
00223   SimTime itsTime;
00224   SimTime itsLastInteractTime;
00225   Point2D<int> itsRetinaOffset;
00226 };
00227 
00228 
00229 // ######################################################################
00230 //! Helper function to transform from buffer to retinal coordinates
00231 /*! You normally would not use this function directly, but rather
00232     VisualBufferStd::bufferToRetinal() or
00233     SimEventVisualBufferOutput::bufferToRetinal(). This function is
00234     here mostly so that both implementations of bufferToRetinal are
00235     always consistent. */
00236 inline Point2D<int> visualBufferToRetinal(const Point2D<int>& p, const Point2D<int>& retinaOffset,
00237                                           const int smlev, const Dims& smdims, const Dims& bufdims)
00238 {
00239   // re-center out of the larger visual buffer:
00240   Point2D<int> pp = p - Point2D<int>((bufdims.w() - smdims.w()) / 2, (bufdims.h() - smdims.h()) / 2);
00241 
00242   // scale back up to retinal scale (we do like in WTAwinner.H):
00243   pp.i <<= smlev; pp.j <<= smlev;
00244 
00245   // then add our current eye position. Caution: make sure this is like rawToRetinal():
00246   pp += retinaOffset;
00247 
00248   return pp;
00249 }
00250 
00251 // ######################################################################
00252 //! Helper function to transform from buffer to retinal coordinates
00253 /*! You normally would not use this function directly. */
00254 inline Point2D<int> retinalToVisualBuffer(const Point2D<int>& p, const Point2D<int>& retinaOffset,
00255                                           const int smlev, const Dims& smdims, const Dims& bufdims)
00256 {
00257   // first subtract our current eye position. Caution: Make sure this is the same as retinalToRaw():
00258   Point2D<int> pp = p - retinaOffset;
00259 
00260   // then downscale to maplevel (we do like in WTAwinner.H, but no random jitter):
00261   pp.i = int(pp.i / double(1 << smlev) + 0.49);
00262   pp.j = int(pp.j / double(1 << smlev) + 0.49);
00263 
00264   // then re-center into the larger visual buffer:
00265   pp += Point2D<int>((bufdims.w() - smdims.w()) / 2, (bufdims.h() - smdims.h()) / 2);
00266 
00267   return pp;
00268 }
00269 
00270 #endif
00271 
00272 // ######################################################################
00273 /* So things look consistent in everyone's emacs... */
00274 /* Local Variables: */
00275 /* indent-tabs-mode: nil */
00276 /* End: */
Generated on Sun May 8 08:05:26 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3