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/VisualTrackerService.H"
00039 #include "Image/ColorOps.H"
00040
00041 const ModelOptionCateg MOC_VT = {
00042 MOC_SORTPRI_2, "Visual Tracker Related Options" };
00043
00044 static const ModelOptionDef OPT_VT_TrackIOR =
00045 { MODOPT_ARG(int), "VCTrackIOR", &MOC_VT, OPTEXP_CORE,
00046 "Number of frames to wait before deciding to stop the tracker",
00047 "vt-track-ior", '\0', "<int>", "-1" };
00048
00049 VisualTrackerI::VisualTrackerI(OptionManager& mgr,
00050 const std::string& descrName,
00051 const std::string& tagName ) :
00052 ModelComponent(mgr, descrName, tagName),
00053 itsTrackIOR(&OPT_VT_TrackIOR, this, ALLOW_ONLINE_CHANGES)
00054 {
00055
00056 IceStorm::TopicPrx topicPrx;
00057 itsTopicsSubscriptions.push_back(TopicInfo("RetinaTopic", topicPrx));
00058 itsTopicsSubscriptions.push_back(TopicInfo("PrefrontalCortexTopic", topicPrx));
00059
00060 #ifdef HAVE_OPENCV
00061 this->points[0] = NULL;
00062 this->points[1] = NULL;
00063 this->status = NULL;
00064 this->track_error = NULL;
00065 this->pyramid = NULL;
00066 this->prev_pyramid = NULL;
00067 #endif
00068 itsInitTracker = true;
00069 itsInitTargets = true;
00070 itsTracking = false;
00071 itsTrackFrames = 0;
00072
00073 }
00074
00075 VisualTrackerI::~VisualTrackerI()
00076 {
00077 unsubscribeSimEvents();
00078 #ifdef HAVE_OPENCV
00079
00080
00081
00082 cvReleaseImage(&this->pyramid);
00083 cvReleaseImage(&this->prev_pyramid);
00084 #endif
00085
00086 }
00087
00088 void VisualTrackerI::initSimEvents(Ice::CommunicatorPtr icPtr, Ice::ObjectPrx objectPrx)
00089 {
00090
00091 Ice::ObjectPrx obj = icPtr->stringToProxy("SimEvents/TopicManager:tcp -p 11111");
00092 IceStorm::TopicManagerPrx topicManager =
00093 IceStorm::TopicManagerPrx::checkedCast(obj);
00094
00095
00096 IceStorm::TopicPrx topic;
00097 try {
00098 topic = topicManager->retrieve("VisualTrackerTopic");
00099 } catch (const IceStorm::NoSuchTopic&) {
00100 topic = topicManager->create("VisualTrackerTopic");
00101 }
00102
00103 Ice::ObjectPrx pub = topic->getPublisher()->ice_oneway();
00104 itsEventsPub = SimEvents::EventsPrx::uncheckedCast(pub);
00105
00106
00107 itsObjectPrx = objectPrx;
00108
00109 for(uint i=0; i<itsTopicsSubscriptions.size(); i++)
00110 {
00111 try {
00112 IceStorm::QoS qos;
00113 itsTopicsSubscriptions[i].topicPrx =
00114 topicManager->retrieve(itsTopicsSubscriptions[i].name.c_str());
00115 itsTopicsSubscriptions[i].topicPrx->subscribeAndGetPublisher(qos, itsObjectPrx);
00116 } catch (const IceStorm::NoSuchTopic&) {
00117 LFATAL("Error! No %s topic found!", itsTopicsSubscriptions[i].name.c_str());
00118 } catch (const char* msg) {
00119 LINFO("Error %s", msg);
00120 } catch (const Ice::Exception& e) {
00121 cerr << e << endl;
00122 }
00123
00124 }
00125 }
00126
00127 void VisualTrackerI::unsubscribeSimEvents()
00128 {
00129
00130 for(uint i=0; i<itsTopicsSubscriptions.size(); i++)
00131 {
00132 itsTopicsSubscriptions[i].topicPrx->unsubscribe(itsObjectPrx);
00133 }
00134 }
00135
00136
00137
00138 void VisualTrackerI::evolve(const SimEvents::EventMessagePtr& eMsg,
00139 const Ice::Current&)
00140 {
00141 if (eMsg->ice_isA("::SimEvents::VisualTrackerBiasMessage")){
00142 SimEvents::VisualTrackerBiasMessagePtr msg = SimEvents::VisualTrackerBiasMessagePtr::dynamicCast(eMsg);
00143 itsTrackLocs.clear();
00144 for(uint i=0; i<msg->locToTrack.size(); i++)
00145 {
00146 itsTrackLocs.push_back(msg->locToTrack[i]);
00147 Point2D<int> trackLoc = Point2D<int>(msg->locToTrack[i].pos.i, msg->locToTrack[i].pos.j);
00148 LINFO("Tracking %ix%i", trackLoc.i, trackLoc.j);
00149 break;
00150 }
00151 itsInitTargets = true;
00152 } else if(eMsg->ice_isA("::SimEvents::RetinaMessage")){
00153 SimEvents::RetinaMessagePtr msg = SimEvents::RetinaMessagePtr::dynamicCast(eMsg);
00154 Image<PixRGB<byte> > img = Ice2Image<PixRGB<byte> > (msg->img);
00155
00156 if (itsInitTracker)
00157 initTracker(img.getDims());
00158
00159 if (itsInitTargets)
00160 setTargets(luminance(img));
00161
00162 Point2D<int> targetLoc(-1,-1);
00163 if (itsTracking)
00164 {
00165 targetLoc = trackObjects(luminance(img));
00166 }
00167
00168 SimEvents::VisualTrackerMessagePtr bMsg = new SimEvents::VisualTrackerMessage;
00169 if (targetLoc.isValid())
00170 {
00171
00172 SimEvents::TrackInfo trackInfo;
00173 trackInfo.pos.i = targetLoc.i;
00174 trackInfo.pos.j = targetLoc.j;
00175 bMsg->trackLocs.push_back(trackInfo);
00176 }
00177 itsEventsPub->evolve(bMsg);
00178 }
00179 }
00180
00181 void VisualTrackerI::initTracker(Dims imageDims, int nPoints, int wz )
00182 {
00183 win_size = 30;
00184
00185 #ifdef HAVE_OPENCV
00186 MAX_COUNT = nPoints;
00187 count = 0;
00188 points[0] = (CvPoint2D32f*)cvAlloc(MAX_COUNT*sizeof(points[0][0]));
00189 points[1] = (CvPoint2D32f*)cvAlloc(MAX_COUNT*sizeof(points[0][0]));
00190
00191 prev_grey = Image<byte>(imageDims, ZEROS);
00192 pyramid = cvCreateImage( cvSize(imageDims.w(), imageDims.h()), 8, 1 );
00193 prev_pyramid = cvCreateImage( cvSize(imageDims.w(), imageDims.h()), 8, 1 );
00194 status = (char*)cvAlloc(MAX_COUNT);
00195 track_error = (float*)cvAlloc(MAX_COUNT);
00196 #endif
00197 flags = 0;
00198 itsInitTracker = false;
00199 itsTrackFrames = 0;
00200
00201
00202
00203 SimEvents::VisualTrackerMessagePtr bMsg = new SimEvents::VisualTrackerMessage;
00204 itsEventsPub->evolve(bMsg);
00205
00206 }
00207
00208
00209 void VisualTrackerI::setTargets(const Image<byte>& grey)
00210 {
00211 #ifdef HAVE_OPENCV
00212 count = MAX_COUNT;
00213
00214 IplImage* tmp = img2ipl(grey);
00215 for(uint i=0; i<itsTrackLocs.size(); i++)
00216 {
00217 Point2D<int> trackLoc = Point2D<int>(itsTrackLocs[i].pos.i, itsTrackLocs[i].pos.j);
00218 LINFO("Setting target to %ix%i", trackLoc.i, trackLoc.j);
00219 points[1][0].x = trackLoc.i;
00220 points[1][0].y = trackLoc.j;
00221
00222 cvFindCornerSubPix(tmp, points[1], count,
00223 cvSize(win_size,win_size), cvSize(-1,-1),
00224 cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,
00225 20,0.03));
00226 cvReleaseImageHeader(&tmp);
00227
00228 prev_grey = grey;
00229 break;
00230 }
00231 flags = 0;
00232 IplImage *swap_temp;
00233 CV_SWAP( prev_pyramid, pyramid, swap_temp );
00234 CV_SWAP( points[0], points[1], swap_points );
00235
00236 #endif
00237
00238 itsTracking = true;
00239 itsInitTargets = false;
00240 itsTrackFrames = 0;
00241
00242 }
00243
00244
00245 Point2D<int> VisualTrackerI::trackObjects(const Image<byte>& grey)
00246 {
00247 Point2D<int> targetLoc(-1,-1);
00248
00249
00250 if (itsTrackIOR.getVal() != -1 &&
00251 (int)itsTrackFrames >= itsTrackIOR.getVal())
00252 {
00253 LINFO("Appling IOR");
00254 itsTrackFrames = 0;
00255 itsTracking = false;
00256 return targetLoc;
00257 }
00258
00259
00260 #ifdef HAVE_OPENCV
00261 if (count > 0)
00262 {
00263 IplImage* tmp1 = img2ipl(prev_grey);
00264 IplImage* tmp2 = img2ipl(grey);
00265
00266
00267
00268 cvCalcOpticalFlowPyrLK(tmp1, tmp2, prev_pyramid, pyramid,
00269 points[0], points[1], count,
00270 cvSize(win_size,win_size), 3, status, track_error,
00271 cvTermCriteria(CV_TERMCRIT_ITER
00272 |CV_TERMCRIT_EPS,
00273 20,0.03), flags);
00274
00275 flags = CV_LKFLOW_PYR_A_READY | CV_LKFLOW_PYR_B_READY;
00276
00277 cvReleaseImageHeader(&tmp1);
00278 cvReleaseImageHeader(&tmp2);
00279
00280
00281
00282 int k, i;
00283 for(i = k = 0; i<count; i++)
00284 {
00285 if (!status[i])
00286 continue;
00287
00288 points[1][k++] = points[1][i];
00289
00290 if (track_error[i] < 2000)
00291 {
00292 targetLoc.i = std::min(grey.getWidth()-1, std::max(0, (int)points[0][i].x));
00293 targetLoc.j = std::min(grey.getHeight()-1, std::max(0, (int)points[0][i].y));
00294 ASSERT(grey.coordsOk(targetLoc));
00295 }
00296 }
00297 count = k;
00298
00299 }
00300
00301 IplImage *swap_temp;
00302 CV_SWAP( prev_pyramid, pyramid, swap_temp );
00303 CV_SWAP( points[0], points[1], swap_points );
00304
00305 prev_grey = grey;
00306 #endif
00307
00308 itsTrackFrames++;
00309
00310 return targetLoc;
00311 }
00312
00313
00314
00315
00316
00317 class VisualTrackerService : public Ice::Service {
00318 protected:
00319 virtual bool start(int, char* argv[]);
00320 virtual bool stop() {
00321 if (itsMgr)
00322 delete itsMgr;
00323 return true;
00324 }
00325
00326 private:
00327 Ice::ObjectAdapterPtr itsAdapter;
00328 ModelManager *itsMgr;
00329 };
00330
00331 bool VisualTrackerService::start(int argc, char* argv[])
00332 {
00333
00334 itsMgr = new ModelManager("VisualTrackerService");
00335
00336 nub::ref<VisualTrackerI> vt(new VisualTrackerI(*itsMgr));
00337 itsMgr->addSubComponent(vt);
00338
00339 itsMgr->parseCommandLine((const int)argc, (const char**)argv, "", 0, 0);
00340
00341 char adapterStr[255];
00342 sprintf(adapterStr, "default -p %i", BrainObjects::VisualTrackerPort);
00343 itsAdapter = communicator()->createObjectAdapterWithEndpoints("VisualTrackerAdapter",
00344 adapterStr);
00345
00346 Ice::ObjectPtr object = vt.get();
00347 Ice::ObjectPrx objectPrx = itsAdapter->add(object, communicator()->stringToIdentity("VisualTracker"));
00348 vt->initSimEvents(communicator(), objectPrx);
00349 itsAdapter->activate();
00350
00351 itsMgr->start();
00352
00353 return true;
00354 }
00355
00356
00357 int main(int argc, char** argv) {
00358
00359 VisualTrackerService svc;
00360 return svc.main(argc, argv);
00361 }
00362
00363