00001 /*!@file SeaBee/SiftRec.C */ 00002 00003 // //////////////////////////////////////////////////////////////////// // 00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005 // 00005 // by the 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: Lior Elazary 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/SeaBee/SiftRec.C $ 00035 // $Id: SiftRec.C 10794 2009-02-08 06:21:09Z itti $ 00036 // 00037 00038 #include "SeaBee/SiftRec.H" 00039 #include "Image/ColorOps.H" 00040 #include "Image/DrawOps.H" 00041 #include "Util/sformat.H" 00042 00043 const ModelOptionCateg MOC_SiftRecOps = { 00044 MOC_SORTPRI_3, "SiftRec options" }; 00045 00046 const ModelOptionDef OPT_VDBFileName = 00047 { MODOPT_ARG(std::string), "VDBFileName", &MOC_SiftRecOps, OPTEXP_CORE, 00048 "The visual database file name", 00049 "vdb-filename", '\0', "", "objects.vdb" }; 00050 00051 const ModelOptionDef OPT_SiftUseColor = 00052 { MODOPT_FLAG, "SiftUseColor", &MOC_SiftRecOps, OPTEXP_CORE, 00053 "Use color in the Sift descriptor", 00054 "use-color", '\0', "", "false" }; 00055 00056 00057 SiftRec::SiftRec(OptionManager& mgr, 00058 const std::string& descrName, 00059 const std::string& tagName ) : 00060 ModelComponent(mgr, descrName, tagName), 00061 itsVDBFile(&OPT_VDBFileName, this, ALLOW_ONLINE_CHANGES), 00062 itsUseColor(&OPT_SiftUseColor, this, ALLOW_ONLINE_CHANGES) 00063 { 00064 } 00065 00066 SiftRec::~SiftRec() 00067 { 00068 } 00069 00070 00071 bool SiftRec::initVDB() 00072 { 00073 itsTrainingMode = false; 00074 itsMaxLabelHistory = 1; 00075 itsVDB.loadFrom(itsVDBFile.getVal()); 00076 00077 return true; 00078 } 00079 00080 void SiftRec::getObject(const Image<PixRGB<byte> > &img) 00081 { 00082 ////Rescale the image to provide some scale inveriance 00083 //Image<PixRGB<byte> > inputImg = rescale(img, 256, 256); 00084 Image<PixRGB<byte> > inputImg = img; 00085 00086 //float matchScore = 0; 00087 std::string objectName; //TODO = matchObject(inputImg, matchScore); 00088 if (objectName == "nomatch") 00089 { 00090 itsRecentLabels.resize(0); 00091 if (itsTrainingMode) 00092 { 00093 LINFO("Enter a lebel for this object:"); 00094 std::getline(std::cin, objectName); 00095 if (objectName != "") 00096 { 00097 rutz::shared_ptr<VisualObject> 00098 vo(new VisualObject(objectName.c_str(), "NULL", inputImg, 00099 Point2D<int>(-1,-1), 00100 std::vector<double>(), 00101 std::vector< rutz::shared_ptr<Keypoint> >(), 00102 itsUseColor.getVal())); 00103 itsVDB.addObject(vo); 00104 itsVDB.saveTo(itsVDBFile.getVal()); 00105 } 00106 } 00107 } else { 00108 itsRecentLabels.push_back(objectName); 00109 while(itsRecentLabels.size() > itsMaxLabelHistory) 00110 itsRecentLabels.pop_front(); 00111 00112 const std::string bestObjName = getBestLabel(1); 00113 00114 if (bestObjName.size() > 0) 00115 { 00116 //itMsg->objectName = std::string("Test"); 00117 //itMsg->objLoc.i = segInfo.rect.tl.i; 00118 //itMsg->objLoc.j = segInfo.rect.tl.j; 00119 00120 //itMsg->confidence = matchScore*100.0F; 00121 //itsEventsPub->evolve(itMsg); 00122 } 00123 } 00124 00125 } 00126 00127 void SiftRec::trainObject(const Image<PixRGB<byte> > &img, const std::string& objectName) 00128 { 00129 if (objectName != "") 00130 { 00131 rutz::shared_ptr<VisualObject> 00132 vo(new VisualObject(objectName.c_str(), "NULL", img, 00133 Point2D<int>(-1,-1), 00134 std::vector<double>(), 00135 std::vector< rutz::shared_ptr<Keypoint> >(), 00136 itsUseColor.getVal())); 00137 itsVDB.addObject(vo, false); 00138 itsVDB.saveTo(itsVDBFile.getVal()); 00139 } 00140 } 00141 00142 std::string SiftRec::getBestLabel(const size_t mincount) 00143 { 00144 if (itsRecentLabels.size() == 0) 00145 return std::string(); 00146 00147 std::map<std::string, size_t> counts; 00148 00149 size_t bestcount = 0; 00150 size_t bestpos = 0; 00151 00152 for (size_t i = 0; i < itsRecentLabels.size(); ++i) 00153 { 00154 const size_t c = ++(counts[itsRecentLabels[i]]); 00155 00156 if (c >= bestcount) 00157 { 00158 bestcount = c; 00159 bestpos = i; 00160 } 00161 } 00162 00163 if (bestcount >= mincount) 00164 return itsRecentLabels[bestpos]; 00165 00166 return std::string(); 00167 } 00168 00169 std::string SiftRec::matchObject(Image<PixRGB<byte> > &ima, float &score, Rectangle& rect) 00170 { 00171 //find object in the database 00172 std::vector< rutz::shared_ptr<VisualObjectMatch> > matches; 00173 rutz::shared_ptr<VisualObject> 00174 vo(new VisualObject("PIC", "PIC", ima, 00175 Point2D<int>(-1,-1), 00176 std::vector<double>(), 00177 std::vector< rutz::shared_ptr<Keypoint> >(), 00178 itsUseColor.getVal())); 00179 00180 const uint nmatches = itsVDB.getObjectMatches(vo, matches, VOMA_SIMPLE, 00181 100U, //max objs to return 00182 0.5F, //keypoint distance score default 0.5F 00183 0.5F, //affine distance score default 0.5F 00184 1.0F, //minscore default 1.0F 00185 3U, //min # of keypoint match 00186 100U, //keypoint selection thershold 00187 false //sort by preattentive 00188 ); 00189 00190 score = 0; 00191 float avgScore = 0, affineAvgDist = 0; 00192 int nkeyp = 0; 00193 int objId = -1; 00194 if (nmatches > 0) 00195 { 00196 rutz::shared_ptr<VisualObject> obj; //so we will have a ref to the last matches obj 00197 rutz::shared_ptr<VisualObjectMatch> vom; 00198 //for(unsigned int i=0; i< nmatches; i++){ 00199 for (unsigned int i = 0; i < 1; ++i) 00200 { 00201 vom = matches[i]; 00202 obj = vom->getVoTest(); 00203 score = vom->getScore(); 00204 nkeyp = vom->size(); 00205 avgScore = vom->getKeypointAvgDist(); 00206 affineAvgDist = vom->getAffineAvgDist(); 00207 00208 Point2D<int> tl, tr, br, bl; 00209 vom->getTransfTestOutline(tl, tr, br, bl); 00210 LINFO("%ix%i %ix%i %ix%i %ix%i", 00211 tl.i, tl.j, tr.i, tr.j, 00212 br.i, br.j, bl.i, bl.j); 00213 00214 //if (tl.i+br.i, tl.j+br.j) 00215 //{ 00216 // Dims rectDims = Dims(tl.i+br.i, tl.j+br.j); 00217 // rect = Rectangle(tl, rectDims); //Onlyh the tl and br 00218 //} 00219 00220 00221 objId = atoi(obj->getName().c_str()+3); 00222 00223 return obj->getName(); 00224 LINFO("### Object match with '%s' score=%f ID:%i", 00225 obj->getName().c_str(), vom->getScore(), objId); 00226 00227 //calculate the actual distance (location of keypoints) between 00228 //keypoints. If the same patch was found, then the distance should 00229 //be close to 0 00230 double dist = 0; 00231 for (int keyp=0; keyp<nkeyp; keyp++) 00232 { 00233 const KeypointMatch kpm = vom->getKeypointMatch(keyp); 00234 00235 float refX = kpm.refkp->getX(); 00236 float refY = kpm.refkp->getY(); 00237 00238 float tstX = kpm.tstkp->getX(); 00239 float tstY = kpm.tstkp->getY(); 00240 dist += (refX-tstX) * (refX-tstX); 00241 dist += (refY-tstY) * (refY-tstY); 00242 } 00243 00244 // printf("%i:%s %i %f %i %f %f %f\n", objNum, obj->getName().c_str(), 00245 // nmatches, score, nkeyp, avgScore, affineAvgDist, sqrt(dist)); 00246 00247 //analizeImage(); 00248 } 00249 00250 } 00251 00252 return std::string("nomatch"); 00253 } 00254