00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
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
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
00065 Ice::ObjectPrx obj = icPtr->stringToProxy("SimEvents/TopicManager:tcp -p 11111");
00066 IceStorm::TopicManagerPrx topicManager =
00067 IceStorm::TopicManagerPrx::checkedCast(obj);
00068
00069
00070 IceStorm::TopicPrx topic;
00071 try {
00072 topic = topicManager->retrieve("InferotemporalCortexTopic");
00073 } catch (const IceStorm::NoSuchTopic&) {
00074 topic = topicManager->create("InferotemporalCortexTopic");
00075 }
00076
00077 Ice::ObjectPrx pub = topic->getPublisher()->ice_oneway();
00078 itsEventsPub = SimEvents::EventsPrx::uncheckedCast(pub);
00079
00080
00081 itsObjectPrx = objectPrx;
00082
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());
00089 itsTopicsSubscriptions[i].topicPrx->subscribeAndGetPublisher(qos, itsObjectPrx);
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
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
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
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
00169
00170
00171
00172
00173
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
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,
00235 0.5F,
00236 0.5F,
00237 1.0F,
00238 3U,
00239 100U,
00240 false
00241 );
00242
00243 score = 0;
00244
00245 int nkeyp = 0;
00246 int objId = -1;
00247 if (nmatches > 0)
00248 {
00249 rutz::shared_ptr<VisualObject> obj;
00250 rutz::shared_ptr<VisualObjectMatch> vom;
00251
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
00259
00260
00261 objId = atoi(obj->getName().c_str()+3);
00262
00263
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
00275
00276
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
00292
00293
00294
00295 }
00296
00297 }
00298
00299 return std::string("nomatch");
00300 }
00301
00302
00303
00304
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