InferotemporalCortexServiceMysql.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/InferotemporalCortexServiceMysql.C $
00035 // $Id: InferotemporalCortexServiceMysql.C 12962 2010-03-06 02:13:53Z irock $
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("SegmenterTopic", topicPrx));
00053 
00054     itsDBCon = new mysqlpp::Connection(false);
00055 
00056     //Connect to the database
00057     const char* db = "ObjRec", *server = "localhost", *user = "neobrain", *pass = "12341234";
00058     if (!itsDBCon->connect(db, server, user, pass))
00059         LFATAL("DB connection failed: ");
00060    // , itsDBCon->error().c_str());
00061 }
00062 
00063 InferotemporalCortexI::~InferotemporalCortexI()
00064 {
00065   unsubscribeSimEvents();
00066 }
00067 
00068 void InferotemporalCortexI::initSimEvents(Ice::CommunicatorPtr icPtr, Ice::ObjectPrx objectPrx)
00069 {
00070   //Get the IceStorm object
00071   Ice::ObjectPrx obj = icPtr->stringToProxy("SimEvents/TopicManager:tcp -h ilab21 -p 11111");
00072   IceStorm::TopicManagerPrx topicManager =
00073     IceStorm::TopicManagerPrx::checkedCast(obj);
00074 
00075   //Create a InferotemporalCortex Topic
00076   IceStorm::TopicPrx topic;
00077   try {
00078     topic = topicManager->retrieve("InferotemporalCortexTopic"); //check if the Retina topic exists
00079   } catch (const IceStorm::NoSuchTopic&) {
00080     topic = topicManager->create("InferotemporalCortexTopic"); //The retina topic does not exists, create
00081   }
00082   //Make a one way visualCortex message publisher for efficency
00083   Ice::ObjectPrx pub = topic->getPublisher()->ice_oneway();
00084   itsEventsPub = SimEvents::EventsPrx::uncheckedCast(pub);
00085 
00086   //Subscribe the SimulationViewer to theTopics
00087   itsObjectPrx = objectPrx;
00088   //subscribe  to the topics
00089   for(uint i=0; i<itsTopicsSubscriptions.size();  i++)
00090   {
00091     try {
00092       IceStorm::QoS qos;
00093       itsTopicsSubscriptions[i].topicPrx =
00094         topicManager->retrieve(itsTopicsSubscriptions[i].name.c_str()); //Get the
00095       itsTopicsSubscriptions[i].topicPrx->subscribeAndGetPublisher(qos, itsObjectPrx); //Subscribe to the retina topic
00096     } catch (const IceStorm::NoSuchTopic&) {
00097       LFATAL("Error! No %s topic found!", itsTopicsSubscriptions[i].name.c_str());
00098     }
00099   }
00100 }
00101 
00102 void InferotemporalCortexI::unsubscribeSimEvents()
00103 {
00104   //Unsubscribe from all the topics we are registerd to
00105   for(uint i=0; i<itsTopicsSubscriptions.size();  i++)
00106   {
00107     itsTopicsSubscriptions[i].topicPrx->unsubscribe(itsObjectPrx);
00108   }
00109 }
00110 
00111 
00112 bool InferotemporalCortexI::initVDB()
00113 {
00114   itsUseColor = false;
00115   itsTrainingMode = false;
00116   itsVDBFile = "objects.vdb";
00117   itsMaxLabelHistory = 1;
00118   itsVDB.loadFrom(itsVDBFile);
00119 
00120   return true;
00121 }
00122 
00123 //The VC excepts a retina image and posts a saliency map
00124 void InferotemporalCortexI::evolve(const SimEvents::EventMessagePtr& eMsg,
00125       const Ice::Current&)
00126 {
00127   if (eMsg->ice_isA("::SimEvents::SegmenterMessage")){
00128     SimEvents::SegmenterMessagePtr msg = SimEvents::SegmenterMessagePtr::dynamicCast(eMsg);
00129     for(uint i=0; i<msg->segLocs.size(); i++)
00130     {
00131       SimEvents::SegInfo segInfo = msg->segLocs[i];
00132       Image<PixRGB<byte> > segImg = Ice2Image<PixRGB<byte> >(segInfo.img);
00133       Rectangle segRect(Point2D<int>(segInfo.rect.tl.i, segInfo.rect.tl.j),
00134           Dims(segInfo.rect.br.i - segInfo.rect.tl.i,
00135             segInfo.rect.br.j - segInfo.rect.tl.j));
00136 
00137 
00138       ////Rescale the image to provide some scale inveriance
00139       //Image<PixRGB<byte> > inputImg = rescale(segImg, 256, 256);
00140       itsImgMutex.lock();
00141       itsCurrentImg = segImg;
00142       itsImgMutex.unlock();
00143     }
00144   }
00145 }
00146 
00147 void InferotemporalCortexI::run()
00148 {
00149 
00150   while(1)
00151   {
00152     itsImgMutex.lock();
00153     Image<PixRGB<byte> > img = itsCurrentImg;
00154     itsImgMutex.unlock();
00155     if (!img.initialized())
00156      continue;
00157 
00158     itsTimer.reset();
00159     rutz::shared_ptr<VisualObject>
00160       vo(new VisualObject("PIC", "PIC", img,
00161             Point2D<int>(-1,-1),
00162             std::vector<double>(),
00163             std::vector< rutz::shared_ptr<Keypoint> >(),
00164             itsUseColor));
00165     itsTimer.mark();
00166     LINFO("Keypoint extraction took %f seconds for %i keypoints (%ix%i)",
00167         itsTimer.user_secs(),
00168         vo->numKeypoints(),
00169         img.getWidth(), img.getHeight());
00170 
00171 
00172     mysqlpp::Query query = itsDBCon->query();
00173     //Insert the keypoints into the database if there is not match;
00174     const uint nkp = vo->numKeypoints();
00175     for(uint kpIdx=0; kpIdx<nkp; kpIdx++)
00176     {
00177       LINFO("Searching for keypoint %i of %i", kpIdx, nkp);
00178       //Get the feature fector
00179       char fv[128];
00180       rutz::shared_ptr<Keypoint> keyPoint = vo->getKeypoint(kpIdx);
00181       for(uint i=0; i<keyPoint->getFVlength(); i++)
00182       {
00183         fv[i] = keyPoint->getFVelement(i);
00184         //printf("%i ", (unsigned char)fv[i]);
00185       }
00186       //printf("\n");
00187 
00188       LINFO("Check NN");
00189       itsTimer.reset();
00190       //check if there is a match in the db
00191       bool foundKeypoint = false;
00192       double foundDist = -1;
00193       int foundMatchCount = -1;
00194       int foundIdx = -1;
00195 
00196       string fill(fv, 128);
00197       ostringstream strbuf;
00198       strbuf << "SELECT kid, matchCount, kp_dist(value, \"" << mysqlpp::escape << fill <<"\") as dist from SiftKeypoints order by dist limit 1" << ends;
00199       query << strbuf.str();
00200 
00201       mysqlpp::Result res = query.store();
00202       if (res)
00203       {
00204         mysqlpp::Row row;
00205         mysqlpp::Row::size_type rowIdx;
00206         for (rowIdx = 0; row = res.at(rowIdx); ++rowIdx) {
00207           foundIdx = row["kid"];
00208           foundDist = row["dist"];
00209           foundMatchCount = row["matchCount"];
00210 
00211           if (foundDist < 100000)
00212             foundKeypoint = true;
00213         }
00214       }
00215       itsTimer.mark();
00216       LINFO("NN Searched (idx=%i matchCount=%i dist=%f) took %f seconds (found=%i)",
00217           foundIdx,
00218           foundMatchCount,
00219           foundDist,
00220           itsTimer.user_secs(),
00221           foundKeypoint);
00222 
00223       LINFO("Service Keypoint");
00224       itsTimer.reset();
00225       if (!foundKeypoint)
00226       {
00227         LINFO("Keypoint not found adding");
00228         std::string kpv(fv, 128);
00229         std::ostringstream strbuf;
00230         strbuf << "INSERT INTO SiftKeypoints (value) VALUES (\"" << mysqlpp::escape << kpv <<"\")" << ends;
00231         query.exec(strbuf.str());
00232         printf("Insert keypoint\n");
00233       } else {
00234         //update the frequency;
00235         std::ostringstream strbuf;
00236         foundMatchCount++; //incr the number of times this keyp was found
00237         strbuf << "UPDATE SiftKeypoints set matchCount = " << foundMatchCount << " WHERE kid = " << foundIdx << ends;
00238         query.exec(strbuf.str());
00239         printf("Update keypoint\n");
00240       }
00241       itsTimer.mark();
00242       LINFO("Service keypoint took %f seconds",
00243           itsTimer.user_secs());
00244 
00245       //Show the keypoint
00246       PixRGB<byte> color;
00247       if(foundKeypoint)
00248         color = PixRGB<byte>(0,255,0);
00249       else
00250         color = PixRGB<byte>(255,0,0);
00251 
00252       float x = keyPoint->getX();
00253       float y = keyPoint->getY();
00254       float s = keyPoint->getS();
00255       float o = keyPoint->getO();
00256 
00257       Point2D<int> keypLoc(int(x + 0.5F), int(y + 0.5F));
00258 
00259       drawDisk(img, keypLoc, 2, color);
00260       if (s > 0.0f)
00261         drawLine(img, keypLoc,
00262           Point2D<int>(int(x + s * cosf(o) + 0.5F),
00263             int(y + s * sinf(o) + 0.5F)),
00264           color);
00265 
00266       itsOfs->writeRGB(img, "KeyPoints", FrameInfo("KeyPoints", SRC_POS));
00267     }
00268     LINFO("Continue");
00269 
00270 
00271     LINFO("Done.");
00272   }
00273 }
00274 
00275 std::string InferotemporalCortexI::getBestLabel(const size_t mincount)
00276 {
00277   if (itsRecentLabels.size() == 0)
00278     return std::string();
00279 
00280   std::map<std::string, size_t> counts;
00281 
00282   size_t bestcount = 0;
00283   size_t bestpos = 0;
00284 
00285   for (size_t i = 0; i < itsRecentLabels.size(); ++i)
00286     {
00287       const size_t c = ++(counts[itsRecentLabels[i]]);
00288 
00289       if (c >= bestcount)
00290         {
00291           bestcount = c;
00292           bestpos = i;
00293         }
00294     }
00295 
00296   if (bestcount >= mincount)
00297     return itsRecentLabels[bestpos];
00298 
00299   return std::string();
00300 }
00301 
00302 std::string InferotemporalCortexI::matchObject(Image<PixRGB<byte> > &ima, float &score)
00303 {
00304   //find object in the database
00305   std::vector< rutz::shared_ptr<VisualObjectMatch> > matches;
00306   rutz::shared_ptr<VisualObject>
00307     vo(new VisualObject("PIC", "PIC", ima,
00308                         Point2D<int>(-1,-1),
00309                         std::vector<double>(),
00310                         std::vector< rutz::shared_ptr<Keypoint> >(),
00311                         itsUseColor));
00312 
00313   const uint nmatches = itsVDB.getObjectMatches(vo, matches, VOMA_SIMPLE,
00314                                              100U, //max objs to return
00315                                              0.5F, //keypoint distance score default 0.5F
00316                                              0.5F, //affine distance score default 0.5F
00317                                              1.0F, //minscore  default 1.0F
00318                                              3U, //min # of keypoint match
00319                                              100U, //keypoint selection thershold
00320                                              false //sort by preattentive
00321                                              );
00322 
00323   score = 0;
00324   float avgScore = 0, affineAvgDist = 0;
00325   int nkeyp = 0;
00326   int objId = -1;
00327   if (nmatches > 0)
00328     {
00329       rutz::shared_ptr<VisualObject> obj; //so we will have a ref to the last matches obj
00330       rutz::shared_ptr<VisualObjectMatch> vom;
00331       //for(unsigned int i=0; i< nmatches; i++){
00332       for (unsigned int i = 0; i < 1; ++i)
00333         {
00334           vom = matches[i];
00335           obj = vom->getVoTest();
00336           score = vom->getScore();
00337           nkeyp = vom->size();
00338           avgScore = vom->getKeypointAvgDist();
00339           affineAvgDist = vom->getAffineAvgDist();
00340 
00341           objId = atoi(obj->getName().c_str()+3);
00342 
00343           return obj->getName();
00344           LINFO("### Object match with '%s' score=%f ID:%i",
00345                 obj->getName().c_str(), vom->getScore(), objId);
00346 
00347           //calculate the actual distance (location of keypoints) between
00348           //keypoints. If the same patch was found, then the distance should
00349           //be close to 0
00350           double dist = 0;
00351           for (int keyp=0; keyp<nkeyp; keyp++)
00352             {
00353               const KeypointMatch kpm = vom->getKeypointMatch(keyp);
00354 
00355               float refX = kpm.refkp->getX();
00356               float refY = kpm.refkp->getY();
00357 
00358               float tstX = kpm.tstkp->getX();
00359               float tstY = kpm.tstkp->getY();
00360               dist += (refX-tstX) * (refX-tstX);
00361               dist += (refY-tstY) * (refY-tstY);
00362             }
00363 
00364           //   printf("%i:%s %i %f %i %f %f %f\n", objNum, obj->getName().c_str(),
00365           //       nmatches, score, nkeyp, avgScore, affineAvgDist, sqrt(dist));
00366 
00367           //analizeImage();
00368         }
00369 
00370     }
00371 
00372   return std::string("nomatch");
00373 }
00374 
00375 
00376 
00377 /////////////////////////// The VC Service to init the retina and start as a deamon ///////////////
00378 class InferotemporalCortexService : public Ice::Service {
00379   protected:
00380     virtual bool start(int, char* argv[]);
00381     virtual bool stop() {
00382       if (itsMgr)
00383         delete itsMgr;
00384       return true;
00385     }
00386 
00387   private:
00388     Ice::ObjectAdapterPtr itsAdapter;
00389     ModelManager *itsMgr;
00390 };
00391 
00392 bool InferotemporalCortexService::start(int argc, char* argv[])
00393 {
00394 
00395         itsMgr = new ModelManager("InferotemporalCortexService");
00396 
00397   nub::ref<OutputFrameSeries> ofs(new OutputFrameSeries(*itsMgr));
00398   itsMgr->addSubComponent(ofs);
00399 
00400   nub::ref<InferotemporalCortexI> itc(new InferotemporalCortexI(*itsMgr, ofs));
00401         itsMgr->addSubComponent(itc);
00402 
00403         itsMgr->parseCommandLine((const int)argc, (const char**)argv, "", 0, 0);
00404 
00405   char adapterStr[255];
00406   sprintf(adapterStr, "default -p %i", BrainObjects::InferoTemporalPort);
00407         itsAdapter = communicator()->createObjectAdapterWithEndpoints("InferotemporalCortexAdapter",
00408       adapterStr);
00409 
00410         Ice::ObjectPtr object = itc.get();
00411   Ice::ObjectPrx objectPrx = itsAdapter->add(object, communicator()->stringToIdentity("InferotemporalCortex"));
00412   itc->initSimEvents(communicator(), objectPrx);
00413         itsAdapter->activate();
00414 
00415   itsMgr->start();
00416 
00417   IceUtil::ThreadPtr itcThread = itc.get();
00418   itcThread->start();
00419 
00420 
00421         return true;
00422 }
00423 
00424 // ######################################################################
00425 int main(int argc, char** argv) {
00426 
00427   InferotemporalCortexService svc;
00428   return svc.main(argc, argv);
00429 }
00430 
00431 
Generated on Sun May 8 08:41:02 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3