test-PF.C

Go to the documentation of this file.
00001 /*!@file BayesFilters/test-PF.C test the filter*/
00002 
00003 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2003   //
00004 // by the University of Southern California (USC) and the iLab at USC.  //
00005 // See http://iLab.usc.edu for information about this project.          //
00006 // //////////////////////////////////////////////////////////////////// //
00007 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00008 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00009 // in Visual Environments, and Applications'' by Christof Koch and      //
00010 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00011 // pending; application number 09/912,225 filed July 23, 2001; see      //
00012 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00013 // //////////////////////////////////////////////////////////////////// //
00014 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00015 //                                                                      //
00016 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00017 // redistribute it and/or modify it under the terms of the GNU General  //
00018 // Public License as published by the Free Software Foundation; either  //
00019 // version 2 of the License, or (at your option) any later version.     //
00020 //                                                                      //
00021 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00022 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00023 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00024 // PURPOSE.  See the GNU General Public License for more details.       //
00025 //                                                                      //
00026 // You should have received a copy of the GNU General Public License    //
00027 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00028 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00029 // Boston, MA 02111-1307 USA.                                           //
00030 // //////////////////////////////////////////////////////////////////// //
00031 // Primary maintainer for this file: Lior Elazary <elazary@usc.edu>
00032 // $HeadURL: $
00033 // $Id: $
00034 
00035 
00036 #include "BayesFilters/ParticleFilter.H"
00037 #include "Component/ModelManager.H"
00038 #include "Raster/GenericFrame.H"
00039 #include "Image/Layout.H"
00040 #include "Image/MatrixOps.H"
00041 #include "Image/DrawOps.H"
00042 #include "GUI/DebugWin.H"
00043 #include "Util/MathFunctions.H"
00044 #include "Media/FrameSeries.H"
00045 #include "Transport/FrameInfo.H"
00046 #include "Image/Point3D.H"
00047 
00048 
00049 
00050 
00051 //Create a tracker to track a particle with a position and velocity
00052 class ParticleTracker : public ParticleFilter
00053 {
00054   public:
00055     ParticleTracker(int numStates, int numObservations, int numParticles) : 
00056       ParticleFilter(numStates, numObservations, numParticles)
00057     {
00058 
00059     }
00060 
00061    ~ParticleTracker() {}; 
00062 
00063    Image<double> getNextState(const Image<double>& X)
00064     {
00065 
00066       double processMean = -0.1;
00067       double processSigma = 0.075;
00068       double processScale = 0.4;
00069 
00070       double posX = X.getVal(0,0);
00071 
00072       processMean = processMean + ((posX - processMean)*processScale) +
00073         processSigma * gaussianRand();
00074 
00075       Image<double> Xnew(1,itsNumStates, ZEROS);
00076       Xnew[0] = processMean;
00077 
00078       return Xnew;
00079     }
00080 
00081    Image<double> getObservation(const Image<double>& X)
00082     {
00083       double posX = X.getVal(0,0);
00084 
00085       Image<double> zNew(1,itsNumObservations, ZEROS);
00086       zNew[0] = posX;
00087       return zNew;
00088     }
00089 
00090 };
00091 
00092 std::vector<int> getIntervals(int n, int polyDegree)
00093 {
00094   std::vector<int> intervals(n+polyDegree+1);
00095 
00096   for (int j=0; j<=n+polyDegree; j++)
00097   {
00098     if (j<polyDegree)
00099       intervals[j]=0;
00100     else
00101       if ((polyDegree<=j) && (j<=n))
00102         intervals[j]=j-polyDegree+1;
00103       else
00104         if (j>n)
00105           intervals[j]=n-polyDegree+2;  // if n-t=-2 then we're screwed, everything goes to 0
00106   }
00107 
00108   return intervals;
00109 
00110 }
00111 
00112 
00113 double blend(int k, int t, std::vector<int>& intervals, double v)
00114 {
00115   double value;
00116 
00117   if (t==1)            // base case for the recursion
00118   {
00119     if ((intervals[k]<=v) && (v<intervals[k+1]))
00120       value=1;
00121     else
00122       value=0;
00123   } else {
00124     if ((intervals[k+t-1]==intervals[k]) && (intervals[k+t]==intervals[k+1]))  // check for divide by zero
00125       value = 0;
00126     else
00127       if (intervals[k+t-1]==intervals[k]) // if a term's denominator is zero,use just the other
00128         value = (intervals[k+t] - v) / (intervals[k+t] - intervals[k+1]) * blend(k+1, t-1, intervals, v);
00129       else
00130         if (intervals[k+t]==intervals[k+1])
00131           value = (v - intervals[k]) / (intervals[k+t-1] - intervals[k]) * blend(k, t-1, intervals, v);
00132         else
00133           value = (v - intervals[k]) / (intervals[k+t-1] - intervals[k]) * blend(k, t-1, intervals, v) +
00134             (intervals[k+t] - v) / (intervals[k+t] - intervals[k+1]) * blend(k+1, t-1, intervals, v);
00135   }
00136 
00137   return value;
00138 
00139 
00140 
00141 }
00142 
00143 
00144 double getWeight(int k, double s)
00145 {
00146 
00147   double weight = 0;
00148 
00149   if (0 <= s && s < 1)
00150     weight = (s*s)/2;
00151   else if (1 <= s && s < 2)
00152     weight = (3/4)-((s-(3/2))*(s-(3/2)));
00153   else if (2 <= s && s < 3)
00154     weight = ((s-3)*(s-3))/2;
00155 
00156   return weight;
00157 }
00158 
00159 void drawBSpline(std::vector<Point3D<float> >& controlPoints)
00160 {
00161 
00162   int numOutput = 100; //The number of points to output
00163   int polyDegree = 3;
00164 
00165   std::vector<int> intervals = getIntervals(controlPoints.size()-1, polyDegree);
00166   double incr = 1.0/double(controlPoints.size()-1); //(double) (controlPoints.size()-1-polyDegree+2)/(numOutput-1);
00167   LINFO("Inc %f", incr);
00168 
00169   std::vector<Point3D<float> > points;
00170   double interval = 0;
00171   for(int outputIndex=0; outputIndex<numOutput; outputIndex++)
00172   {
00173     //Compute point
00174     Point3D<float> point(0,0,0);
00175     for(uint k=0; k<controlPoints.size(); k++)
00176     {
00177       double blendVal = blend(k,polyDegree, intervals, interval);
00178       //double blendVal = getWeight(k, interval-k);
00179       point.x += blendVal*controlPoints[k].x;
00180       point.y += blendVal*controlPoints[k].y;
00181       point.z += blendVal*controlPoints[k].z;
00182     }
00183 
00184     LINFO("Point %f %f", point.x, point.y);
00185     points.push_back(point);
00186     interval += incr;
00187   }
00188   //the last point is the control
00189   //points.push_back(controlPoints[0]);
00190 
00191   LINFO("Draw");
00192   Image<PixRGB<byte> > tmp(640,480,ZEROS);
00193   for(uint i=0; i<controlPoints.size(); i++)
00194   {
00195     Point2D<int> cLoc = Point2D<int>(controlPoints[i].x,controlPoints[i].y);
00196     drawCircle(tmp, cLoc, 3, PixRGB<byte>(0,255,0));
00197   }
00198 
00199   for(uint i=0; i<points.size()-10; i++)
00200   {
00201     Point2D<int> loc = Point2D<int>(points[i].x,points[i].y);
00202     Point2D<int> loc2 = Point2D<int>(points[(i+1)%points.size()].x,points[(i+1)%points.size()].y);
00203     drawLine(tmp, loc, loc2, PixRGB<byte>(255,0,0));
00204     //if (tmp.coordsOk(loc))
00205     //  tmp.setVal(loc, PixRGB<byte>(255,0,0));
00206   }
00207   SHOWIMG(tmp);
00208 
00209 
00210 }
00211 
00212 
00213 int main(int argc, char *argv[]){
00214 
00215   ModelManager manager("Test UKF");
00216 
00217   nub::ref<OutputFrameSeries> ofs(new OutputFrameSeries(manager));
00218   manager.addSubComponent(ofs);
00219 
00220   // Parse command-line:
00221   if (manager.parseCommandLine(argc, argv, "", 0, 0) == false) return(1);
00222   // let's get all our ModelComponent instances started:
00223   manager.start();
00224   ///B Spline
00225   std::vector<Point3D<float> > controlPoints;
00226   //controlPoints.push_back(Point3D<float>(10 , 100,0));
00227   //controlPoints.push_back(Point3D<float>(200, 100,0));
00228   //controlPoints.push_back(Point3D<float>(345, 300,0));
00229   //controlPoints.push_back(Point3D<float>(400, 250,0));
00230   //controlPoints.push_back(Point3D<float>(500, 550,0));
00231   //controlPoints.push_back(Point3D<float>(550, 150,0));
00232   //controlPoints.push_back(Point3D<float>(570, 50,0));
00233   //controlPoints.push_back(Point3D<float>(600, 100,0));
00234 
00235   controlPoints.push_back(Point3D<float>(50*2.75,50*5.25,0));
00236   controlPoints.push_back(Point3D<float>(50*3.28,50*7.07,0));
00237   controlPoints.push_back(Point3D<float>(50*6.61,50*7.08,0));
00238   controlPoints.push_back(Point3D<float>(50*6.85,50*5.19,0));
00239   controlPoints.push_back(Point3D<float>(50*5.29,50*4.00,0));
00240   controlPoints.push_back(Point3D<float>(50*5.67,50*1.28,0));
00241   controlPoints.push_back(Point3D<float>(50*4.12,50*1.28,0));
00242   controlPoints.push_back(Point3D<float>(50*4.33,50*4.04,0));
00243 
00244 
00245   drawBSpline(controlPoints);
00246 
00247   //Initialize tracker with 4 states and 2 observations and 1000 particles
00248   ParticleTracker pt(4,2, 1000);
00249 
00250   //Simulate a moving particle with a particuler velocity
00251   Image<PixRGB<byte> > worldImg(640,480,ZEROS);
00252 
00253   double processMean = -0.1;
00254   double processSigma =  0.4;
00255   double scaling =  0.075;
00256 
00257 
00258 
00259   for(uint t=0; t<100; t++)
00260   {
00261     double truePosition = processMean;
00262     //Move the particle
00263     processMean = processMean + ((truePosition - processMean)*scaling) +
00264       processSigma * pt.gaussianRand();
00265 
00266     pt.predictState();
00267 
00268     //Observe the state and update
00269     Image<double> z(1,1,ZEROS);
00270     z[0] = processMean + processSigma*pt.gaussianRand();
00271     pt.update(z);
00272 
00273     //Show the results
00274     //worldImg.setVal(Point2D<int>(particlePosition), PixRGB<byte>(0,255,0));
00275     //if (worldImg.coordsOk(Point2D<int>(pt.getPosition())))
00276     //  worldImg.setVal(Point2D<int>(pt.getPosition()), PixRGB<byte>(255,0,0));
00277     //Image<PixRGB<byte> > tmp = worldImg;
00278     //drawCircle(tmp, Point2D<int>(particlePosition), 3, PixRGB<byte>(0,255,0),3);
00279     //drawCircle(tmp, Point2D<int>(pt.getPosition()), 3, PixRGB<byte>(255,0,0), 3); 
00280     //ofs->writeRGB(tmp, "Particle Tracker", FrameInfo("Particle Tracker", SRC_POS));
00281     //usleep(100000);
00282     //SHOWIMG(tmp);
00283     getchar();
00284   }
00285 
00286   exit(0);
00287 
00288 }
00289 
00290 
Generated on Sun May 8 08:04:24 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3