SingleChannel.H

Go to the documentation of this file.
00001 /*!@file Channels/SingleChannel.H Channel for a single stream of processing. */
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: Rob Peters <rjpeters@klab.caltech.edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Channels/SingleChannel.H $
00035 // $Id: SingleChannel.H 14632 2011-03-23 20:08:44Z dberg $
00036 //
00037 
00038 #ifndef SINGLECHANNEL_H_DEFINED
00039 #define SINGLECHANNEL_H_DEFINED
00040 
00041 #include "Channels/ChannelBase.H"
00042 #include "Channels/ChannelFacet.H"
00043 #include "Channels/InputHandler.H"
00044 #include "Channels/SubmapAlgorithm.H"
00045 #include "Component/ModelParam.H"
00046 #include "Image/ImageSet.H"
00047 #include "Image/LevelSpec.H"
00048 #include "Image/PyrBuilder.H"
00049 #include "Image/fancynorm.H" // for MaxNormType
00050 #include "Util/SimTime.H"
00051 #include "rutz/shared_ptr.h"
00052 #include <deque>
00053 
00054 // ######################################################################
00055 //! SingleChannel represents a single stream of processing.
00056 /*! The processing is implemented by an internal PyrBuilder object of some
00057     kind. */
00058 class SingleChannel : public ChannelBase, public ChannelFacetMap
00059 {
00060 public:
00061   //! Constructor. See ChannelBase.H
00062   /*! @param mgr our ModelManager (see ModelManager.H)
00063       @param descrName descriptive name for human usage
00064       @param tagName name for ParamMap usage
00065       @param vs The VisualFeature implemented by the channel
00066       @param pyr The type of pyramid that should be used. */
00067   SingleChannel(OptionManager& mgr, const std::string& descrName,
00068                 const std::string& tagName, const VisualFeature vs,
00069                 rutz::shared_ptr<PyrBuilder<float> > pyr);
00070 
00071   //! destructor
00072   virtual ~SingleChannel();
00073 
00074   //! Reset SingleChannel
00075   /*! See the base function in ModelComponent.H for info. */
00076   virtual void reset1();
00077 
00078   /// Calls visitSingleChannel() on the ChannelVisitor.
00079   virtual void accept(ChannelVisitor& v);
00080 
00081   //! Overload so that we can reconfigure when our params get changed
00082   virtual void paramChanged(ModelParamBase* const param,
00083                             const bool valueChanged,
00084                             ParamClient::ChangeStatus* status);
00085 
00086   //! Send an already computed pyramid as input to the channel.
00087   void inputPyramid(const ImageSet<float>& pyramid, const SimTime& t,
00088                     const Image<byte>& clipMask = Image<byte>());
00089 
00090   //! Computes the channel's pyramid but doesn't store it
00091   virtual ImageSet<float> computePyramid(const Image<float>& bwimg,
00092                                          const rutz::shared_ptr<PyramidCache<float> >& cache);
00093 
00094   virtual void readFrom(const ParamMap& pmap);
00095 
00096   virtual void writeTo(ParamMap& pmap) const;
00097 
00098   //! Set the template that will be applied to the submap
00099   void setTempl(const uint cntr, const uint surr, Image<float> &templ);
00100 
00101   //! Set the mask that will be applied to the submap
00102   void setBiasMask(Image<float> &biasMask);
00103 
00104   //! Set the mask that will be applied to the submap
00105   Image<float> getBiasMask() const;
00106 
00107   //! Get the template that is beeing applied to the submap
00108   Image<float> getTempl(const uint cntr, const uint surr) const;
00109 
00110   virtual bool outputAvailable() const;
00111 
00112   //! do we have any input pyramids in our queue?
00113   bool hasPyramid() const;
00114 
00115   //! have we already computed and cached the current output?
00116   bool hasOutputCache() const;
00117 
00118   virtual Dims getMapDims() const;
00119 
00120   //! Get the image from the given level of the internal pyramid
00121   virtual const Image<float>& getImage(const uint lev) const;
00122 
00123   //! Get the center/surround image for the given levels
00124   virtual Image<float> centerSurround(const uint cntr, const uint surr) const;
00125 
00126   //! Get the center/surround, split into positive and negative parts
00127   virtual void centerSurround(const uint cntr, const uint surr,
00128                               Image<float>& pos, Image<float>& neg) const;
00129 
00130   virtual uint numSubmaps() const;
00131 
00132   //! This is just a caching wrapper around computeSubmap()
00133   virtual Image<float> getSubmap(const uint index) const;
00134 
00135   virtual std::string getSubmapName(const uint index) const;
00136 
00137   virtual std::string getSubmapNameShort(const uint index) const;
00138 
00139   virtual void getFeatures(const Point2D<int>& locn,
00140                            std::vector<float>& mean) const;
00141 
00142   virtual void getFeaturesBatch(std::vector<Point2D<int>*> *locn,
00143                                 std::vector<std::vector<float> > *mean,
00144                                 int *count) const;
00145 
00146   //! save basic stats for single channel
00147   void saveStats(const Image<float> img, const short idx);
00148 
00149   //! This is just a caching wrapper around combineSubMaps()
00150   virtual Image<float> getOutput();
00151 
00152   //! Combine all feature maps into a single output map
00153   virtual Image<float> combineSubMaps();
00154 
00155   //! Save our various maps using an FrameOstream
00156   /*! Depending on our ModelParam settings, we can save raw pyramid
00157     levels (with name prefix "SR<tagname>-<level>-"), center-surround
00158     feature maps ("SF<tagname>-<ctr>-<surr>-"), and output map
00159     ("SO<tagname>-") */
00160   virtual void saveResults(const nub::ref<FrameOstream>& ofs);
00161 
00162   //! Get the number of pyramids in our queue
00163   size_t numPyramids() const;
00164 
00165   //! Access to the underlying pyramid is provided for completeness.
00166   /*! However, it probably shouldn't need to be used except for testing,
00167       debugging, etc. Instead, the Channel interface should be used or
00168       extended to fill the specific need.
00169       @param index The index in the queue (0 = newest, qlen-1 = oldest). */
00170   const ImageSet<float>& pyramid(const uint index) const;
00171 
00172   //! Access to the underlying pyramid times is provided for completeness.
00173   /*! However, it probably shouldn't need to be used except for testing,
00174       debugging, etc. Instead, the Channel interface should be used or
00175       extended to fill the specific need.
00176       @param index The index in the queue (0 = newest, qlen-1 = oldest). */
00177   SimTime pyramidTime(const uint index) const;
00178 
00179   //! Access to the underlying clipPyramid
00180   const ImageSet<float>& clipPyramid() const;
00181 
00182   //! get our the LevelSpec
00183   virtual LevelSpec getLevelSpec() const;
00184 
00185   //! get our NormType:
00186   int getNormType() const;
00187 
00188   //! SingleChannel implements this to clear its cached output.
00189   virtual void killCaches();
00190 
00191   //! a time-stamped pyramid
00192   struct TPyr
00193   {
00194     TPyr(const ImageSet<float>& pyr_, const SimTime t_)
00195       : pyr(pyr_), t(t_) {}
00196     ImageSet<float> pyr; //!< the pyramid
00197     SimTime t;           //!< the timestamp
00198   };
00199 
00200   //! Store m as the output map
00201   void storeOutputCache(const Image<float>& m);
00202 
00203   //! Stores p as the channel's pyramid at time t
00204   virtual void storePyramid(const ImageSet<float>& p, const SimTime& t);
00205 
00206   //! Store p as the channel's clip pyramid
00207   void storeClipPyramid(const ImageSet<float>& p);
00208 
00209   //! make the clipping pyramid from the clip mask
00210   virtual void setClipPyramid(const Image<byte>& clipMask);
00211 
00212   //! Store p as the channel's submap cache
00213   void storeSubmapCache(const ImageSet<float>& p);
00214 
00215   //! Install an input handler
00216   void setInputHandler(rutz::shared_ptr<InputHandler> h);
00217 
00218   //! Get a cloned copy of our input handler
00219   rutz::shared_ptr<InputHandler> cloneInputHandler() const;
00220 
00221   //! get raw CS map; part of getSubmap()
00222   virtual Image<float> getRawCSmap(const uint idx) const;
00223 
00224   //! rescale and post-process raw CS map; part of default getSubMap()
00225   Image<float> postProcessMap(const Image<float>& smap,
00226                               const uint idx) const;
00227 
00228   //! Install a new submap algorithm
00229   void setSubmapAlgorithm(nub::ref<SubmapAlgorithm> algo);
00230 
00231   void setComputeFullPyramid(bool v)
00232   { itsComputeFullPyramid.setVal(v); }
00233 
00234   virtual int getMinPyrLevel() const
00235   {
00236     // If we want to save our raw pyramid maps, or otherwise need a
00237     // full pyramid, then let's compute the pyramid in full starting
00238     // from level 0; otherwise, we can skip the levels below our
00239     // LevelSpec's levMin():
00240     return (itsSaveRawMaps.getVal() || itsComputeFullPyramid.getVal() ||
00241             itsComputeFullPyramidForGist.getVal() )  ? 0 : itsLevelSpec.getVal().levMin();
00242   }
00243 
00244   virtual int getMaxPyrLevel() const { return itsLevelSpec.getVal().maxDepth(); }
00245 
00246 protected:
00247   //! SingleChannel requires only luminance input
00248   virtual void doInput(const InputFrame& inframe);
00249 
00250   //! Change to use a different pyramid object.
00251   void setPyramid(rutz::shared_ptr<PyrBuilder<float> > pyr);
00252 
00253   //! Mutable access to underlying pyramid
00254   ImageSet<float>& pyrMut(const uint index);
00255 
00256   NModelParam<bool> itsTakeAbs;
00257   NModelParam<bool> itsNormalizeOutput;
00258   NModelParam<bool> itsScaleNoiseToMax;
00259   NModelParam<float> itsLowThresh;
00260   NModelParam<bool> itsRectifyPyramid;
00261   NModelParam<bool> itsComputeFullPyramid;
00262 
00263   OModelParam<bool> itsUseRandom;
00264   OModelParam<bool> itsUseSplitCS;
00265   OModelParam<LevelSpec> itsLevelSpec;
00266   OModelParam<MaxNormType> itsNormType;
00267   OModelParam<int> itsQlen;
00268   OModelParam<bool> itsUseOlderVersion;
00269 
00270   //! Time decay for the contribution of differences in the pyramid queue.
00271   /*! This decay will yield a factor fac = exp( (t2 - t) * decay)
00272     applied to the difference image between t (current time, in
00273     seconds) and t2 (time of previous image, in seconds): */
00274   OModelParam<double> itsTimeDecay;
00275 
00276   //! Save our raw pyramid levels?
00277   OModelParam<bool> itsSaveRawMaps;
00278 
00279   //! save our raw pyramid levels for the gist computation?
00280   OModelParam<bool> itsComputeFullPyramidForGist;
00281 
00282   //! Save our center-surround feature maps?
00283   OModelParam<bool> itsSaveFeatureMaps;
00284 
00285   //! Save our output map?
00286   OModelParam<bool> itsSaveOutputMap;
00287 
00288   //! Type name for our SubmapAlgorithm
00289   OModelParam<std::string> itsSubmapAlgoType;
00290 
00291   //! Save basic single channel stats after combineSubMaps
00292   OModelParam<bool> itsGetSingleChannelStats;
00293 
00294   //! If saving stats, should we put each feature in its own file?
00295   OModelParam<bool> itsSaveStatsPerChannel;
00296 
00297   //! Should we save frequency information per channel?
00298   OModelParam<bool> itsSaveStatsPerChannelFreq;
00299 
00300   //! File name for single channel stats after combineSubMaps
00301   OModelParam<std::string> itsGetSingleChannelStatsFile;
00302 
00303   //! Tag name for single channel stats after combineSubMaps
00304   OModelParam<std::string> itsGetSingleChannelStatsTag;
00305 
00306   //! Set a fixed range of values for the raw output
00307   /*! By default, the range is set to [MAXNORMMIN .. MAXNORMMAX] at
00308     construction. If non-zero values are provided here, in getOutput()
00309     we will cumulate our various submaps, apply the provided range,
00310     apply spatial competition for salience, apply our total weight,
00311     and return the result. If a range [0.0 .. 0.0] is provided here,
00312     only spatial competition and weights will be applied, but the
00313     first step of applying the range will be skipped. This must be
00314     called before start(). */
00315   OModelParam<float> itsOutputRangeMin;
00316   OModelParam<float> itsOutputRangeMax;
00317 
00318   // get us started (see ModelComponent.H)
00319   /*! If you overload this, make sure you call SingleChannel::start1()
00320     at the beginning of your overload */
00321   virtual void start1();
00322 
00323   // get us stopped (see ModelComponent.H)
00324   /*! If you overload this, make sure you call SingleChannel::start1()
00325     at the beginning of your overload */
00326   virtual void stop2();
00327 
00328   // shortcut to the csToIndex function of itsLevelSpec:
00329   virtual uint csToIndex(uint centerlev, uint surroundlev) const;
00330 
00331   // shortcut to the indexToCS function of itsLevelSpec:
00332   virtual void indexToCS(const uint index, uint& centerlev, uint& surroundlev) const;
00333 
00334   // shortcut to maxIndex function in itsLevelSpec
00335   virtual uint maxIndex() const;
00336 
00337 private:
00338   SingleChannel(const SingleChannel&); // not allowed
00339   SingleChannel& operator=(const SingleChannel&); // not allowed
00340 
00341   std::deque<TPyr>               itsPq; // temporal queue of pyramids
00342   Image<float>                   itsBiasMask;   // to bias the channel based on a mask
00343 
00344   uint                           itsFrameIdx; // for logging purposes
00345   Image<float>                   itsOutputCache;
00346   Image<float>*                  itsSubmapCache;
00347   ImageSet<float>                itsTempl; // the templates at each submap level
00348   rutz::shared_ptr<PyrBuilder<float> >  itsPyrBuilder;
00349   ImageSet<float>                itsClipPyr;
00350   rutz::shared_ptr<InputHandler>        itsInputHandler;
00351   nub::ref<SubmapAlgorithm>      itsSubmapAlgo;
00352 
00353   friend class OrientationChannel; // this one too
00354   friend class RGBConvolveChannel; // this one messes with itsPyrBuilder
00355 };
00356 
00357 
00358 /* So things look consistent in everyone's emacs... */
00359 /* Local Variables: */
00360 /* indent-tabs-mode: nil */
00361 /* End: */
00362 
00363 #endif // !SINGLECHANNEL_H_DEFINED
Generated on Sun May 8 08:04:41 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3