Keypoint.H

Go to the documentation of this file.
00001 /*!@file SIFT/Keypoint.H Keypoint for SIFT obj recognition */
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: James Bonaiuto <bonaiuto@usc.edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/SIFT/Keypoint.H $
00035 // $Id: Keypoint.H 10462 2008-11-20 06:36:31Z rand $
00036 //
00037 
00038 #ifndef KEYPOINT_H_DEFINED
00039 #define KEYPOINT_H_DEFINED
00040 
00041 #include "Component/ModelManager.H"
00042 #include "Raster/Raster.H"
00043 #include "Util/Types.H"
00044 #include "Util/Assert.H"
00045 #include "rutz/shared_ptr.h"
00046 #include <vector>
00047 #include <iosfwd>
00048 
00049 // ########################################################################
00050 //! The keypoint base class
00051 // ########################################################################
00052 /*! The sift keypoint feature descriptor
00053     3D position (x, y, scale)
00054     Mean orientation, magnitude
00055     Feature vector */
00056 class Keypoint
00057 {
00058 public:
00059         enum CHANNEL {ORI, COL};
00060   // ######################################################################
00061   /*! @name Constructors, destructor, copy, assigment */
00062   //@{
00063 
00064   //! Uninitialized constructor; will net to call reset() later
00065   Keypoint();
00066 
00067   //! Constructor
00068   Keypoint(const std::vector<byte>& features, const float x, const float y,
00069            const float s, const float o, const float dogmag);
00070 
00071   //! Constructor with Color
00072   Keypoint(const std::vector<byte>& features,
00073            const std::vector<byte>& colFeatures,
00074            const float x, const float y,
00075            const float s, const float o, const float dogmag,
00076            float oriWeight=1.0F, float colWeight=1.0F);
00077 
00078   //! Copy-constructor
00079   Keypoint(const Keypoint& k);
00080 
00081   //! Reset all internal values
00082   void reset(const std::vector<byte>& features,
00083              const float x, const float y,
00084              const float s, const float o, const float dogmag);
00085 
00086   //! Destructor
00087   ~Keypoint();
00088 
00089   //! Assignment
00090   Keypoint& operator=(const Keypoint& k);
00091 
00092   //@}
00093 
00094   // ######################################################################
00095   /*! @name Iterators and access functions
00096     The iterators iterate on our feature vector data only, while the
00097     other access functions can be used to access the other data. */
00098 
00099   //@{
00100 
00101   //! standard iterator
00102   typedef std::vector<byte>::iterator iterator;
00103 
00104   //! const iterator
00105   typedef std::vector<byte>::const_iterator const_iterator;
00106 
00107   //! Returns a read-only iterator to the beginning of the feature vec data
00108   inline const_iterator begin(CHANNEL channel=ORI) const;
00109 
00110   //! Returns a read-only iterator to one-past-the-end of the feature vec data
00111   inline const_iterator end(CHANNEL channel=ORI) const;
00112 
00113   //! Returns a read-write iterator to the beginning of the feature vec data
00114   inline iterator beginw(CHANNEL channel=ORI);
00115 
00116   //! Returns a read-write iterator to one-past-the-end of the feature vec data
00117   inline iterator endw(CHANNEL channel=ORI);
00118 
00119   //! x getter
00120   inline float getX() const;
00121 
00122   //! y getter
00123   inline float getY() const;
00124 
00125   //! scale getter
00126   inline float getS() const;
00127 
00128   //! orientation getter
00129   inline float getO() const;
00130 
00131   //! DoG magnitude getter
00132   inline float getM() const;
00133 
00134   //! Return the length of this keypoint's feature vector
00135   inline uint getFVlength(CHANNEL channel=ORI) const;
00136 
00137   //! Return the value of the feature vector at the given index
00138   inline byte getFVelement(const uint index, CHANNEL channel=ORI) const;
00139 
00140   //! Return a copy of the orientation feature vector
00141   inline std::vector<byte> getOriFV() { return itsOriFV; };
00142 
00143   //! Return a copy of the color feature vector
00144   inline std::vector<byte> getColFV() { return itsColFV; };
00145   //@}
00146 
00147   // ######################################################################
00148   /*! Comparisons and feature distance computation */
00149   //@{
00150 
00151   //! Compute squared distance between two keypoint descriptors
00152   inline int distSquared(const rutz::shared_ptr<Keypoint>& k) const;
00153 
00154   //! Return the maximum possible dist sq between two feature vectors
00155   /*! This is just a function of the size of our feature vector */
00156   inline int maxDistSquared(CHANNEL channel=ORI) const;
00157 
00158   //! Compares the magnitude of this keypoint to the given keypoint
00159   /*! This is useful, for example, to use std::sort() on an
00160     std::vector< rutz::shared_ptr<Keypoint> >. Just remember that the
00161     comparison is based on the magnitude of the DoG only, not on any
00162     other internal data of the Keypoint. */
00163   inline bool operator<(const Keypoint& k) const;
00164 
00165 
00166   //@}
00167 
00168 protected:
00169   float itsX;                        //!< our x coordinate
00170   float itsY;                        //!< our y coordinate
00171   float itsS;                        //!< our scale coordinate
00172   float itsO;                        //!< our orientation
00173   float itsM;                        //!< our DoG magnitude, for sorting
00174   std::vector<byte> itsOriFV;        //!< our Ori feature vector
00175   std::vector<byte> itsColFV;        //!< our color feature vector
00176   float itsOriWeight;                //!< The weight for ori
00177   float itsColWeight;                //!< The weight for col
00178 
00179 
00180 private:
00181   friend std::istream& operator>>(std::istream& is, Keypoint& k);
00182   friend std::ostream& operator<<(std::ostream& os, const Keypoint& k);
00183 };
00184 
00185 // ######################################################################
00186 // Keypoint I/O:
00187 // ######################################################################
00188 
00189 //! Load a Keypoint from an istream
00190 std::istream& operator>>(std::istream& is, Keypoint& k);
00191 
00192 //! Save a Keypoint to an ostream
00193 std::ostream& operator<<(std::ostream& os, const Keypoint& k);
00194 
00195 // ######################################################################
00196 // Inlined member functions
00197 // ######################################################################
00198 inline Keypoint::const_iterator Keypoint::begin(CHANNEL channel) const
00199 {
00200   switch (channel){
00201   case ORI:
00202     return itsOriFV.begin();
00203   case COL:
00204     return itsColFV.begin();
00205   default:
00206     return itsOriFV.begin();  //default
00207   }
00208 }
00209 
00210 inline Keypoint::const_iterator Keypoint::end(CHANNEL channel) const
00211 {
00212   switch (channel){
00213   case ORI:
00214     return itsOriFV.end();
00215   case COL:
00216     return itsColFV.end();
00217   default:
00218     return itsOriFV.end();  //default
00219   }
00220 }
00221 
00222 //TODO: should these be beginw and endw?
00223 inline Keypoint::iterator Keypoint::beginw(CHANNEL channel)
00224 {
00225   switch (channel){
00226   case ORI:
00227     return itsOriFV.begin();
00228   case COL:
00229     return itsColFV.begin();
00230   default:
00231     return itsOriFV.begin();  //default
00232   }
00233 }
00234 
00235 inline Keypoint::iterator Keypoint::endw(CHANNEL channel)
00236 {
00237   switch (channel){
00238   case ORI:
00239     return itsOriFV.end();
00240   case COL:
00241     return itsColFV.end();
00242   default:
00243     return itsOriFV.end();  //default
00244   }
00245 }
00246 
00247 ///////////////////// Color FV access ///////////////////////////
00248 inline float Keypoint::getX() const
00249 { return itsX; }
00250 
00251 inline float Keypoint::getY() const
00252 { return itsY; }
00253 
00254 inline float Keypoint::getS() const
00255 { return itsS; }
00256 
00257 inline float Keypoint::getO() const
00258 { return itsO; }
00259 
00260 inline float Keypoint::getM() const
00261 { return itsM; }
00262 
00263 inline uint Keypoint::getFVlength(CHANNEL channel) const
00264 {
00265   switch (channel){
00266   case ORI:
00267     return itsOriFV.size();
00268   case COL:
00269     return itsColFV.size();
00270   default:
00271     return itsOriFV.size();  //default
00272   }
00273 }
00274 
00275 inline byte Keypoint::getFVelement(const uint index,CHANNEL channel) const
00276 {
00277   switch (channel){
00278   case ORI:
00279     ASSERT(index < itsOriFV.size());
00280     return itsOriFV[index];
00281   case COL:
00282     ASSERT(index < itsColFV.size());
00283     return itsColFV[index];
00284   default:
00285     ASSERT(index < itsOriFV.size());
00286     return itsOriFV[index];
00287   }
00288 }
00289 
00290 inline int Keypoint::distSquared(const rutz::shared_ptr<Keypoint>& k) const
00291 {
00292   int oriDistsq = 0;
00293   int colDistsq = 0;
00294 
00295   ASSERT(itsOriFV.size() == k->itsOriFV.size());
00296   if (itsColFV.size() > 0)
00297      ASSERT(itsColFV.size() == k->itsColFV.size());
00298 
00299   Keypoint::const_iterator oriF1 = begin(ORI), oriF2 = k->begin(ORI),
00300           oriStop = end(ORI);
00301 
00302   while(oriF1 != oriStop)
00303     {
00304       const int of1 = int(*oriF1++);
00305       const int of2 = int(*oriF2++);
00306       const int dif =  of1 - of2;
00307       oriDistsq += dif * dif;
00308     }
00309 
00310   if (itsColFV.size() > 0) {
00311     Keypoint::const_iterator colF1 = begin(COL), colF2 = k->begin(COL),
00312       colStop = end(COL);
00313     while(colF1 != colStop)
00314       {
00315         const int dif = int(*colF1++) - int(*colF2++);
00316         colDistsq += dif * dif;
00317       }
00318   }
00319 
00320   return int(itsOriWeight*float(oriDistsq) + itsColWeight*float(colDistsq));
00321   // return oriDistsq + colDistsq;
00322 }
00323 
00324 inline int Keypoint::maxDistSquared(CHANNEL channel) const
00325 {
00326   switch (channel){
00327   case ORI:
00328     return 255 * 255 * itsOriFV.size();
00329   case COL:
00330     return 255 * 255 * itsColFV.size();
00331   default:
00332     return 255 * 255 * itsOriFV.size();
00333   }
00334 }
00335 
00336 inline bool Keypoint::operator<(const Keypoint& k) const
00337 { return (itsM < k.itsM); }
00338 
00339 #endif
00340 
00341 // ######################################################################
00342 /* So things look consistent in everyone's emacs... */
00343 /* Local Variables: */
00344 /* indent-tabs-mode: nil */
00345 /* End: */
Generated on Sun May 8 08:06:49 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3