Jet.H

Go to the documentation of this file.
00001 /*!@file Channels/Jet.H a simple jet (i.e., cortical hypercolumn) */
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/Channels/Jet.H $
00035 // $Id: Jet.H 6990 2006-08-11 18:13:51Z rjpeters $
00036 //
00037 
00038 #ifndef JET_H_DEFINED
00039 #define JET_H_DEFINED
00040 
00041 #include "Util/Assert.H"
00042 #include "Util/Types.H"
00043 #include "Channels/VisualFeatures.H"
00044 #include "Util/Promotions.H"
00045 #include "Util/log.H"
00046 #include "rutz/shared_ptr.h"
00047 #include <cstdarg>
00048 #include <vector>
00049 
00050 template <class T> class Image;
00051 
00052 // ######################################################################
00053 //! This class specifies the features, scales and indices represented in a Jet
00054 /*! A Jet object requires a valid JetSpec object at construction */
00055 class JetSpec
00056 {
00057 public:
00058   /*! @name Constructors, destructor and operators */
00059   //@{
00060 
00061   //! Empty constructor; starts with an empty specification
00062   JetSpec();
00063 
00064   //! Copy constructor
00065   JetSpec(const JetSpec& js);
00066 
00067   //! Assignment operator
00068   JetSpec& operator=(const JetSpec& js);
00069 
00070   //! Free all allocated memory and un-initialize
00071   void freeMem();
00072 
00073   //! Destructor
00074   ~JetSpec();
00075   //@}
00076 
00077   /*! @name Build methods */
00078   //@{
00079   //! Add a new feature; returns true on success
00080   bool addFeature(const VisualFeature f);
00081 
00082   //! Add a new representation type for an existing feature; true on success
00083   bool addFeatureType(const VisualFeature f, const VisualFeatureType t);
00084 
00085   //! Add a new index range for existing feature and type; true on success
00086   /*! Valid indices will be in [indexmin..indexmax] inclusive on both sides. */
00087   bool addIndexRange(const VisualFeature f, const VisualFeatureType t,
00088                      const int indexmin, const int indexmax);
00089   //@}
00090 
00091   /*! @name Access methods */
00092   //@{
00093   //! Get the number of components in a jet with our specs
00094   inline int getJetSize() const;
00095 
00096   //! Query whether we have some representation for given feature
00097   inline bool hasFeature(const VisualFeature f) const;
00098 
00099   //! Query whether we have some representation for given feature/type
00100   inline bool hasFeatureType(const VisualFeature f,
00101                              const VisualFeatureType t) const;
00102 
00103   //! Get index of first Jet element for given feature & type
00104   /*! Also returns the total size allocated in the Jet for this feature
00105     and type */
00106   inline int getIndexBase(const VisualFeature f, const VisualFeatureType t,
00107                           int& siz) const;
00108 
00109   //! Get number of index ranges
00110   inline int getNbIndexRanges(const VisualFeature f,
00111                               const VisualFeatureType t) const;
00112 
00113   //! Get an index range; true if range exists in JetSpec
00114   inline bool getIndexRange(const VisualFeature f, const VisualFeatureType t,
00115                             const int idxnum, int& idxmin, int& idxmax) const;
00116 
00117   //! Debugging printout to stdout
00118   void print() const;
00119 
00120   //@}
00121 
00122   /*! @name Jet data access methods */
00123   //@{
00124   //! Get index in Jet array data for given feature, type and set of indices
00125   /*! The ... arguments should be as many ints as we have have
00126     addIndexRange()'d when building the JetSpec, and their values
00127     should be within the ranges specified at the time of
00128     addIndexRange(). Returns -1 if feature or type unknown or if any
00129     of the indices is out of range. */
00130   inline int getIndex(const VisualFeature f,
00131                       const VisualFeatureType t, ...) const;
00132 
00133   //! getIndex() with va_list parameters
00134   inline int getIndexA(const VisualFeature f, const VisualFeatureType t,
00135                 va_list& a) const;
00136 
00137   //! getIndex() with vector of parameters
00138   inline int getIndexV(const VisualFeature f, const VisualFeatureType t,
00139                        const std::vector<int>& v) const;
00140   //@}
00141 
00142 private:
00143   //! Chained list element that holds index range defs for given feature type
00144   struct JFT {
00145     VisualFeatureType ftype; //!< feature type
00146     int indexBase;           //!< index in Jet of first data element
00147     int siz;                 //!< total number of elements
00148     int nbidx;               //!< number of indices
00149     int *idxmin;             //!< minimum index value
00150     int *idxmax;             //!< max index val; valid range: idxmin<=i<idxmax
00151     JFT *next;               //!< pointer to next feature type for that feature
00152   };
00153 
00154   //! chained list element that holds JTF definitions for given feature
00155   struct JF {
00156     VisualFeature feature;   //!< feature
00157     JFT *jft;                //!< pointer to list of feature types
00158     JF *next;                //!< pointer to next feature in this specification
00159   };
00160 
00161   JF *spec;  //!< Specification as tree of JF's holding JFT's
00162 
00163   //! accelerated access to individula feature/type defs
00164   JFT *dataIdx[NBVISUALFEATURES][NBVISUALFEATURETYPES];
00165   int jetSize;  //!< size of a Jet using our specs
00166 
00167   //! update our accelerated access array in dataIdx
00168   void updateDataIdx();
00169 };
00170 
00171 
00172 // ######################################################################
00173 //! This class specifies a Jet, i.e., array of feature values for one location
00174 /*! The features represented in the Jet are defined by a JetSpec
00175 object that must be passed at construction of the Jet. Jet extends
00176 Image and inherits all of its functionality. The JetSpec is passed as
00177 a rutz::shared_ptr, so that the original can run out of scope and be
00178 destroyed (and the actual data will be freed upon destruction of the
00179 last Jet built from that JetSpec). */
00180 
00181 template <class T>
00182 class Jet : public Image<T> {
00183 public:
00184   /*! @name Constructors, initialization and destructor */
00185   //@{
00186   //! Constructor; must provide a fully-configured JetSpec
00187   Jet(const rutz::shared_ptr<JetSpec> js);
00188 
00189   //! Uninitialized constructor (for arrays of Jets)
00190   Jet();
00191 
00192   //! Initialization of an uninitialized Jet
00193   void init(const rutz::shared_ptr<JetSpec> js);
00194 
00195   //! Load from an Image, presenving our JetSpec
00196   /*! The Jet must have been initialized previously and its size must
00197     match that of the Image. This is potentially dangerous, and mostly
00198     provided so that we can inherit all of the Image free functions
00199     that return images (e.g., those of Image_MathOps.H). This is a
00200     cheap operation thanks to the copy-on-write/ref-counting */
00201   inline Jet<T>& operator=(const Image<T>& img);
00202 
00203   //! Load from an image, preserving our JetSpec and doing a clamped convert
00204   /*! The Jet must have been initialized previously and its size must
00205     match that of the Image. This is potentially dangerous, and mostly
00206     provided so that we can inherit all of the Image free functions
00207     that return images (e.g., those of Image_MathOps.H). This is an
00208     expensive operation in which we convert each pixel in turn. */
00209   template <class TT> inline Jet<T>& operator=(const Image<TT>& img);
00210 
00211   //! Destructor
00212   ~Jet();
00213   //@}
00214 
00215   /*! @name Access functions */
00216   //@{
00217   //! Get a value, for given feature, type and indices
00218   inline T getVal(const VisualFeature f, const VisualFeatureType t, ...) const;
00219 
00220   //! Get a value, for given feature, type and vector of indices
00221   inline T getValV(const VisualFeature f, const VisualFeatureType t,
00222             const std::vector<int>& v) const;
00223 
00224   //! Get a value by absolute index in the Jet array. Use with caution!
00225   inline T getVal(const int idx) const;
00226 
00227   //! Set a value, for given feature, type and indices
00228   inline void setVal(const T& val, const VisualFeature f,
00229                      const VisualFeatureType t, ...);
00230 
00231   //! Set a value, for given feature, type and vector of indices
00232   inline void setValV(const T& val, const VisualFeature f,
00233                       const VisualFeatureType t, const std::vector<int>& v);
00234 
00235   //! Set a value by absolute index in the Jet array. Use with caution!
00236   inline void setVal(const int idx, const T& val);
00237 
00238   //! Retrieve the JetSpec in case your original has run out of scope
00239   inline rutz::shared_ptr<JetSpec> getSpec() const;
00240   //@}
00241 
00242   /*! @name Convenience JetSpec Access Methods */
00243   //@{
00244   //! Query whether we have some representation for given feature
00245   inline bool hasFeature(const VisualFeature f) const;
00246 
00247   //! Query whether we have some representation for given feature/type
00248   inline bool hasFeatureType(const VisualFeature f,
00249                              const VisualFeatureType t) const;
00250 
00251   //! Get index of first Jet element for given feature & type
00252   /*! Also returns total size allocated in the Jet for this feature/type */
00253   inline int getIndexBase(const VisualFeature f,
00254                           const VisualFeatureType t, int& siz) const;
00255 
00256   //! Get number of index ranges
00257   inline int getNbIndexRanges(const VisualFeature f,
00258                               const VisualFeatureType t) const;
00259 
00260   //! Get an index range; true if range exists in JetSpec
00261   inline bool getIndexRange(const VisualFeature f, const VisualFeatureType t,
00262                             const int idxnum, int& idxmin, int& idxmax) const;
00263   //@}
00264 
00265 private:
00266   rutz::shared_ptr<JetSpec> spec;
00267 };
00268 
00269 // ######################################################################
00270 //! Compute distance between two Jets like Rao et al., Vis Res, 2002
00271 double raodistance(const Jet<float>& j1, const Jet<float>& j2,
00272                    const int idxmin, const int idxmax);
00273 
00274 // ######################################################################
00275 template <class Stream, class T>
00276 inline Stream& operator<<(Stream& s, const Jet<T> &j)
00277 {
00278   int siz = j.getSize();
00279   for (int i = 0; i < siz; i ++) s<<j.Image<T>::getVal(i)<<' ';
00280   return s;
00281 }
00282 
00283 // ######################################################################
00284 template <class Stream, class T>
00285 inline Stream& operator>>(Stream& s, Jet<T> &j)
00286 {
00287   int siz = j.getSize(); float x;
00288   for (int i = 0; i < siz; i ++) { s>>x; j.Image<T>::setVal(i, x); }
00289   return s;
00290 }
00291 
00292 // ######################################################################
00293 // ######################################################################
00294 // ########## INLINED METHODS for JetSpec:
00295 // ######################################################################
00296 // ######################################################################
00297 
00298 // ######################################################################
00299 inline int JetSpec::getJetSize() const
00300 { return jetSize; }
00301 
00302 // ######################################################################
00303 inline bool JetSpec::hasFeature(const VisualFeature f) const
00304 {
00305   JF *jfp = spec;
00306   while(jfp) if (jfp->feature == f) return true; else jfp = jfp->next;
00307   return false;
00308 }
00309 
00310 // ######################################################################
00311 inline bool JetSpec::hasFeatureType(const VisualFeature f,
00312                                     const VisualFeatureType t) const
00313 { return (dataIdx[f][t] != NULL); }
00314 
00315 // ######################################################################
00316 inline int JetSpec::getIndexBase(const VisualFeature f,
00317                                  const VisualFeatureType t, int& siz) const
00318 {
00319   ASSERT(dataIdx[f][t]);
00320   siz = dataIdx[f][t]->siz;
00321   return dataIdx[f][t]->indexBase;
00322 }
00323 
00324 // ######################################################################
00325 inline int JetSpec::getNbIndexRanges(const VisualFeature f,
00326                                      const VisualFeatureType t) const
00327 {
00328   ASSERT(dataIdx[f][t]);
00329   return dataIdx[f][t]->nbidx;
00330 }
00331 
00332 // ######################################################################
00333 inline bool JetSpec::getIndexRange(const VisualFeature f,
00334                                    const VisualFeatureType t,
00335                                    const int idxnum, int& idxmin,
00336                                    int& idxmax) const
00337 {
00338   if (dataIdx[f][t] == NULL || idxnum < 0 || idxnum >= dataIdx[f][t]->nbidx)
00339     return false;
00340   idxmin = dataIdx[f][t]->idxmin[idxnum];
00341   idxmax = dataIdx[f][t]->idxmax[idxnum];
00342   return true;
00343 }
00344 
00345 // ######################################################################
00346 inline int JetSpec::getIndex(const VisualFeature f, const VisualFeatureType t,
00347                              ...) const
00348 {
00349   va_list a; va_start(a, t); int idx = getIndexA(f, t, a); va_end(a);
00350   return idx;
00351 }
00352 
00353 // ######################################################################
00354 inline int JetSpec::getIndexA(const VisualFeature f,
00355                               const VisualFeatureType t, va_list& a) const
00356 {
00357   // do a rapid fetch of data for given feature & type:
00358   JFT *jftp = dataIdx[f][t];
00359   if (jftp == NULL) {
00360     LERROR("Unknown feature/type: %s/%s", featureName(f), featureTypeName(t));
00361     return -1;
00362   }
00363 
00364   // FIXME: how can we check that the number of va_args matches the
00365   // number of indices?
00366 
00367   // add offset according to parameters passed by caller:
00368   int index = 0;
00369   for (int i = 0; i < jftp->nbidx; i ++) {
00370     int arg = va_arg(a, int);
00371     if (arg < jftp->idxmin[i] || arg > jftp->idxmax[i])
00372       { LERROR("Index %d value %d out of range [%d..%d]", i, arg,
00373                jftp->idxmin[i], jftp->idxmax[i]); return -1; }
00374     index = index * (jftp->idxmax[i] - jftp->idxmin[i] + 1) +
00375       (arg - jftp->idxmin[i]);
00376   }
00377   return index + jftp->indexBase;
00378 }
00379 
00380 // ######################################################################
00381 inline int JetSpec::getIndexV(const VisualFeature f, const VisualFeatureType t,
00382                               const std::vector<int>& v) const
00383 {
00384   // do a rapid fetch of data for given feature & type:
00385   JFT *jftp = dataIdx[f][t];
00386   if (jftp == NULL) {
00387     LERROR("Unknown feature/type: %s/%s", featureName(f), featureTypeName(t));
00388     return -1;
00389   }
00390 
00391   // check that caller passed right number of indices:
00392   if (int(v.size()) != jftp->nbidx) {
00393     LERROR("Passed %"ZU" indices but %s/%s has %d", v.size(),
00394            featureName(f), featureTypeName(t), jftp->nbidx);
00395     return -1;
00396   }
00397 
00398   //std::cout<<featureName(f)<<'/'<<featureTypeName(t)<<"[ ";
00399   //for (int i = 0; i < v.size(); i ++) std::cout<<v[i]<<' ';
00400 
00401   // add offset according to parameters passed by caller:
00402   int index = 0;
00403   for (int i = 0; i < jftp->nbidx; i ++) {
00404     int arg = v[i];
00405     if (arg < jftp->idxmin[i] || arg > jftp->idxmax[i])
00406       { LERROR("Index %d value %d out of range [%d..%d]", i, arg,
00407                jftp->idxmin[i], jftp->idxmax[i]); return -1; }
00408     index = index * (jftp->idxmax[i] - jftp->idxmin[i] + 1) +
00409       (arg - jftp->idxmin[i]);
00410   }
00411 
00412   //std::cout<<"] = "<<index + jftp->indexBase<<std::endl;
00413 
00414   return index + jftp->indexBase;
00415 }
00416 
00417 
00418 // ######################################################################
00419 // ######################################################################
00420 // ########## INLINED METHODS for Jet:
00421 // ######################################################################
00422 // ######################################################################
00423 
00424 // ######################################################################
00425 template <class T> inline
00426 Jet<T>& Jet<T>::operator=(const Image<T>& img)
00427 {
00428   ASSERT(isSameSize(img));
00429   Image<T> A_copy(img);
00430   this->swap(A_copy);
00431   return *this;
00432 }
00433 
00434 // ######################################################################
00435 template <class T> template <class TT> inline
00436 Jet<T>& Jet<T>::operator=(const Image<TT>& img)
00437 {
00438   ASSERT(isSameSize(img));
00439   Image<T>::operator=(img); return *this;
00440 }
00441 
00442 // ######################################################################
00443 template <class T> inline
00444 T Jet<T>::getVal(const VisualFeature f, const VisualFeatureType t, ...) const
00445 {
00446 
00447   va_list a; va_start(a, t); int idx = spec->getIndexA(f, t, a); va_end(a);
00448   return Image<T>::getVal(idx);
00449 }
00450 
00451 // ######################################################################
00452 template <class T> inline
00453 T Jet<T>::getValV(const VisualFeature f, const VisualFeatureType t,
00454                   const std::vector<int>& v) const
00455 {
00456   int idx = spec->getIndexV(f, t, v);
00457   return Image<T>::getVal(idx);
00458 }
00459 
00460 // ######################################################################
00461 template <class T> inline
00462 T Jet<T>::getVal(const int idx) const
00463 { return this->begin()[idx]; }
00464 
00465 // ######################################################################
00466 template <class T> inline
00467 void Jet<T>::setVal(const T& val, const VisualFeature f,
00468                     const VisualFeatureType t, ...)
00469 {
00470   va_list a; va_start(a, t);
00471   setVal(spec->getIndexA(f, t, a), val);
00472   va_end(a);
00473 }
00474 
00475 // ######################################################################
00476 template <class T> inline
00477 void Jet<T>::setValV(const T& val, const VisualFeature f,
00478                      const VisualFeatureType t, const std::vector<int>& v)
00479 {
00480   setVal(spec->getIndexV(f, t, v), val);
00481 }
00482 
00483 // ######################################################################
00484 template <class T> inline
00485 void Jet<T>::setVal(const int idx, const T& val)
00486 { this->beginw()[idx] = val; }
00487 
00488 // ######################################################################
00489 template <class T> inline
00490 rutz::shared_ptr<JetSpec> Jet<T>::getSpec() const
00491 { return spec; }
00492 
00493 // ######################################################################
00494 template <class T> inline
00495 bool Jet<T>::hasFeature(const VisualFeature f) const
00496 { return spec->hasFeature(f); }
00497 
00498 // ######################################################################
00499 template <class T> inline
00500 bool Jet<T>::hasFeatureType(const VisualFeature f,
00501                             const VisualFeatureType t) const
00502 { return spec->hasFeatureType(f, t); }
00503 
00504 // ######################################################################
00505 template <class T> inline
00506 int Jet<T>::getIndexBase(const VisualFeature f, const VisualFeatureType t,
00507                          int& siz) const
00508 { return spec->getIndexBase(f, t, siz); }
00509 
00510 
00511 // ######################################################################
00512 template <class T> inline
00513 int Jet<T>::getNbIndexRanges(const VisualFeature f,
00514                              const VisualFeatureType t) const
00515 { return spec->getNbIndexRanges(f, t); }
00516 
00517 
00518 // ######################################################################
00519 template <class T> inline
00520 bool Jet<T>::getIndexRange(const VisualFeature f, const VisualFeatureType t,
00521                            const int idxnum, int& idxmin, int& idxmax) const
00522 { return spec->getIndexRange(f, t, idxnum, idxmin, idxmax); }
00523 
00524 #endif
00525 
00526 // ######################################################################
00527 /* So things look consistent in everyone's emacs... */
00528 /* Local Variables: */
00529 /* indent-tabs-mode: nil */
00530 /* End: */
Generated on Sun May 8 08:40:22 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3