InferotemporalCortexService.C

00001 /*!@file Neuro/InferotemporalCortexService.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/NeovisionII/InferotemporalCortexService.C $
00035 // $Id: InferotemporalCortexService.C 14522 2011-02-17 01:52:47Z dparks $
00036 //
00037 
00038 #include "NeovisionII/InferotemporalCortexService.H"
00039 #include "Image/ColorOps.H"
00040 #include "Image/DrawOps.H"
00041 #include "Util/sformat.H"
00042 
00043 InferotemporalCortexI::InferotemporalCortexI(OptionManager& mgr,
00044     nub::ref<OutputFrameSeries> ofs,
00045     const std::string& descrName,
00046     const std::string& tagName ) :
00047   ModelComponent(mgr, descrName, tagName),
00048   itsOfs(ofs)
00049 {
00050     //Subscribe to the various topics
00051     IceStorm::TopicPrx topicPrx;
00052     itsTopicsSubscriptions.push_back(TopicInfo("PrefrontalCortexTopic", topicPrx));
00053     initVDB();
00054 }
00055 
00056 InferotemporalCortexI::~InferotemporalCortexI()
00057 {
00058   LINFO("Un suscribe");
00059   unsubscribeSimEvents();
00060 }
00061 
00062 void InferotemporalCortexI::initSimEvents(Ice::CommunicatorPtr icPtr, Ice::ObjectPrx objectPrx)
00063 {
00064   //Get the IceStorm object
00065   Ice::ObjectPrx obj = icPtr->stringToProxy("SimEvents/TopicManager:tcp -p 11111");
00066   IceStorm::TopicManagerPrx topicManager =
00067     IceStorm::TopicManagerPrx::checkedCast(obj);
00068 
00069   //Create a InferotemporalCortex Topic
00070   IceStorm::TopicPrx topic;
00071   try {
00072     topic = topicManager->retrieve("InferotemporalCortexTopic"); //check if the Retina topic exists
00073   } catch (const IceStorm::NoSuchTopic&) {
00074     topic = topicManager->create("InferotemporalCortexTopic"); //The retina topic does not exists, create
00075   }
00076   //Make a one way visualCortex message publisher for efficency
00077   Ice::ObjectPrx pub = topic->getPublisher()->ice_oneway();
00078   itsEventsPub = SimEvents::EventsPrx::uncheckedCast(pub);
00079 
00080   //Subscribe the SimulationViewer to theTopics
00081   itsObjectPrx = objectPrx;
00082   //subscribe  to the topics
00083   for(uint i=0; i<itsTopicsSubscriptions.size();  i++)
00084   {
00085     try {
00086       IceStorm::QoS qos;
00087       itsTopicsSubscriptions[i].topicPrx =
00088         topicManager->retrieve(itsTopicsSubscriptions[i].name.c_str()); //Get the
00089       itsTopicsSubscriptions[i].topicPrx->subscribeAndGetPublisher(qos, itsObjectPrx); //Subscribe to the retina topic
00090     } catch (const IceStorm::NoSuchTopic&) {
00091       LFATAL("Error! No %s topic found!", itsTopicsSubscriptions[i].name.c_str());
00092     } catch (const char* msg) {
00093       LINFO("Error %s", msg);
00094     }
00095   }
00096 }
00097 
00098 void InferotemporalCortexI::unsubscribeSimEvents()
00099 {
00100   //Unsubscribe from all the topics we are registerd to
00101   for(uint i=0; i<itsTopicsSubscriptions.size();  i++)
00102   {
00103     itsTopicsSubscriptions[i].topicPrx->unsubscribe(itsObjectPrx);
00104   }
00105 }
00106 
00107 
00108 bool InferotemporalCortexI::initVDB()
00109 {
00110   itsUseColor = false;
00111   itsTrainingMode = true;
00112   itsVDBFile = "objects.vdb";
00113   itsMaxLabelHistory = 1;
00114   itsVDB.loadFrom(itsVDBFile);
00115 
00116   return true;
00117 }
00118 
00119 //The VC excepts a retina image and posts a saliency map
00120 void InferotemporalCortexI::evolve(const SimEvents::EventMessagePtr& eMsg,
00121       const Ice::Current&)
00122 {
00123   if (eMsg->ice_isA("::SimEvents::InfrotemporalCortexBiasMessage")){
00124     SimEvents::InfrotemporalCortexBiasMessagePtr msg = SimEvents::InfrotemporalCortexBiasMessagePtr::dynamicCast(eMsg);
00125     Image<PixRGB<byte> > objImg = Ice2Image<PixRGB<byte> >(msg->img);
00126 
00127     //Recognize the image
00128     float score;
00129     float rotation = 0;
00130     std::string objName = matchObject(objImg, score, rotation);
00131 
00132     if (objName == "nomatch")
00133     {
00134       itsRecentLabels.resize(0);
00135 
00136       if (itsTrainingMode)
00137       {
00138         LINFO("Enter a label for this object:\n");
00139         std::getline(std::cin, objName);
00140         LINFO("You typed '%s'", objName.c_str());
00141 
00142         if (objName != "" && objName != "exit")
00143         {
00144           rutz::shared_ptr<VisualObject>
00145             vo(new VisualObject(objName.c_str(), "NULL", objImg,
00146                   Point2D<int>(-1,-1),
00147                   std::vector<float>(),
00148                   std::vector< rutz::shared_ptr<Keypoint> >(),
00149                   itsUseColor));
00150           itsVDB.addObject(vo, false);
00151           itsVDB.saveTo(itsVDBFile);
00152         } else {
00153           objName = "nomatch";
00154         }
00155 
00156         SimEvents::InfrotemporalCortexMessagePtr itMsg = new SimEvents::InfrotemporalCortexMessage;
00157         itMsg->objectName = objName;
00158         itMsg->confidence = -1;
00159         itMsg->rotation = rotation;
00160         LINFO("Sending message");
00161         itsEventsPub->evolve(itMsg);
00162 
00163       }
00164       LINFO("NO match");
00165     } else {
00166       const std::string bestObjName = objName;
00167 
00168       //itsRecentLabels.push_back(objName);
00169       //while (itsRecentLabels.size() > 1)
00170       //  itsRecentLabels.pop_front();
00171 
00172       //const std::string bestObjName =
00173       //  getBestLabel(itsRecentLabels, 1);
00174 
00175       LINFO("Found object %s rot=%f", bestObjName.c_str(), rotation);
00176       if (bestObjName.size() > 0)
00177       {
00178         SimEvents::InfrotemporalCortexMessagePtr itMsg = new SimEvents::InfrotemporalCortexMessage;
00179         itMsg->objectName = bestObjName;
00180         itMsg->confidence = score;
00181         itMsg->rotation = rotation;
00182         itsEventsPub->evolve(itMsg);
00183 
00184       }
00185     }
00186     LINFO("Done.");
00187   }
00188 }
00189 
00190 std::string InferotemporalCortexI::getBestLabel(const size_t mincount)
00191 {
00192   if (itsRecentLabels.size() == 0)
00193     return std::string();
00194 
00195   std::map<std::string, size_t> counts;
00196 
00197   size_t bestcount = 0;
00198   size_t bestpos = 0;
00199 
00200   for (size_t i = 0; i < itsRecentLabels.size(); ++i)
00201     {
00202       const size_t c = ++(counts[itsRecentLabels[i]]);
00203 
00204       if (c >= bestcount)
00205         {
00206           bestcount = c;
00207           bestpos = i;
00208         }
00209     }
00210 
00211   if (bestcount >= mincount)
00212     return itsRecentLabels[bestpos];
00213 
00214   return std::string();
00215 }
00216 
00217 std::string InferotemporalCortexI::matchObject(Image<PixRGB<byte> > &ima, float &score, float &rotation)
00218 {
00219   //find object in the database
00220   std::vector< rutz::shared_ptr<VisualObjectMatch> > matches;
00221   rutz::shared_ptr<VisualObject>
00222     vo(new VisualObject("PIC", "NULL", ima,
00223           Point2D<int>(-1,-1),
00224           std::vector<float>(),
00225           std::vector< rutz::shared_ptr<Keypoint> >(),
00226           itsUseColor));
00227 
00228   Image<PixRGB<byte> > siftImg = vo->getKeypointImage();
00229   itsOfs->writeRGB(siftImg, "SIFTKeypoints", FrameInfo("SiftKeypoints", SRC_POS));
00230   itsOfs->updateNext();
00231   usleep(10000);
00232 
00233   const uint nmatches = itsVDB.getObjectMatches(vo, matches, VOMA_SIMPLE,
00234       10000U, //max objs to return
00235       0.5F, //keypoint distance score default 0.5F
00236       0.5F, //affine distance score default 0.5F
00237       1.0F, //minscore  default 1.0F
00238       3U, //min # of keypoint match
00239       100U, //keypoint selection thershold
00240       false //sort by preattentive
00241       );
00242 
00243   score = 0;
00244   //float avgScore = 0, affineAvgDist = 0;
00245   int nkeyp = 0;
00246   int objId = -1;
00247   if (nmatches > 0)
00248   {
00249     rutz::shared_ptr<VisualObject> obj; //so we will have a ref to the last matches obj
00250     rutz::shared_ptr<VisualObjectMatch> vom;
00251     //for(unsigned int i=0; i< nmatches; i++){
00252     for (unsigned int i = 0; i < 1; ++i)
00253     {
00254       vom = matches[i];
00255       obj = vom->getVoTest();
00256       score = vom->getScore();
00257       nkeyp = vom->size();
00258       //avgScore = vom->getKeypointAvgDist();
00259       //affineAvgDist = vom->getAffineAvgDist();
00260 
00261       objId = atoi(obj->getName().c_str()+3);
00262 
00263       //Get the rotation
00264       float theta, sx, sy, str;
00265       SIFTaffine aff = vom->getSIFTaffine();
00266       aff.decompose(theta, sx, sy, str);
00267       rotation = theta;
00268 
00269 
00270       return obj->getName();
00271       LINFO("### Object match with '%s' score=%f ID:%i",
00272           obj->getName().c_str(), vom->getScore(), objId);
00273 
00274       //calculate the actual distance (location of keypoints) between
00275       //keypoints. If the same patch was found, then the distance should
00276       //be close to 0
00277       double dist = 0;
00278       for (int keyp=0; keyp<nkeyp; keyp++)
00279       {
00280         const KeypointMatch kpm = vom->getKeypointMatch(keyp);
00281 
00282         float refX = kpm.refkp->getX();
00283         float refY = kpm.refkp->getY();
00284 
00285         float tstX = kpm.tstkp->getX();
00286         float tstY = kpm.tstkp->getY();
00287         dist += (refX-tstX) * (refX-tstX);
00288         dist += (refY-tstY) * (refY-tstY);
00289       }
00290 
00291       //   printf("%i:%s %i %f %i %f %f %f\n", objNum, obj->getName().c_str(),
00292       //       nmatches, score, nkeyp, avgScore, affineAvgDist, sqrt(dist));
00293 
00294       //analizeImage();
00295     }
00296 
00297   }
00298 
00299   return std::string("nomatch");
00300   }
00301 
00302 
00303 
00304 /////////////////////////// The VC Service to init the retina and start as a deamon ///////////////
00305 class InferotemporalCortexService : public Ice::Service {
00306   protected:
00307     virtual bool start(int, char* argv[]);
00308     virtual bool stop() {
00309       if (itsMgr)
00310         delete itsMgr;
00311       return true;
00312     }
00313 
00314   private:
00315     Ice::ObjectAdapterPtr itsAdapter;
00316     ModelManager *itsMgr;
00317 };
00318 
00319 bool InferotemporalCortexService::start(int argc, char* argv[])
00320 {
00321 
00322   itsMgr = new ModelManager("InferotemporalCortexService");
00323 
00324   nub::ref<OutputFrameSeries> ofs(new OutputFrameSeries(*itsMgr));
00325   itsMgr->addSubComponent(ofs);
00326 
00327   nub::ref<InferotemporalCortexI> itc(new InferotemporalCortexI(*itsMgr, ofs));
00328   itsMgr->addSubComponent(itc);
00329 
00330   itsMgr->parseCommandLine((const int)argc, (const char**)argv, "", 0, 0);
00331 
00332   char adapterStr[255];
00333   sprintf(adapterStr, "default -p %i", BrainObjects::InferoTemporalPort);
00334   itsAdapter = communicator()->createObjectAdapterWithEndpoints("InferotemporalCortexAdapter",
00335       adapterStr);
00336 
00337   Ice::ObjectPtr object = itc.get();
00338   Ice::ObjectPrx objectPrx = itsAdapter->add(object, communicator()->stringToIdentity("InferotemporalCortex"));
00339   itc->initSimEvents(communicator(), objectPrx);
00340   itsAdapter->activate();
00341 
00342   itsMgr->start();
00343 
00344   return true;
00345 }
00346 
00347 // ######################################################################
00348 int main(int argc, char** argv) {
00349 
00350   InferotemporalCortexService svc;
00351   return svc.main(argc, argv);
00352 }
00353 
00354 
Generated on Sun May 8 08:41:02 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3