00001 /*!@file SIFT/VisualObject.H Header file for visual objects to be recognized */ 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/SIFT/VisualObject.H $ 00035 // $Id: VisualObject.H 14116 2010-10-08 08:34:50Z siagian $ 00036 // 00037 00038 #ifndef VISUALOBJECT_H_DEFINED 00039 #define VISUALOBJECT_H_DEFINED 00040 00041 #include "Image/Pixels.H" 00042 #include "Image/Image.H" 00043 #include "SIFT/Keypoint.H" 00044 #include "rutz/shared_ptr.h" 00045 00046 #include <vector> 00047 #include <iosfwd> 00048 #include <string> 00049 00050 class Keypoint; 00051 00052 //! Describes name and attributes of a visual object 00053 /*! A VisualObject is a visual view of a given real-world object. As 00054 such, it is described by a name, an Image representing the view, and 00055 possibly a preattentive feature vector (as obtained, for example, 00056 from VisualCortex::getFeatures() ), and a list of SIFT Keypoint 00057 objects. */ 00058 class VisualObject 00059 { 00060 public: 00061 // ###################################################################### 00062 //! @name Constructor, assigment and destructor 00063 //@{ 00064 00065 //! Constructor assuming precomputed keypoints 00066 /*! @param name the name of the object. 00067 @param imagefname the filename to store our image into; see operator<< 00068 and operator>> for details on how this will be used. 00069 @param image an image of the object. Also see operator<< and operator>> 00070 for details. 00071 @param salpt the salient point location of the object. 00072 @param preattfeatures preattentive features, as obtained, for example, 00073 from VisualCortex::getFeatures(). 00074 @param keypoints a vector of SIFT Keypoint descriptors. If this is 00075 empty, then a ScaleSpace will be built from the image and the SIFT 00076 keypoints will be extracted from it. */ 00077 VisualObject(const std::string& name = "NULL", 00078 const std::string& imagefname = "NULL", 00079 const Image< PixRGB<byte> >& image = Image< PixRGB<byte> >(), 00080 const Point2D<int>& salpt = Point2D<int>(-1,-1), 00081 const std::vector<float>& preattfeatures = std::vector<float>(), 00082 const std::vector< rutz::shared_ptr<Keypoint> >& keypoints = 00083 std::vector< rutz::shared_ptr<Keypoint> >(), 00084 const bool useColor = false, 00085 bool computeKP = true); 00086 00087 //! this is for computing keypoints at a later time 00088 //! only compute if the image is initialized and keypoints vector is empty 00089 void computeKeypoints(); 00090 00091 //! Copy constructor 00092 VisualObject(const VisualObject& vo); 00093 00094 //! Destructor 00095 ~VisualObject(); 00096 00097 //! Assignment 00098 VisualObject& operator=(const VisualObject& vo); 00099 00100 //@} 00101 00102 // ###################################################################### 00103 //! @name Access functions 00104 //@{ 00105 00106 //! name getter 00107 inline const std::string& getName() const; 00108 00109 //! change the name, e.g., after we have recognized the object 00110 inline void setName(const std::string& name); 00111 00112 //! image filename getter 00113 inline const std::string& getImageFname() const; 00114 00115 //! change the image file name, e.g., after we have recognized the object 00116 inline void setImageFname(const std::string& fname); 00117 00118 //! change the size of the object 00119 inline void setObjectSize(const Dims size); 00120 00121 //! delete the image file from disk 00122 /*! This is useful if you want to make sure that the current image 00123 will be saved, as by default operator<< will not overwrite the 00124 image file. */ 00125 void deleteImageFile() const; 00126 00127 //! image getter 00128 inline const Image<PixRGB<byte> >& getImage() ; 00129 00130 //! get the object dims 00131 inline const Dims getObjectSize() const; 00132 00133 //! get the salient point location 00134 inline const Point2D<int>& getSalPoint() const; 00135 00136 //! get all preattentive features 00137 inline const std::vector<float>& getFeatures() const; 00138 00139 //! get number of pre-attentive features 00140 inline uint numFeatures() const; 00141 00142 //! get a given pre-attentive feature 00143 inline float getFeature(const uint index) const; 00144 00145 //! get all SIFT keypoints 00146 inline const std::vector< rutz::shared_ptr<Keypoint> >& getKeypoints() const; 00147 00148 //! get number of SIFT keypoints 00149 inline uint numKeypoints() const; 00150 00151 //! get a given SIFT keypoint 00152 inline const rutz::shared_ptr<Keypoint>& getKeypoint(const uint index) const; 00153 00154 //! load the visual object image without returning it 00155 inline void loadImage() ; 00156 00157 //@} 00158 00159 // ###################################################################### 00160 //! @name Compute functions 00161 //@{ 00162 00163 //! Sort our Keypoints in ascending order of their DoG magnitude 00164 /*! We internally keep track of when we are sorted, so calling this 00165 multiple times will not impact performance. */ 00166 void sortKeypoints(); 00167 00168 //! get squared distance between our and obj's pre-attentive features 00169 double getFeatureDistSq(const rutz::shared_ptr<VisualObject>& obj) const; 00170 00171 //! Get an image that shows our SIFT keypoints 00172 /*! This returns our internal image onto which our keypoints are 00173 drawn as little vectors. 00174 @param scale optional scale factor to apply to the image, default 00175 is to zoom in by a factor 4, which makes the keypoints more visible. 00176 @param vmag magnitute factor for the length of the scale vectors. 00177 @param col color of the vectors. */ 00178 Image<PixRGB<byte> > getKeypointImage(const float scale = 2.0F, 00179 const float vmag = 5.0F, 00180 const PixRGB<byte> col = 00181 PixRGB<byte>(255, 0, 0)) ; 00182 00183 //! same as getKeypointImage with scale displayed as well 00184 Image<PixRGB<byte> > getKeypointImage2(const float scale = 2.0F, 00185 const float vmag = 5.0F, 00186 const PixRGB<byte> col = 00187 PixRGB<byte>(255, 0, 0)) ; 00188 00189 //! same as getKeypointImage except + salient point 00190 Image<PixRGB<byte> > getSalAndKeypointImage(const float scale = 2.0F, 00191 const float vmag = 5.0F, 00192 const PixRGB<byte> col = 00193 PixRGB<byte>(255, 0, 0)) ; 00194 00195 //@} 00196 00197 00198 static void createVisualObject(std::istream& is, VisualObject &v, bool loadImage = true); 00199 00200 protected: 00201 std::string itsName; // name of this object 00202 std::string itsImageFname; // filename of our image 00203 Image<PixRGB<byte> > itsImage; // object image 00204 std::vector< rutz::shared_ptr<Keypoint> > itsKeypoints; // keypoints 00205 Point2D<int> itsSalPoint; // the salient point location 00206 std::vector<float> itsFeatures; // pre-attentive features 00207 bool itsIsSorted; // are our Keypoints sorted? 00208 bool itsUseColor; // should we add color 00209 bool itsImageLoaded; // Does the image already loaded? 00210 Dims itsObjectSize; // This correspond to object size in the real world 00211 00212 private: 00213 friend std::istream& operator>>(std::istream& is, VisualObject& v); 00214 friend std::ostream& operator<<(std::ostream& os, const VisualObject& v); 00215 }; 00216 00217 // ###################################################################### 00218 // VisualObject I/O: 00219 // ###################################################################### 00220 00221 //! Load a VisualObject from an istream 00222 std::istream& operator>>(std::istream& is, VisualObject& v); 00223 00224 //! Save a VisualObject to an ostream 00225 /*! If our image file name is known also save the image, but only if 00226 there is not already a file by than name. You should delete the file 00227 first if you want to ensure that the image will be saved. You can 00228 use VisualObject::deleteImageFile() for that. */ 00229 std::ostream& operator<<(std::ostream& os, const VisualObject& v); 00230 00231 00232 // ###################################################################### 00233 // Implementation for VisualObject inline functions 00234 // ###################################################################### 00235 inline const std::string& VisualObject::getName() const 00236 { return itsName; } 00237 00238 inline void VisualObject::setName(const std::string& name) 00239 { itsName = name; } 00240 00241 inline const std::string& VisualObject::getImageFname() const 00242 { return itsImageFname; } 00243 00244 inline void VisualObject::setImageFname(const std::string& fname) 00245 { itsImageFname = fname; } 00246 00247 inline void VisualObject::setObjectSize(const Dims size) 00248 { itsObjectSize = size; } 00249 00250 inline const Image<PixRGB<byte> >& VisualObject::getImage() 00251 { 00252 if(!itsImageLoaded) 00253 { 00254 itsImage = Raster::ReadRGB(itsImageFname); 00255 itsImageLoaded = true; 00256 } 00257 return itsImage; 00258 } 00259 00260 inline void VisualObject::loadImage() 00261 { 00262 if(!itsImageLoaded) 00263 { 00264 itsImage = Raster::ReadRGB(itsImageFname); 00265 itsImageLoaded = true; 00266 } 00267 } 00268 00269 inline const Dims VisualObject::getObjectSize() const 00270 { 00271 return itsObjectSize; 00272 } 00273 00274 inline const Point2D<int>& VisualObject::getSalPoint() const 00275 { return itsSalPoint; } 00276 00277 inline const std::vector<float>& VisualObject::getFeatures() const 00278 { return itsFeatures; } 00279 00280 inline uint VisualObject::numFeatures() const 00281 { return itsFeatures.size(); } 00282 00283 inline float VisualObject::getFeature(const uint index) const 00284 { 00285 ASSERT(index < itsFeatures.size()); 00286 return itsFeatures[index]; 00287 } 00288 00289 inline const std::vector< rutz::shared_ptr<Keypoint> >& 00290 VisualObject::getKeypoints() const 00291 { return itsKeypoints; } 00292 00293 inline uint VisualObject::numKeypoints() const 00294 { return itsKeypoints.size(); } 00295 00296 inline const rutz::shared_ptr<Keypoint>& 00297 VisualObject::getKeypoint(const uint index) const 00298 { 00299 ASSERT(index < itsKeypoints.size()); 00300 return itsKeypoints[index]; 00301 } 00302 00303 #endif 00304 00305 // ###################################################################### 00306 /* So things look consistent in everyone's emacs... */ 00307 /* Local Variables: */ 00308 /* indent-tabs-mode: nil */ 00309 /* End: */