00001 /*!@file Channels/ComplexChannel.H Channel class that pools across multiple 00002 subchannels. */ 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: Rob Peters <rjpeters@klab.caltech.edu> 00035 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Channels/ComplexChannel.H $ 00036 // $Id: ComplexChannel.H 14487 2011-02-08 18:57:45Z dberg $ 00037 // 00038 00039 #ifndef COMPLEXCHANNEL_H_DEFINED 00040 #define COMPLEXCHANNEL_H_DEFINED 00041 00042 #include "Channels/ChannelBase.H" 00043 #include "Channels/ChannelFacet.H" 00044 #include "Channels/MapCombineType.H" 00045 #include "Image/Image.H" 00046 #include "Image/fancynorm.H" // for MaxNormType 00047 00048 // ###################################################################### 00049 //! A an abstract channel class that pools across several subchannels. 00050 class ComplexChannel : public ChannelBase, public ChannelFacetMap 00051 { 00052 public: 00053 /// Refer to a subchannel by one of: its index, its tagname, its address 00054 /** Only one of the pieces of information will be valid. Inside the 00055 ComplexChannel functions that use SubchanKey, we will determine 00056 which one of the keys is the valid one, and use that one to look 00057 up the subchannel itself. */ 00058 struct SubchanKey 00059 { 00060 /// Initialize with an integer index 00061 SubchanKey(uint i) : index(i), tag(0), addr(0) {} 00062 00063 /// Initialize with a tag name 00064 SubchanKey(const char* t) : index(uint(-1)), tag(t), addr(0) {} 00065 00066 /// Initialize with a channel reference 00067 SubchanKey(ChannelBase& c) : index(uint(-1)), tag(0), addr(&c) {} 00068 00069 uint index; 00070 const char* tag; 00071 ChannelBase* addr; 00072 }; 00073 00074 //! Constructor. 00075 /*! @param mgr our ModelManager (see ModelManager.H) 00076 @param descrName descriptive name for human usage 00077 @param tagName name for ParamMap usage 00078 @param vs The VisualFeature implemented by the channel */ 00079 ComplexChannel(OptionManager& mgr, const std::string& descrName, 00080 const std::string& tagName, const VisualFeature vs); 00081 00082 //! Virtual destructor. 00083 virtual ~ComplexChannel(); 00084 00085 /// Calls visitComplexChannel() on the ChannelVisitor. 00086 virtual void accept(ChannelVisitor& v); 00087 00088 //! Is the channel homogeneous? 00089 /*! A homogeneous channel is one whose subchannels (and their subs) 00090 have identical VisualFeatures, and those are also identical to our 00091 VisualFeature. Default implementation returns true. */ 00092 virtual bool isHomogeneous() const; 00093 00094 //! Get the number of subchannels. 00095 uint numChans() const; 00096 00097 //! Look up one of the subchannels by its integer index. 00098 nub::ref<ChannelBase> subChan(const uint idx) const; 00099 00100 //! Look up one of the subchannels by its tagname 00101 nub::ref<ChannelBase> subChan(const std::string& tagname) const; 00102 00103 //! Look up one of the subchannels by a submap number 00104 /*!@param oldIdx - the submap index (in the ComplexChannel); 00105 @param newIdx - return value: the number of the submap within 00106 the subchannel*/ 00107 nub::ref<ChannelBase> subChanFromSubmapNum(const uint oldIdx, 00108 uint& newIdx) const; 00109 00110 //! Add a subchannel 00111 /*! @param ch The channel to be added 00112 @param name If not null, the channel's tagName will be set to 00113 this value 00114 @param weight Equivalent to calling setSubchanTotalWeight() on 00115 the newly-added channel 00116 @param exportOpts Whether to call exportOptions(MC_RECURSE) on 00117 the newly-added channel 00118 00119 The channel's tagName is used for associative lookup. 00120 00121 This is just a wrapper to ModelComponent::addSubComponent(), 00122 with some checking that the subcomponent indeed is a ChannelBase 00123 derivative, and some adjustment of our homogeneity (if the newly 00124 added subchannel has a different VisualFeature from ours, then 00125 be become heterogeneous). */ 00126 void addSubChan(nub::ref<ChannelBase> ch, const char* name = 0, 00127 const double weight = 1.0, 00128 bool exportOpts = false); 00129 00130 /// Remove a subchannel 00131 void removeSubChan(nub::ref<ChannelBase> ch); 00132 00133 /// Remove all of our subchannels 00134 void removeAllSubChans(); 00135 00136 /// Check if we have a channel of given tagname 00137 bool hasSubChan(const char* name) const; 00138 00139 /// Install a visitor which will be applied to all newly-added subchannels. 00140 void setSubchanVisitor(rutz::shared_ptr<ChannelVisitor> v); 00141 00142 //! Set the total weight allocated to the specified subchannel. 00143 /*! This weight will be divided amongst any sub-subchannels managed 00144 by the specifed subchannel. So, for example, if the total weight 00145 is set to 2.0, and the subchannel has four sub-subchannels, then 00146 each sub-subchannel will get an effective weight of 0.5. The 00147 initial weight setting is 1.0. But, If you are handling b/w 00148 images, for instance, you may set the weight for the color 00149 channel to 0.0 and save computations. */ 00150 void setSubchanTotalWeight(SubchanKey key, const double wt); 00151 00152 //! Return the total weight allocated to the specified subchannel. 00153 double getSubchanTotalWeight(SubchanKey key) const; 00154 00155 /// Whether to sort subchannels by their number of submaps. 00156 /** If true, this may help in parallel-processing situations where 00157 we want to start the most CPU-intensive channels first. 00158 00159 Must be called before start(). 00160 */ 00161 void sortChannelsByNumSubmaps(bool dosort); 00162 00163 virtual void readFrom(const ParamMap& pmap); 00164 00165 virtual void writeTo(ParamMap& pmap) const; 00166 00167 virtual bool outputAvailable() const; 00168 00169 virtual Dims getMapDims() const; 00170 00171 virtual uint numSubmaps() const; 00172 00173 virtual Image<float> getSubmap(const uint index) const; 00174 00175 //! get raw CS map; part of getSubmap() 00176 virtual Image<float> getRawCSmap(const uint idx) const; 00177 00178 virtual std::string getSubmapName(const uint index) const; 00179 00180 virtual std::string getSubmapNameShort(const uint index) const; 00181 00182 00183 virtual void getFeatures(const Point2D<int>& locn, 00184 std::vector<float>& mean) const; 00185 00186 virtual void getFeaturesBatch(std::vector<Point2D<int>*> *locn, 00187 std::vector<std::vector<float> > *mean, 00188 int *count) const; 00189 00190 //! Form output by combining output of subchannels. 00191 /*! This function just provides a caching wrapper around 00192 combineOutputs(), where the real work is done. ComplexChannel 00193 provides a default implementation of combineOutputs() that sums 00194 the outputs of the subchannels and then optionally 00195 maxNormalize()'s the result. */ 00196 virtual Image<float> getOutput(); 00197 00198 //! Save our various maps using a FrameOstream 00199 /*! By default, we save our output map (if itsSaveOutputMap is true) 00200 and propagate the call to our subchannels. Our output 00201 (conspicuity) map will be prefixed by "CO<tagname>-" */ 00202 virtual void saveResults(const nub::ref<FrameOstream>& ofs); 00203 00204 //! Clears the output cache. 00205 virtual void killCaches(); 00206 00207 protected: 00208 OModelParam<MaxNormType> itsNormType; //!< Normalization; see fancynorm.H 00209 OModelParam<MapCombineType> itsCombineType; //!< see Channels/MapCombineType.H 00210 OModelParam<bool> itsSaveOutputMap; //!< Save our output map? 00211 OModelParam<bool> itsUseOlderVersion; //!< use old version? see Visualcortex.H 00212 NModelParam<bool> itsUseSpaceVariantBoundary;//!< check subchannels for this? 00213 00214 //! Set a fixed range of values for the raw output 00215 /*! By default, the range is set to [MAXNORMMIN .. MAXNORMMAX] at 00216 construction. If non-zero values are provided here, in getOutput() 00217 we will cumulate our various submaps, apply the provided range, 00218 apply spatial competition for salience, apply our total weight, 00219 and return the result. If a range [0.0 .. 0.0] is provided here, 00220 only spatial competition and weights will be applied, but the 00221 first step of applying the range will be skipped. This must be 00222 called before start(). */ 00223 OModelParam<float> itsOutputRangeMin; 00224 OModelParam<float> itsOutputRangeMax; 00225 00226 //! Combines the outputs of subchannels. 00227 /*! The default implementation just sums the outputs of the 00228 subchannels and then maxNormalize()'s if requested by 00229 itsNormType. */ 00230 virtual Image<float> combineOutputs(); 00231 00232 //! get started 00233 virtual void start1(); 00234 00235 //! get started 00236 virtual void start2(); 00237 00238 //! stop 00239 virtual void stop2(); 00240 00241 private: 00242 ComplexChannel(const ComplexChannel&); // not allowed 00243 ComplexChannel& operator=(const ComplexChannel&); // not allowed 00244 00245 void lookupSubmap(const uint idx, uint& subchan, uint& subidx) const; 00246 00247 struct Impl; 00248 Impl* rep; 00249 }; 00250 00251 00252 // ###################################################################### 00253 /* So things look consistent in everyone's emacs... */ 00254 /* Local Variables: */ 00255 /* indent-tabs-mode: nil */ 00256 /* End: */ 00257 00258 #endif // !COMPLEXCHANNEL_H_DEFINED