00001 /*!@file SIFT/VisualObjectDB.H Visual object database */ 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/VisualObjectDB.H $ 00035 // $Id: VisualObjectDB.H 14116 2010-10-08 08:34:50Z siagian $ 00036 // 00037 00038 #ifndef VISUALOBJECTDB_DEFINED 00039 #define VISUALOBJECTDB_DEFINED 00040 00041 #include "Image/Image.H" 00042 #include "SIFT/VisualObject.H" 00043 #include "SIFT/VisualObjectMatch.H" 00044 00045 #include <cstring> 00046 #include <iosfwd> 00047 #include <vector> // for std::pair 00048 00049 class KDTree; 00050 00051 //! VisualObjectDatabase 00052 class VisualObjectDB 00053 { 00054 public: 00055 //! Constructor; use operator>> and operator<< to load/save 00056 VisualObjectDB(); 00057 00058 //! Destructor 00059 ~VisualObjectDB(); 00060 00061 //! Easy loading from file 00062 /*! This will just open a file and use operator>> on it. Returns true on success. */ 00063 bool loadFrom(const std::string& fname, bool preloadImage = true); 00064 00065 //! Easy saving to file 00066 /*! This will just open a file and use operator<< on it. Returns true on success. */ 00067 bool saveTo(const std::string& fname); 00068 00069 //! name access methods 00070 inline std::string getName() const; 00071 inline void setName(const std::string& name); 00072 00073 //! get number of objects in the database 00074 inline uint numObjects() const; 00075 00076 //! object getter 00077 inline const rutz::shared_ptr<VisualObject>& getObject(const uint index) const; 00078 00079 //! object setter 00080 inline void setObject(const uint index, const rutz::shared_ptr<VisualObject>& obj); 00081 00082 //! erase object 00083 inline void eraseObject(const uint index); 00084 00085 inline void clearObjects(uint size = 0); 00086 00087 //! object getter by name 00088 /*! Returns an uninitialized rutz::shared_ptr is not found. */ 00089 inline rutz::shared_ptr<VisualObject> getObject(const std::string objectName) const; 00090 00091 //! add object 00092 /*! @return true if the object was added, false if it was not added 00093 because an object with the same name already exists (uniqueName=true) in the 00094 database. This invalidates any internal KDTree we may have. */ 00095 bool addObject(const rutz::shared_ptr<VisualObject>& obj, bool uniqueName = true); 00096 00097 //! Build a giant internal KDTree from all our Keypoints 00098 /*! This will automatically be called by getObjectMatches() if an 00099 up-to-date KDTree is not internally available. This function is 00100 made public because it may take a while to run, and is best run 00101 just after loading a DB, rather than on the first match 00102 attempt. If an up-to-date KDTree is already internally available, 00103 this is a no-op. */ 00104 void buildKDTree(); 00105 00106 //! find match for the keypoints in the scene 00107 /*! @param obj the VisualObject to match against the objects in our database. 00108 @param matches list of matches which satisfy all criteria, sorted 00109 by matching score. Note: the list is initially cleared. 00110 @param algo the algorithm to use for matching (see VisualObjectMatch.H). 00111 @param maxn the maximum number of object matches to return. NOTE: 00112 we will return the first maxn matches found without exploring the 00113 database any further. If this is not desirable, use a large 00114 matchn. You can also use sortbypf below to attempt that these 00115 first matches will indeed be the best ones. 00116 @param kcoeff coefficient for keypoint distance, used to score a 00117 match. See VisualObjectMatch::getScore(). 00118 @param acoeff coefficient for affine distance, used to score a 00119 match. See VisualObjectMatch::getScore(). 00120 @param minscore min acceptable VisualObjectMatch::getScore(kcoeff, acoeff). 00121 @param mink minimum number of matching keypoints in an object match. 00122 @param kthresh threshold to use for keypoint selection in obj; see 00123 VisualObject constructor and ScaleSpace. 00124 @param sortbypf sort our database by similarity of preattentive 00125 visual features if true. This is incompatible with KDTree-based 00126 matching algos, which would not benefit from this sorting. 00127 @return the number of matches found (== matches.size()) */ 00128 uint getObjectMatches(const rutz::shared_ptr<VisualObject> obj, 00129 std::vector< rutz::shared_ptr<VisualObjectMatch> >& matches, 00130 const VisualObjectMatchAlgo algo = VOMA_SIMPLE, 00131 const uint maxn = 5U, 00132 const float kcoeff = 0.5F, 00133 const float acoeff = 0.5F, 00134 const float minscore = 1.0F, 00135 const uint mink = 3U, 00136 const uint kthresh = 6U, 00137 const bool sortbypf = false); 00138 00139 //! find match for the keypoints in the scene, parallel version 00140 uint getObjectMatchesParallel(const rutz::shared_ptr<VisualObject> obj, 00141 std::vector< rutz::shared_ptr<VisualObjectMatch> >& matches, 00142 const uint numthreads = 4, 00143 const float kcoeff = 0.5F, 00144 const float acoeff = 0.5F, 00145 const float minscore = 1.0F, 00146 const uint mink = 3U, 00147 const uint kthresh = 6U, 00148 const bool sortbypf = false); 00149 00150 00151 void createVisualObjectDB(std::istream& is, VisualObjectDB& vdb, bool preloadImage = true); 00152 00153 private: 00154 std::string itsName; 00155 std::vector< rutz::shared_ptr<VisualObject> > itsObjects; // objects 00156 rutz::shared_ptr<KDTree> itsKDTree; 00157 std::vector< std::pair<uint,uint> > itsKDindices; // <objidx, kpidx> 00158 00159 // sort object db according to preattentive feature vector similarity 00160 void computeSortedIndices(std::vector<uint>& indices, 00161 const rutz::shared_ptr<VisualObject>& obj) const; 00162 00163 friend std::istream& operator>>(std::istream& is, VisualObjectDB& vdb); 00164 friend std::ostream& operator<<(std::ostream& os, const VisualObjectDB& vdb); 00165 }; 00166 00167 // ###################################################################### 00168 // VisualObjectDB I/O functions 00169 // ###################################################################### 00170 00171 //! Load a VisualObjectDB from an istream 00172 std::istream& operator>>(std::istream& is, VisualObjectDB& vdb); 00173 00174 //! Save a VisualObjectDB to an ostream 00175 std::ostream& operator<<(std::ostream& os, const VisualObjectDB& vdb); 00176 00177 00178 // ###################################################################### 00179 // VisualObjectDB inline function implementations 00180 // ###################################################################### 00181 00182 inline std::string VisualObjectDB::getName() const 00183 { return itsName; } 00184 00185 inline void VisualObjectDB::setName(const std::string& name) 00186 { itsName = name; } 00187 00188 inline uint VisualObjectDB::numObjects() const 00189 { return itsObjects.size(); } 00190 00191 inline void VisualObjectDB::eraseObject(const uint index) 00192 { 00193 ASSERT(index < itsObjects.size()); 00194 itsObjects.erase(itsObjects.begin() + index); 00195 } 00196 00197 inline void VisualObjectDB::clearObjects(uint size) 00198 { 00199 itsObjects.clear(); 00200 if(size > 0) itsObjects.resize(size); 00201 } 00202 00203 inline const rutz::shared_ptr<VisualObject>& 00204 VisualObjectDB::getObject(const uint index) const 00205 { 00206 ASSERT(index < itsObjects.size()); 00207 return itsObjects[index]; 00208 } 00209 00210 inline rutz::shared_ptr<VisualObject> 00211 VisualObjectDB::getObject(const std::string objectName) const 00212 { 00213 std::vector< rutz::shared_ptr<VisualObject> >::const_iterator 00214 vo = itsObjects.begin(), stop = itsObjects.end(); 00215 00216 while (vo != stop) 00217 { 00218 if ((*vo)->getName().compare(objectName) == 0) return *vo; 00219 ++ vo; 00220 } 00221 00222 // not found, return an uninitialized rutz::shared_ptr: 00223 return rutz::shared_ptr<VisualObject>(); 00224 } 00225 00226 inline void VisualObjectDB::setObject(const uint index, const rutz::shared_ptr<VisualObject>& obj) 00227 { 00228 ASSERT(index < itsObjects.size()); 00229 itsObjects[index] = obj; 00230 } 00231 00232 #endif 00233 00234 // ###################################################################### 00235 /* So things look consistent in everyone's emacs... */ 00236 /* Local Variables: */ 00237 /* indent-tabs-mode: nil */ 00238 /* End: */