VisualTrackerService.C

00001 /*!@file Neuro/VisualTrackerService.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/VisualTrackerService.C $
00035 // $Id: VisualTrackerService.C 12962 2010-03-06 02:13:53Z irock $
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     //Subscribe to the various topics
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   //cvFree(&this->points[0]);
00080   //cvFree(&this->points[1]);
00081   //cvFree(&this->status);
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   //Get the IceStorm object
00091   Ice::ObjectPrx obj = icPtr->stringToProxy("SimEvents/TopicManager:tcp -p 11111");
00092   IceStorm::TopicManagerPrx topicManager =
00093     IceStorm::TopicManagerPrx::checkedCast(obj);
00094 
00095   //Create a VisualTracker Topic
00096   IceStorm::TopicPrx topic;
00097   try {
00098     topic = topicManager->retrieve("VisualTrackerTopic"); //check if the Retina topic exists
00099   } catch (const IceStorm::NoSuchTopic&) {
00100     topic = topicManager->create("VisualTrackerTopic"); //The retina topic does not exists, create
00101   }
00102   //Make a one way visualCortex message publisher for efficency
00103   Ice::ObjectPrx pub = topic->getPublisher()->ice_oneway();
00104   itsEventsPub = SimEvents::EventsPrx::uncheckedCast(pub);
00105 
00106   //Subscribe the SimulationViewer to theTopics
00107   itsObjectPrx = objectPrx;
00108   //subscribe  to the topics
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()); //Get the
00115       itsTopicsSubscriptions[i].topicPrx->subscribeAndGetPublisher(qos, itsObjectPrx); //Subscribe to the retina topic
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   //Unsubscribe from all the topics we are registerd to
00130   for(uint i=0; i<itsTopicsSubscriptions.size();  i++)
00131   {
00132     itsTopicsSubscriptions[i].topicPrx->unsubscribe(itsObjectPrx);
00133   }
00134 }
00135 
00136 
00137 //The VC excepts a retina image and posts a saliency map
00138 void VisualTrackerI::evolve(const SimEvents::EventMessagePtr& eMsg,
00139       const Ice::Current&)
00140 {
00141   if (eMsg->ice_isA("::SimEvents::VisualTrackerBiasMessage")){ //Set the tracker location
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; //only track one point at this time;
00150     }
00151     itsInitTargets = true; //Let the system know we want to reinit
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     //We got the first image, initalize the tracker
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()) //If we lost the track then send an empty message
00170     {
00171             //return the current track location
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   //Send an init message to indicate that we are not tracking
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; //only a single point is allowed for now
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   //Apply the track IOR
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     //flags = CV_LKFLOW_INITIAL_GUESSES;
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     //show track points
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                         //LINFO("Error %i: %f", i, track_error[i]);
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 /////////////////////////// The VC Service to init the retina and start as a deamon ///////////////
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 
Generated on Sun May 8 08:05:24 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3