SpatioTemporalEnergy.C

Go to the documentation of this file.
00001 /*!@file Robots/Beobot2/Navigation/FOE_Navigation/SpatioTemporalEnergy.C 
00002   detect motion in an image stream   */
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the //
00005 // 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: Christian Siagian <siagian@usc.edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Robots/Beobot2/Navigation/FOE_Navigation/SpatioTemporalEnergy.C  $
00035 // $Id: $
00036 //
00037 
00038 #include "Robots/Beobot2/Navigation/FOE_Navigation/SpatioTemporalEnergy.H"
00039 
00040 // ######################################################################
00041 // ##### SpatioTemporalEnergyPyrBuilder Functions:
00042 // ######################################################################
00043 
00044 //debuging
00045 //#define DEBUG_SpatioTemporalEnergy
00046 
00047 #ifdef DEBUG_SpatioTemporalEnergy
00048 #include "GUI/DebugWin.H"
00049 #endif
00050 
00051 #include "Raster/Raster.H"
00052 #include "Image/CutPaste.H"
00053 #include "Image/ShapeOps.H"
00054 #include "Image/Kernels.H"
00055 
00056 // ######################################################################
00057 template <class T>
00058 SpatioTemporalEnergyPyrBuilder<T>::SpatioTemporalEnergyPyrBuilder
00059 (const PyramidType typ,
00060  const float gabor_theta,
00061  const float speed,
00062  const uint depth,
00063  const int timeDomainSize) :
00064   PyrBuilder<T>(),
00065   itsPtype(typ),
00066   itsDepth(depth),
00067   itsGaborAngle(gabor_theta),
00068   itsSpeed(speed),
00069   itsTimeDomainSize(timeDomainSize)
00070 {
00071   ASSERT(itsTimeDomainSize == 3 || itsTimeDomainSize == 5);
00072 
00073   setSpatioTemporalFilters();
00074   itsSpatioTemporalEnergyOptimalShift.reset(depth);
00075 }
00076 
00077 // ######################################################################
00078 template <class T>
00079 void SpatioTemporalEnergyPyrBuilder<T>::setSpatioTemporalFilters()
00080 {
00081   float angle = 90.0; //  NOTE: MAKE THIS 0.0 for the Aperture Problem solution
00082   float filter_period = 2.5; //3.75;
00083   float elongation = 1.0;  
00084   uint size = 5;
00085 
00086   double major_stddev = filter_period / 3.0;
00087   double minor_stddev = major_stddev * elongation;
00088 
00089   itsSpatTemp0filter  = gaborFilter3(major_stddev, minor_stddev,
00090                                      filter_period, 0.0f, angle, size);
00091   itsSpatTemp90filter = gaborFilter3(major_stddev, minor_stddev,
00092                                      filter_period, 90.0f, angle, size);
00093 
00094   LDEBUG("angle = %.2f, period = %.2f pix, size = %dx%d pix",
00095         angle, filter_period, 
00096         itsSpatTemp0filter.getWidth(), itsSpatTemp0filter.getHeight());
00097 
00098   
00099 //   if(itsGaborAngle == 0.0)
00100 //     {
00101 //       for(uint y = 0; y < size; y++)
00102 //         {
00103 //           for(uint x = 0; x < size; x++)           
00104 //             LINFO("%7.3f ", itsSpatTemp0filter.getVal(x,y));//*-128 + 127);
00105 //           LINFO("\n");
00106 //         }
00107 //       LINFO("\n");
00108    
00109 //       for(uint y = 0; y < size; y++)
00110 //         {
00111 //           for(uint x = 0; x < size; x++)           
00112 //             LINFO("%7.3f ", itsSpatTemp90filter.getVal(x,y));//*128 + 127);
00113 //           LINFO("\n");
00114 //         }
00115 //       LINFO("\n");   
00116 //       if(itsWin.is_invalid())
00117 //         {
00118 //           std::string ntext(sformat("t=%5.2f", itsGaborAngle));
00119 //           itsWin.reset(new XWinManaged(Dims(300,300), 0,0, ntext.c_str()));
00120 //         }
00121 //       else itsWin->setDims(Dims(300, 300));
00122 
00123 //       float mn1,mx1,mn2,mx2;
00124 //       getMinMax(itsSpatTemp0filter, mn1, mx1);
00125 //       LDEBUG("g0  min: %f, max: %f", mn1, mx1);
00126 //       getMinMax(itsSpatTemp90filter, mn2, mx2);
00127 //       LDEBUG("g90 min: %f, max: %f", mn2, mx2);
00128       
00129 //       Image<float> disp0 (300,300,ZEROS);
00130 //       Image<float> disp90(300,300,ZEROS);
00131 
00132 //       disp0  = (disp0 +1.0)*mx1;
00133 //       disp90 = (disp90+1.0)*mx2;
00134 //       for(int i = 0; i < 5; i++)
00135 //         {
00136 //           std::string ntexth(sformat("%d", i-2));
00137 //           writeText(disp0,  Point2D<int>(70+40*i-10,25), ntexth.c_str(),mn1,mx1);
00138 //           writeText(disp90, Point2D<int>(70+40*i-10,25), ntexth.c_str(),mn2,mx2);
00139 //         }
00140 //       std::string ntexthl(sformat("dx"));
00141 //       writeText(disp0,  Point2D<int>(250,25), ntexthl.c_str(),mn1,mx1);
00142 //       writeText(disp90, Point2D<int>(250,25), ntexthl.c_str(),mn2,mx2);
00143 
00144 //       for(int i = 0; i < 5; i++)
00145 //         {
00146 //           std::string ntextv(sformat("%d", i));
00147 //           writeText(disp0,  Point2D<int>(25, 70+40*i-10), ntextv.c_str(),mn1,mx1);
00148 //           writeText(disp90, Point2D<int>(25, 70+40*i-10), ntextv.c_str(),mn2,mx2);
00149 //         }
00150 //       std::string ntextvl(sformat("dt"));
00151 //       writeText(disp0,  Point2D<int>(25,250), ntextvl.c_str(),mn1,mx1);
00152 //       writeText(disp90, Point2D<int>(25,250), ntextvl.c_str(),mn2,mx2);
00153 
00154 //       inplacePaste(disp0,  zoomXY(itsSpatTemp0filter , 40), Point2D<int>(50,50));
00155 //       inplacePaste(disp90, zoomXY(itsSpatTemp90filter , 40), Point2D<int>(50,50));
00156 //       inplaceNormalize(disp0,  0.0F, 255.0F);
00157 //       inplaceNormalize(disp90, 0.0F, 255.0F);
00158 //       Raster::WriteRGB(disp0, "disp0.ppm");
00159 //       Raster::WriteRGB(disp90,"disp90.ppm");
00160 //       //itsWin->drawImage(disp0, 0,0); Raster::waitForKey();
00161 //       //itsWin->drawImage(disp90,0,0); Raster::waitForKey();
00162 
00163 
00164 //       PixRGB<byte> bl(0,  0,  0);
00165 //       PixRGB<byte> wh(255,255,255);
00166 //       uint wST = 100 + 19*40;
00167 //       uint hST = 100 + 11*40;
00168 //       Image<PixRGB<byte> > dispST(wST, hST,ZEROS);
00169 //       dispST = (dispST+ wh);
00170 //       std::string ntexth(sformat("dt"));
00171       
00172 //       // 1px/fr
00173 //       uint ri = 50 + 40 * 7; uint rj = 50 + 40*9; 
00174 //       drawFilledRect
00175 //         (dispST, Rectangle::tlbrI(rj, ri, rj+40-1, ri+40-1), PixRGB<byte>(255,  0,  0));
00176 //       ri = 50 + 40 * 8; rj = 50 + 40*8; 
00177 //       drawFilledRect
00178 //         (dispST, Rectangle::tlbrI(rj, ri, rj+40-1, ri+40-1), PixRGB<byte>(255,  0,  0));
00179 //       ri = 50 + 40 * 10; rj = 50 + 40*6; 
00180 //       drawFilledRect
00181 //         (dispST, Rectangle::tlbrI(rj, ri, rj+40-1, ri+40-1), PixRGB<byte>(255,  0,  0));
00182 //       ri = 50 + 40 * 11; rj = 50 + 40*5; 
00183 //       drawFilledRect
00184 //         (dispST, Rectangle::tlbrI(rj, ri, rj+40-1, ri+40-1), PixRGB<byte>(255,  0,  0));
00185 
00186 //       //2 px/fr
00187 //       ri = 50 + 40 * 7; rj = 50 + 40*8; 
00188 //       drawFilledRect
00189 //         (dispST, Rectangle::tlbrI(rj, ri, rj+40-1, ri+40-1), PixRGB<byte>(0,  255,  0));
00190 //       ri = 50 + 40 * 5; rj = 50 + 40*9; 
00191 //       drawFilledRect
00192 //         (dispST, Rectangle::tlbrI(rj, ri, rj+40-1, ri+40-1), PixRGB<byte>(0,  255,  0));
00193 //       ri = 50 + 40 * 11; rj = 50 + 40*6; 
00194 //       drawFilledRect
00195 //         (dispST, Rectangle::tlbrI(rj, ri, rj+40-1, ri+40-1), PixRGB<byte>(0,  255,  0));
00196 //       ri = 50 + 40 * 13; rj = 50 + 40*5; 
00197 //       drawFilledRect
00198 //         (dispST, Rectangle::tlbrI(rj, ri, rj+40-1, ri+40-1), PixRGB<byte>(0,  255,  0));
00199 
00200 //       // 4px/fr
00201 //       ri = 50 + 40 * 5; rj = 50 + 40*8; 
00202 //       drawFilledRect
00203 //         (dispST, Rectangle::tlbrI(rj, ri, rj+40-1, ri+40-1), PixRGB<byte>(0,  0,   255));
00204 //       ri = 50 + 40 * 1; rj = 50 + 40*9; 
00205 //       drawFilledRect
00206 //         (dispST, Rectangle::tlbrI(rj, ri, rj+40-1, ri+40-1), PixRGB<byte>(0,  0,   255));
00207 //       ri = 50 + 40 * 13; rj = 50 + 40*6; 
00208 //       drawFilledRect
00209 //         (dispST, Rectangle::tlbrI(rj, ri, rj+40-1, ri+40-1), PixRGB<byte>(0,  0,   255));
00210 //       ri = 50 + 40 * 17; rj = 50 + 40*5; 
00211 //       drawFilledRect
00212 //         (dispST, Rectangle::tlbrI(rj, ri, rj+40-1, ri+40-1), PixRGB<byte>(0,  0,   255));
00213 
00214 //       // 1/2 px/fr
00215 //       ri = 50 + 40 * 11; rj = 50 + 40*1; 
00216 //       drawFilledRect
00217 //         (dispST, Rectangle::tlbrI(rj, ri, rj+40-1, ri+40-1), PixRGB<byte>(255, 255,  0));
00218 //       ri = 50 + 40 * 10; rj = 50 + 40*3; 
00219 //       drawFilledRect
00220 //         (dispST, Rectangle::tlbrI(rj, ri, rj+40-1, ri+40-1), PixRGB<byte>(255, 255,  0));
00221 //       ri = 50 + 40 * 9; rj = 50 + 40*5; 
00222 //       drawFilledRect
00223 //         (dispST, Rectangle::tlbrI(rj, ri, rj+40-1, ri+40-1), PixRGB<byte>(255, 255,  0));
00224 //       ri = 50 + 40 * 8; rj = 50 + 40*7; 
00225 //       drawFilledRect
00226 //         (dispST, Rectangle::tlbrI(rj, ri, rj+40-1, ri+40-1), PixRGB<byte>(255, 255,  0));
00227 //       ri = 50 + 40 * 7; rj = 50 + 40*9; 
00228 //       drawFilledRect
00229 //         (dispST, Rectangle::tlbrI(rj, ri, rj+40-1, ri+40-1), PixRGB<byte>(255, 255,  0));
00230 
00231 //       // 1/4 px/fr
00232 // //       ri = 50 + 40 * 11; rj = 50 + 40*1; 
00233 // //       drawFilledRect
00234 // //         (dispST, Rectangle::tlbrI(rj, ri, rj+40-1, ri+40-1), PixRGB<byte>(255, 255,  0));
00235 // //       ri = 50 + 40 * 10; rj = 50 + 40*3; 
00236 // //       drawFilledRect
00237 // //         (dispST, Rectangle::tlbrI(rj, ri, rj+40-1, ri+40-1), PixRGB<byte>(255, 255,  0));
00238 //       ri = 50 + 40 * 9; rj = 50 + 40*1; 
00239 //       drawFilledRect
00240 //         (dispST, Rectangle::tlbrI(rj, ri, rj+40-1, ri+40-1), PixRGB<byte>(255, 0,  255));
00241 //       ri = 50 + 40 * 8; rj = 50 + 40*5; 
00242 //       drawFilledRect
00243 //         (dispST, Rectangle::tlbrI(rj, ri, rj+40-1, ri+40-1), PixRGB<byte>(255, 0, 255));
00244 //       ri = 50 + 40 * 7; rj = 50 + 40*9; 
00245 //       drawFilledRect
00246 //         (dispST, Rectangle::tlbrI(rj, ri, rj+40-1, ri+40-1), PixRGB<byte>(255, 0, 255));
00247 
00248 
00249 
00250 
00251 //       uint ri1 = 50 + 40 * 7 +20; uint rj1 = 50 + 40*9+20; 
00252 //       uint ri2 = 50 + 40 * 11+20; uint rj2 = 50 + 40*5+20; 
00253 //       drawLine(dispST, Point2D<int>(ri1, rj1), Point2D<int>(ri2, rj2), bl);      
00254 //       ri = 50 + 40 * 9; rj = 50 + 40*7; 
00255 //       drawLine(dispST, Point2D<int>(ri, rj), Point2D<int>(ri+40, rj+40), bl);
00256 //       drawLine(dispST, Point2D<int>(ri, rj+40), Point2D<int>(ri+40, rj), bl);      
00257 //       ri1 = 50 + 40 * 5 +20; rj1 = 50 + 40*9+20; 
00258 //       ri2 = 50 + 40 * 13+20; rj2 = 50 + 40*5+20; 
00259 //       drawLine(dispST, Point2D<int>(ri1, rj1), Point2D<int>(ri2, rj2), bl);
00260 //       ri1 = 50 + 40 * 1 +20; rj1 = 50 + 40*9+20; 
00261 //       ri2 = 50 + 40 * 17+20; rj2 = 50 + 40*5+20; 
00262 //       drawLine(dispST, Point2D<int>(ri1, rj1), Point2D<int>(ri2, rj2), bl);
00263 //       ri1 = 50 + 40 * 11 +20; rj1 = 50 + 40*1 +20; 
00264 //       ri2 = 50 + 40 * 7  +20; rj2 = 50 + 40*9 +20; 
00265 //       drawLine(dispST, Point2D<int>(ri1, rj1), Point2D<int>(ri2, rj2), bl);
00266 //       ri1 = 50 + 40 * 11 +20; rj1 = 50 + 40*-7 +20; 
00267 //       ri2 = 50 + 40 * 7  +20; rj2 = 50 + 40*9 +20; 
00268 //       drawLine(dispST, Point2D<int>(ri1, rj1), Point2D<int>(ri2, rj2), bl);
00269 
00270 
00271 
00272 //       writeText(dispST,  Point2D<int>(25, 25), ntexth.c_str(), bl, wh);
00273 //       for(int i = 0; i < 20; i++)
00274 //         {
00275 //           drawLine(dispST, 
00276 //                    Point2D<int>(50+i*40, 50), 
00277 //                    Point2D<int>(50+i*40, 50+10*40), bl);
00278 //           std::string ntext(sformat("%2d", i-8));
00279 //           if(i != 19) 
00280 //             writeText(dispST,  Point2D<int>(70+40*i-10, 50+10*40+5), ntext.c_str(), bl, wh);
00281 //         }
00282 
00283 //       std::string ntextv(sformat("dx"));
00284 //       writeText(dispST,  Point2D<int>(70+40*19-10, 50+10*40+5), ntextv.c_str(), bl, wh);
00285 //       for(int j = 0; j < 11; j++)
00286 //         {
00287 //           drawLine(dispST, 
00288 //                    Point2D<int>(50,      50+j*40), 
00289 //                    Point2D<int>(50+19*40,50+j*40), bl);
00290 
00291 //           std::string ntext(sformat("%2d", j-9));
00292 //           if(j != 10) 
00293 //             writeText(dispST,  Point2D<int>(25, 70+40*j-10), ntext.c_str(), bl, wh);
00294 //         }
00295 
00296 //       //inplaceNormalize(dispST,  0.0F, 255.0F);
00297 //       Raster::WriteRGB(dispST, "ST.ppm");
00298 //       itsWin->setDims(Dims(wST, hST));
00299 //       //itsWin->drawImage(dispST,0,0); Raster::waitForKey();
00300 
00301 
00302 //       uint wRF = 100 + 28*20;
00303 //       uint hRF = 100 + 28*20;
00304 //       Image<PixRGB<byte> > dispRF (wRF,hRF,ZEROS);
00305 //       dispRF  = (dispRF + PixRGB<byte>(255,255,255));
00306 
00307 //       ri = 50 + 20 * 2*4; rj = 50 + 20*2*4; 
00308 //       drawFilledRect
00309 //         (dispRF, Rectangle::tlbrI(rj, ri, rj+240-1, ri+240-1), PixRGB<byte>(255, 255, 0));
00310 //       ri = 50 + 20 * 3*4; rj = 50 + 20*3*4; 
00311 //       drawFilledRect
00312 //         (dispRF, Rectangle::tlbrI(rj, ri, rj+80-1, ri+80-1), PixRGB<byte>(255, 0, 0));
00313 
00314 
00315 //       for(int i = 0; i < 29; i++)
00316 //         {
00317 //           drawLine(dispRF, 
00318 //                    Point2D<int>(50+i*20, 50), 
00319 //                    Point2D<int>(50+i*20, 50+28*20), bl, 1);
00320 //         }
00321 
00322 //       for(int j = 0; j < 29; j++)
00323 //         {
00324 //           drawLine(dispRF, 
00325 //                    Point2D<int>(50,      50+j*20), 
00326 //                    Point2D<int>(50+28*20,50+j*20), bl, 1);
00327 //         }
00328 
00329 //       for(int i = 0; i < 29; i+=2)
00330 //         {
00331 //           drawLine(dispRF, 
00332 //                    Point2D<int>(50+i*20, 50), 
00333 //                    Point2D<int>(50+i*20, 50+28*20), bl, 2);
00334 //         }
00335 
00336 //       for(int j = 0; j < 29; j+=2)
00337 //         {
00338 //           drawLine(dispRF, 
00339 //                    Point2D<int>(50,      50+j*20), 
00340 //                    Point2D<int>(50+28*20,50+j*20), bl, 2);
00341 //         }
00342 
00343 //       for(int i = 0; i < 29; i+=4)
00344 //         {
00345 //           drawLine(dispRF, 
00346 //                    Point2D<int>(50+i*20, 50), 
00347 //                    Point2D<int>(50+i*20, 50+28*20), bl, 3);
00348 //         }
00349 
00350 //       for(int j = 0; j < 29; j+=4)
00351 //         {
00352 //           drawLine(dispRF, 
00353 //                    Point2D<int>(50,      50+j*20), 
00354 //                    Point2D<int>(50+28*20,50+j*20), bl, 3);
00355 //         }
00356 
00357 //       Raster::WriteRGB(dispRF,"RF.ppm");
00358 //       itsWin->setDims(Dims(wRF, hRF));
00359 //       itsWin->drawImage(dispRF,0,0); Raster::waitForKey();
00360 //     }  
00361 
00362   // old filters with size increase detection
00363   itsSpatTemp2filter = Image<float>(5,5,NO_INIT);
00364   itsSpatTemp2filter.setVal(0,0, 0.01);
00365   itsSpatTemp2filter.setVal(0,1, 0.05);
00366   itsSpatTemp2filter.setVal(0,2, 0.40);
00367   itsSpatTemp2filter.setVal(0,3, 0.05);
00368   itsSpatTemp2filter.setVal(0,4, 0.01);
00369 
00370   itsSpatTemp2filter.setVal(1,0, 0.01);
00371   itsSpatTemp2filter.setVal(1,1, 0.10);
00372   itsSpatTemp2filter.setVal(1,2, 0.40);
00373   itsSpatTemp2filter.setVal(1,3, 0.10);
00374   itsSpatTemp2filter.setVal(1,4, 0.01);
00375   
00376   itsSpatTemp2filter.setVal(2,0, 0.03);
00377   itsSpatTemp2filter.setVal(2,1, 0.20);
00378   itsSpatTemp2filter.setVal(2,2, 0.40);
00379   itsSpatTemp2filter.setVal(2,3, 0.20);
00380   itsSpatTemp2filter.setVal(2,4, 0.03);
00381 
00382   itsSpatTemp2filter.setVal(3,0, 0.05);
00383   itsSpatTemp2filter.setVal(3,1, 0.25);
00384   itsSpatTemp2filter.setVal(3,2, 0.40);
00385   itsSpatTemp2filter.setVal(3,3, 0.25);
00386   itsSpatTemp2filter.setVal(3,4, 0.05);
00387 
00388   itsSpatTemp2filter.setVal(4,0, 0.10);
00389   itsSpatTemp2filter.setVal(4,1, 0.30);
00390   itsSpatTemp2filter.setVal(4,2, 0.40);
00391   itsSpatTemp2filter.setVal(4,3, 0.30);
00392   itsSpatTemp2filter.setVal(4,4, 0.10);
00393 }
00394 
00395 // ######################################################################
00396 template <class T>
00397 ImageSet<float> SpatioTemporalEnergyPyrBuilder<T>::getOptimalShift()
00398 {
00399   return itsSpatioTemporalEnergyOptimalShift;
00400 }
00401 // ######################################################################
00402 template <class T>
00403 ImageSet<float> SpatioTemporalEnergyPyrBuilder<T>::getSpatioTemporalEnergy()
00404 {
00405   return itsSpatioTemporalEnergy;
00406 }
00407 
00408 // ######################################################################
00409 template <class T>
00410 ImageSet<T> SpatioTemporalEnergyPyrBuilder<T>::build
00411 (const Image<T>& image,
00412  const int firstlevel,
00413  const int depth,
00414  PyramidCache<T>* cache)
00415 {
00416   // WAS: Gaussian5
00417 //   itsMotionPyrs.reset
00418 //     (new SpatioTemporalEnergyPyrBuilder<byte>(Oriented5, 0.0f, 10.0f, itsPyrLevel));
00419   
00420   // create a pyramid with the input image
00421   //ImageSet<T> pyr = buildPyrGeneric(image, 0, itsDepth, Gaussian5,
00422   //                                  itsGaborAngle);
00423 
00424   //ImageSet<float> pyr =
00425   //  buildPyrGabor(image, 0, itsDepth, itsGaborAngle+90.0, 3.75, 1.0, 7);
00426 
00427   ImageSet<float> pyr =
00428     buildPyrGabor(image, 0, itsDepth, itsGaborAngle+90.0, 2.50, 1.0, 5);
00429 
00430   //DEBUG
00431   //print(pyr, si, ei, sj, ej, false);
00432   //display(pyr);
00433 
00434   imgPyrQ.push_back(pyr); //build the time domain
00435 
00436   if (imgPyrQ.size() > itsTimeDomainSize)        //limit the image time queue
00437     imgPyrQ.pop_front();
00438 
00439   // if we have too few imgs in the Q, just return an empty image:
00440   if (imgPyrQ.size() < itsTimeDomainSize)
00441     {
00442       LDEBUG("not enough images yet: %"ZU, imgPyrQ.size());
00443       return ImageSet<float>();
00444     }
00445 
00446   const int pdepth = imgPyrQ[0].size();
00447   ImageSet<float> result(pdepth);
00448 
00449   // compute the motion detection at each location
00450   for (int scale = 0; scale < pdepth; scale++)
00451     result[scale] = buildMotion(scale);
00452 
00453   itsSpatioTemporalEnergy = result;
00454 
00455   return result;
00456 }
00457 
00458 // // ######################################################################
00459 // // get the motion by detecting edge orientations in the space and time
00460 // template <class T>
00461 // Image<float> SpatioTemporalEnergyPyrBuilder<T>::buildMotion(int scale)
00462 // {
00463 //   // if we have too few imgs in the Q, just return an empty image:
00464 //   uint currQueueSize = imgPyrQ.size();
00465 
00466 //   // go through each spatial shift 
00467 //   bool motionComputed = false;
00468 //   std::vector<Image<float> > results;
00469 //   std::vector<float> shifts;
00470 
00471 //   //LINFO("num of spatial shifts: %d", itsSpatialShift);
00472 
00473 //   for(uint i = 0; i < itsSpatialShift; i++)
00474 //     {
00475 //       uint neededSize = itsTimeDomainSize;
00476 //       if (neededSize > currQueueSize)
00477 //         {
00478 //           LINFO("Not enough images: %d < %d for spatial shift %d", 
00479 //                 currQueueSize, neededSize, i);
00480 //         }
00481 //       else
00482 //         {
00483 //           uint sshift = uint(pow(2.0, i));
00484 //           results.push_back(buildMotion(scale, sshift, 1));
00485 //           shifts.push_back(float(sshift*pow(2.0, scale)));
00486 //           motionComputed = true;
00487 //         }
00488 //     }
00489 
00490 //   // FIX: NOTES maybe nested loop later on these two
00491 //   // go through each temporal shift
00492 //   for(uint j = 0; j < itsTemporalShift; j++)
00493 //     {
00494 //       //uint            neededSize =  9; // speed: 1/2 pix/fr
00495 //       //if(j == 1)      neededSize = 13; // speed: 1/3 pix/fr
00496 //       //else if(j == 2) neededSize = 17; // speed: 1/4 pix/fr
00497 //       uint neededSize = 1 + 4*(j+2);
00498 
00499 //       if (neededSize > currQueueSize)
00500 //         {
00501 //           LINFO("Not enough images: %d < %d for temporal shift %d", 
00502 //                 currQueueSize, neededSize, j);
00503 //         }
00504 //       else
00505 //         {
00506 //           float sshift = 1.0/(j+2.0);
00507 //           results.push_back(buildMotion(scale, 1, j+1));
00508 //           shifts.push_back(sshift*pow(2.0, scale));
00509 //           motionComputed = true;
00510 //         }
00511 //     }
00512 
00513 //   // find max among all the spatial and temporal shifts
00514 //   // --> basically max among all the shifting values
00515 //   if(motionComputed)
00516 //     {
00517 //       uint width  = results[0].getWidth();
00518 //       uint height = results[0].getHeight();
00519 //       Image<float> result(width, height, ZEROS);
00520 
00521 //       itsSpatioTemporalEnergyOptimalShift[scale] = 
00522 //         Image<float>(width, height, ZEROS);
00523 
00524 //       typename Image<float>::iterator 
00525 //         resultT = result.beginw();
00526 
00527 //       typename Image<float>::iterator 
00528 //         shiftT = itsSpatioTemporalEnergyOptimalShift[scale].beginw(); 
00529 
00530 //       typename Image<float>::iterator resT[results.size()];
00531 //       for (unsigned int i=0; i < results.size(); i++)
00532 //           resT[i] = results[i].beginw();
00533 
00534 //       for(uint i = 0; i < width; i++)
00535 //         {
00536 //           for(uint j = 0; j < height; j++)
00537 //             {
00538 //               float max = 0.0; float optShift = 0.0;
00539 //               uint size = results.size();
00540 
00541 //               for(uint r = 0; r < size; r++)
00542 //                 {
00543 //                   float val = *resT[r]++; 
00544 //                   if(max < val) 
00545 //                     {
00546 //                       max = val;
00547 //                       optShift = shifts[r];
00548 //                     }
00549 //                 }
00550 //               *resultT++ = max;
00551 //               *shiftT++  = optShift;
00552 //             }
00553 //         }
00554 
00555 // //       if((scale == 1))
00556 // //         {
00557 // //           uint div = uint(pow(2.0,scale));
00558 // //           LINFO("COMB: Ang: %f sc: %d", itsGaborAngle, scale);      
00559 // //           print(result, 166/div, 196/div, 55/div, 75/div, false);
00560 // //         }
00561 
00562 
00563 //       return result;
00564 //     }
00565 //   else
00566 //     return Image<float>();
00567 // }
00568 
00569 // ######################################################################
00570 template <class T>
00571 Image<float> SpatioTemporalEnergyPyrBuilder<T>::buildMotion(int scale)
00572 {
00573   int width  = imgPyrQ[0][scale].getWidth();
00574   int height = imgPyrQ[0][scale].getHeight();
00575 
00576   // build the time domain pointers
00577   /*typename Image<float>::iterator imgT[itsTimeDomainSize];
00578   for (unsigned int i=0; i < itsTimeDomainSize; i++)
00579     {
00580       imgT[i] = imgPyrQ[i][scale].beginw();
00581     }*/
00582 
00583   // to make the operation look nice and readable
00584   // the parenthesis around the x are needed
00585   // otherwise a bug happens when using PixH(0,i-1)
00586 #define Pix(t,x,y) (*(imgT[t] + (y*width)+(x)))
00587 
00588   float cosAng = cos(itsGaborAngle * M_PI/180.0); 
00589   float sinAng = sin(itsGaborAngle * M_PI/180.0); 
00590 
00591 //   LINFO("Bef  %f %f ss:%d ts:%d scale: %d ang: %f", 
00592 //         cosAng,sinAng, spatialShift, temporalShift, scale, itsGaborAngle);
00593 
00594 //   if(cosAng >  .1 && cosAng <  0.9) cosAng =  1.0F;
00595 //   if(sinAng >  .1 && sinAng <  0.9) sinAng =  1.0F;
00596 //   if(cosAng < -.1 && cosAng > -0.9) cosAng = -1.0F;
00597 //   if(sinAng < -.1 && sinAng > -0.9) sinAng = -1.0F;
00598 
00599   // NOTE: FIX THIS UNFORTUNATE SITUATION
00600   // find the limit on the XY plane of the spatiotemporal space
00601   uint dx = 2*itsSpeed + 2; // 2; //uint(spatialShift * cosAng * (itsTimeDomainSize/2));
00602   uint dy = 2*itsSpeed + 2; // 2; //uint(spatialShift * sinAng * (itsTimeDomainSize/2));
00603 //   LINFO("%f c,s(%10.3f, %10.3f) dx: %7d, dy: %7d", 
00604 //         itsGaborAngle, cosAng, sinAng, dx, dy);
00605 
00606   Image<float> motion(width, height, ZEROS); // motion place holder
00607 
00608   // go through all the active area
00609   for (uint j = dy; j < (height-dy); j++)
00610     {
00611       typename Image<float>::iterator mot = 
00612         motion.beginw() + (j*width) + dx;
00613         
00614       for (uint i = dx; i < (width-dx); i++)
00615         {
00616           //LINFO("[%d %d]",i ,j, );
00617 
00618           // calculate the firing for displacement & size increase
00619           // based on timedomainsize
00620           switch(itsTimeDomainSize)
00621             {
00622               // calculate values from 3 most recent frames 
00623             case 3: // do something simpler later
00624               break;
00625               
00626               // 5 values from 5 most recent frames 
00627             case 5:
00628               {
00629                 uint speed  = 1;
00630                 uint tshift = 1;
00631                 if(itsSpeed >= 1.0) speed = uint(itsSpeed);
00632                 else
00633                   {
00634                     // FIXXX: add cases for 1/2, 1/3, 1/4
00635                   }
00636 
00637                 float val = 
00638                   getSpatioTemporalVal
00639                   (cosAng, sinAng, scale, i, j, speed, tshift);
00640                 //motion.setVal(i,j,val);
00641                 *mot = val; mot++; // saves 3ms compared to setVal
00642               }
00643               break;
00644 
00645             default: LFATAL("invalid itsTimeDomainSize: %d", itsTimeDomainSize);
00646               break;
00647             }
00648         }
00649     }
00650 
00651   // DEBUG
00652   //  uint div = uint(pow(2.0, scale));
00653 //   if((itsGaborAngle == 0.0 || itsGaborAngle == 180.0) &&
00654 //      (scale == 0) && (spatialShift == 1) && (temporalShift == 1))
00655 //     {
00656 //   if((scale == 0))// && (spatialShift == 1) && (temporalShift == 1))
00657 //     {
00658 //       LINFO("Ang: %f sc: %d, ss: %d ts: %d", 
00659 //             itsGaborAngle, scale, spatialShift, temporalShift);      
00660 //       print(motion, 158, 169, 55, 75, false);
00661 //     }
00662   //print(motion, 165/div, 175/div, 45/div, 75/div, true);
00663   //print(motion, 175/div, 185/div, 45/div, 75/div, true);
00664   //print(motion, 185/div, 195/div, 45/div, 75/div, true);
00665 
00666   return motion;
00667 }
00668 
00669 // ######################################################################
00670 template <class T> 
00671 float SpatioTemporalEnergyPyrBuilder<T>::getSpatioTemporalVal
00672 (float cosAng, float sinAng, uint scale, uint i, uint j,
00673  uint spatialShift, uint temporalShift)
00674 {
00675   
00676   typename Image<float>::iterator f0 =
00677     itsSpatTemp0filter.beginw();
00678   typename Image<float>::iterator f90 =
00679     itsSpatTemp90filter.beginw();
00680 
00681 //   typename Image<float>::iterator f2 =
00682 //     itsSpatTemp2filter.beginw();
00683 
00684   // to make the operation look nice and readable
00685   // the parenthesis around the x are needed
00686   // otherwise a bug happens when using PixH(0,i-1)
00687 #define v0(x,y)  (*(f0  + (y*itsTimeDomainSize)+(x)))
00688 #define v90(x,y) (*(f90 + (y*itsTimeDomainSize)+(x)))
00689   //#define v2(x,y)  (*(f2  + (y*itsTimeDomainSize)+(x)))
00690 
00691   float tsum0 = 0.0; float tsum90 = 0.0;
00692   std::vector<float> sum0(5);
00693   std::vector<float> sum90(5);
00694 
00695   std::vector<float> spatShift(5);
00696   spatShift[0] = -2.0 * spatialShift;
00697   spatShift[1] = -1.0 * spatialShift;
00698   spatShift[2] =  0.0;
00699   spatShift[3] =  1.0 * spatialShift;
00700   spatShift[4] =  2.0 * spatialShift;
00701 
00702   // check temporal shifting  
00703   uint tempLimit = 1 + temporalShift*(itsTimeDomainSize-1); 
00704   uint ft = 0; 
00705   for(uint t = 0; t < tempLimit; t+= temporalShift)
00706     {      
00707       sum0[t]  = getFilterResponseVal
00708         (spatShift[ft], cosAng, sinAng, t, scale,
00709          i, j, v0(ft,0), v0(ft,1), v0(ft,2), v0(ft,3), v0(ft,4));
00710       
00711       sum90[t] = getFilterResponseVal
00712         (spatShift[ft], cosAng, sinAng, t, scale,
00713          i, j, v90(ft,0), v90(ft,1), v90(ft,2), v90(ft,3), v90(ft,4));
00714 
00715       tsum0  += sum0[t];
00716       tsum90 += sum90[t];
00717 //       sum[t] = getSpatTempVal
00718 //         (shift[t], cosAng, sinAng, t, scale,
00719 //          i, j, v2(t,0), v2(t,1), v2(t,2), v2(t,3), v2(t,4));      
00720 
00721 //        LINFO("s: %f (%f %f) t:%d s:%d [%d %d] %f %f %f %f %f", 
00722 //              shift[t], cosAng, sinAng, t, scale,
00723 //              i, j, v2(t,0), v2(t,1), v2(t,2), v2(t,3), v2(t,4));    
00724 
00725       //sum2 += sum[t];
00726 
00727 //       LINFO("%10.3f %10.3f %10.3f %10.3f %10.3f ", 
00728 //             v0(ft,0), v0(ft,1), v0(ft,2), v0(ft,3), v0(ft,4));
00729 
00730       ft++;
00731     }
00732 
00733   float sum = tsum0*tsum0 + tsum90*tsum90;
00734   
00735 //   // grab values from frame t - 4
00736 //   float v0 = getSpatTempVal
00737 //     (-2.0, cosAng, sinAng, 0, scale,
00738 //      i, j, 0.01, 0.05, 0.40, 0.05, 0.01);
00739 
00740 //   // grab values from frame t - 3
00741 //   float v1 = getSpatTempVal
00742 //     (-1.0, cosAng, sinAng, 1, scale,
00743 //      i, j, 0.01, 0.10, 0.40, 0.10, 0.01);
00744 
00745 //   // grab values from frame t - 2
00746 //   float v2 = getSpatTempVal
00747 //     (0.0, cosAng, sinAng, 2, scale,
00748 //      i, j, 0.03, 0.20, 0.40, 0.20, 0.03);
00749 
00750 //   // grab values from frame t - 1
00751 //   float v3 = getSpatTempVal
00752 //     (1.0, cosAng, sinAng, 3, scale,
00753 //      i, j, 0.05, 0.25, 0.40, 0.25, 0.05);
00754 
00755 //   // grab values from frame t 
00756 //   float v4 = getSpatTempVal
00757 //     (2.0, cosAng, sinAng, 4, scale,
00758 //      i, j, 0.10, 0.30, 0.40, 0.30, 0.10);
00759 
00760 //   if(i > 150 && i < 170 && j ==60)
00761 //     {
00762 //       LINFO(" 0(%d %d) %10.3f,%10.3f,%10.3f,%10.3f,%10.3f = %10.3f", 
00763 //             i, j, sum0[0], sum0[1], sum0[2], sum0[3], sum0[4], tsum0);
00764 //       LINFO("90(%d %d) %10.3f,%10.3f,%10.3f,%10.3f,%10.3f = %10.3f", 
00765 //             i, j, sum90[0], sum90[1], sum90[2], sum90[3], sum90[4], tsum90);
00766 
00767 //       LINFO("%f^2 + %f^2  = %f + %f = %f ", 
00768 //             tsum0, tsum90, tsum0*tsum0, tsum90*tsum90, sum);
00769 //       //LINFO("(%d %d) %10.3f,%10.3f,%10.3f,%10.3f,%10.3f = %10.3f", 
00770 //       //      i, j, v0, v1, v2, v3, v4, v0+v1+v2+v3+v4);
00771 //     }  
00772   
00773   //   return  v0 + v1 + v2 + v3 + v4;
00774   return  sum;
00775 }
00776 
00777 // ######################################################################
00778 template <class T> 
00779 float SpatioTemporalEnergyPyrBuilder<T>::getFilterResponseVal
00780 (float dshift, float cosAng, float sinAng, uint time, uint scale,
00781  uint i, uint j,
00782  float wm2, float wm1, float w, float wp1, float wp2)
00783 {
00784 
00785   uint width = imgPyrQ[time][scale].getWidth();
00786 
00787   // to make the operation look nice and readable
00788   // the parenthesis around the x are needed
00789   // otherwise a bug happens when using Px(0,i-1)
00790   //#define Px(t,x,y) (*(imgT[t] + ((y)*width)+(x))
00791 #define Px(x,y) (*(imgT + ((y)*width)+(x)))
00792 
00793   // build the time domain pointers
00794 //   typename Image<float>::iterator imgT[itsTimeDomainSize];
00795 //   for (unsigned int ind = 0; ind < itsTimeDomainSize; ind++)
00796 //     {
00797 //       imgT[ind] = imgPyrQ[ind][scale].beginw();
00798 //     }
00799 
00800   typename Image<float>::iterator imgT = imgPyrQ[time][scale].beginw();
00801 
00802   float ii = i + (dshift * cosAng);
00803   float jj = j + (dshift * sinAng);
00804 
00805   float pi = cosAng;  // old: sinAng
00806   float pj = sinAng;  // old: cosAng
00807 
00808 //   float iim2 = ii - 2*pi;
00809 //   float jjm2 = jj - 2*pj;
00810 
00811 //   float iim1 = ii - pi;
00812 //   float jjm1 = jj - pj;
00813 
00814 //   float iip1 = ii + pi;
00815 //   float jjp1 = jj + pj;
00816 
00817 //   float iip2 = ii + 2*pi;
00818 //   float jjp2 = jj + 2*pj;
00819 
00820 //   float v1 = wm2 * Px(time, int(iim2),int(jjm2));
00821 //   float v2 = wm1 * Px(time, int(iim1),int(jjm1));
00822 //   float v3 = w   * Px(time, int(ii),  int(jj)  );
00823 //   float v4 = wp1 * Px(time, int(iip1),int(jjp1));
00824 //   float v5 = wp2 * Px(time, int(iip2),int(jjp2));
00825 
00826   float v1 = wm2 * Px(int(ii - 2*pi),int(jj - 2*pj));
00827   float v2 = wm1 * Px(int(ii - pi),  int(jj - pj));
00828   float v3 = w   * Px(int(ii),       int(jj)  );
00829   float v4 = wp1 * Px(int(ii + pi),  int(jj + pj));
00830   float v5 = wp2 * Px(int(ii + 2*pi),int(jj + 2*pj));
00831 
00832   float val  = v1 + v2 + v3 + v4 + v5;
00833 
00834 //    if(i > 158 && i < 170 && j ==60 && scale == 0 && 
00835 //       pi != 0.0 && pj != 0.0)
00836 //    {
00837 //      LINFO("[%d] i,  j:  %d %d", time, i,  j);
00838 //      LINFO("ii, jj: %f %f", ii, jj);
00839 //      LINFO("pi, pj: %f %f", pi, pj);
00840 
00841 // //     LINFO("%d %d: %f x",           int(iim2),int(jjm2), wm2);
00842 // //     LINFO("%d %d: %f x",           int(iim1),int(jjm1), wm1);
00843 // //     LINFO("%d %d: %f x",           int(ii),  int(jj), w);
00844 // //     LINFO("%d %d: %f x",           int(iip1),int(jjp1), wp1);
00845 // //     LINFO("%d %d: %f x",           int(iip2),int(jjp2), wp2);
00846 
00847 //     LINFO("%d %d: %f x %f", int(iim2),int(jjm2), Px(int(iim2),int(jjm2)), wm2);
00848 //     LINFO("%d %d: %f x %f", int(iim1),int(jjm1), Px(int(iim1),int(jjm1)), wm1);
00849 //     LINFO("%d %d: %f x %f", int(ii),  int(jj),   Px(int(ii),  int(jj)  ), w);
00850 //     LINFO("%d %d: %f x %f", int(iip1),int(jjp1), Px(int(iip1),int(jjp1)), wp1);
00851 //     LINFO("%d %d: %f x %f", int(iip2),int(jjp2), Px(int(iip2),int(jjp2)), wp2);
00852 
00853 //     LINFO("%f %f %f %f %f = %f", v1, v2, v3, v4, v5, val);
00854 //    }
00855 
00856   return val;
00857   
00858 }
00859 
00860 // ######################################################################
00861 template <class T>
00862 float SpatioTemporalEnergyPyrBuilder<T>::DrawVectors
00863 (Image<T> &img, Image<float> &motion)
00864 {
00865   //TODO: should check the mag is the same size as dir
00866 
00867   Image<float>::const_iterator mag_ptr = motion.begin();
00868   Image<float>::const_iterator mag_stop = motion.end();
00869 
00870   int inx=0;
00871   int avg_i = 0;
00872   double avg_angle = 0;
00873 
00874   while (mag_ptr != mag_stop)
00875     {
00876       int y = inx/motion.getWidth();
00877       int x = inx - (y*motion.getWidth());
00878 
00879       if (*mag_ptr != 0) {
00880         avg_i++;
00881         //avg_angle += (*mag_ptr+M_PI/2);
00882         avg_angle += (*mag_ptr);
00883 
00884         int scale_x = x * (img.getWidth()/motion.getWidth());
00885         int scale_y = y * (img.getHeight()/motion.getHeight());
00886         drawLine(img, Point2D<int>(scale_x,scale_y),
00887                  Point2D<int>((int)(scale_x+25*cos((*mag_ptr))),
00888                          (int)(scale_y-25*sin((*mag_ptr)))),
00889                  (T)0);
00890       }
00891       mag_ptr++;
00892       inx++;
00893     }
00894 
00895   if (avg_i > 0){
00896     int xi = img.getWidth()/2;
00897     int yi = img.getHeight()/2;
00898 
00899     drawLine(img,Point2D<int>(xi, yi),
00900              Point2D<int>((int)(xi+75*cos(avg_angle/avg_i)),
00901                      (int)(yi-75*sin(avg_angle/avg_i))),
00902              (T)0, 3);
00903     return avg_angle/avg_i;
00904   }
00905 
00906   return -999;
00907 }
00908 
00909 // ######################################################################
00910 template <class T>
00911 SpatioTemporalEnergyPyrBuilder<T>* SpatioTemporalEnergyPyrBuilder<T>::clone() const
00912 { return new SpatioTemporalEnergyPyrBuilder<T>(*this); }
00913 
00914 // ######################################################################
00915 template <class T>
00916 void SpatioTemporalEnergyPyrBuilder<T>::reset()
00917 {
00918   // imgPyrQ.clear();
00919 }
00920 
00921 // ######################################################################
00922 template <class T>
00923 void SpatioTemporalEnergyPyrBuilder<T>::print
00924 (Image<float> image, uint si, uint ei, uint sj, uint ej, float stop)
00925 {
00926   for(uint j = sj; j <= ej; j++)
00927     {
00928       for(uint i = si; i <= ei; i++)           
00929         //if(image.getVal(i,j) > 0.0) 
00930           //LINFO("[%3d %3d]: %10.3f", i,j,  image.getVal(i,j));
00931           LINFO("%9.3f ", image.getVal(i,j));
00932       LINFO("\n");
00933     }
00934   LINFO("\n");
00935   if(stop) Raster::waitForKey();
00936 }
00937 
00938 // ######################################################################
00939 template <class T>
00940 void SpatioTemporalEnergyPyrBuilder<T>::print
00941 (ImageSet<float> images, uint si, uint ei, uint sj, uint ej, float stop)
00942 {
00943   for(uint k = 0; k < images.size(); k++)
00944     {
00945       LINFO("level: %d", k);
00946       uint div = uint(pow(2.0,k));
00947       for(uint j = sj/div; j <= ej/div; j++)
00948         {
00949           for(uint i = si/div; i <= ei/div; i++)           
00950             //if(image.getVal(i,j) > 0.0) 
00951             //LINFO("[%3d %3d]: %10.3f", i,j,  image.getVal(i,j));
00952             LINFO("%9.3f ", images[k].getVal(i,j));
00953           LINFO("\n");
00954         }
00955       LINFO("\n");
00956     }
00957 
00958   if(stop) Raster::waitForKey();
00959 }
00960 
00961 
00962 // ######################################################################
00963 // template <class T>
00964 // void SpatioTemporalEnergyPyrBuilder<T>::print
00965 //(Image<float> image, std::vector<uint> si, std::vector<uint> ei, 
00966 // std::vector<uint> sj, std::vector<uint> ej, std::vector<uint> levels, float stop)
00967 // {
00968 //   for (uint i = 0; i < itsDepth; i++)
00969 //     {
00970 //       if(i == 0)
00971 //         { 
00972 //           LINFO("level 0");
00973 //           for(uint y = 35; y < 85; y++)
00974 //             {
00975 //               for(uint x = 155; x < 168; x++)           
00976 //                 LINFO("%7.3f ",pyr[i].getVal(x,y));
00977 //                 //LINFO("%3d ",pyr[i].getVal(x,y));
00978 //               LINFO("\n");
00979 //             }
00980 //           LINFO("\n");
00981 //         }
00982 
00983 //       if(i == 1)
00984 //         {
00985 //           LINFO("level 1");
00986 //           for(uint y = 10; y < 50; y++)
00987 //             {
00988 //               for(uint x = 75; x < 88; x++)           
00989 //                 LINFO("%7.3f ",pyr[i].getVal(x,y));
00990 //                 //LINFO("%3d ",pyr[i].getVal(x,y));
00991 //               LINFO("\n");
00992 //             }
00993 //           LINFO("\n");
00994 //         }
00995 
00996 //       if(i == 2)
00997 //         {
00998 //           LINFO("level 2");
00999 //           for(uint y = 5; y < 25; y++)
01000 //             {
01001 //               for(uint x = 35; x < 48; x++)           
01002 //                 LINFO("%7.3f ",pyr[i].getVal(x,y));
01003 //                 //LINFO("%3d ",pyr[i].getVal(x,y));
01004 //               LINFO("\n");
01005 //             }
01006 //           LINFO("\n");
01007 //         }
01008 
01009 //       if(i == 3)
01010 //         {
01011 //           LINFO("level 3");
01012 //           for(uint y = 0; y < 20; y++)
01013 //             {
01014 //               for(uint x = 13; x < 27; x++)           
01015 //                 LINFO("%7.3f ",pyr[i].getVal(x,y));
01016 //                 //LINFO("%3d ",pyr[i].getVal(x,y));
01017 //               LINFO("\n");
01018 //             }
01019 //           LINFO("\n");
01020 //         }
01021 
01022 //       if(i == 4)
01023 //         {
01024 //           LINFO("level 4");
01025 //           for(uint y = 0; y < 15; y++)
01026 //             {
01027 //               for(uint x = 5; x < 18; x++)           
01028 //                 LINFO("%7.3f ",pyr[i].getVal(x,y));
01029 //               //LINFO("%3d ",pyr[i].getVal(x,y));
01030 //               LINFO("\n");
01031 //             }
01032 //           LINFO("\n");
01033 //         }
01034 //   }
01035 //}
01036 
01037 // ######################################################################
01038 template <class T>
01039 void SpatioTemporalEnergyPyrBuilder<T>::display(Image<float> image)
01040 {
01041   uint w = image.getWidth();
01042   uint h = image.getHeight();
01043 
01044   if(itsWin.is_invalid())
01045     {
01046       std::string ntext(sformat("t=%5.2f", itsGaborAngle));
01047       itsWin.reset(new XWinManaged(Dims(w,h), 0,0, ntext.c_str()));
01048     }
01049 
01050   itsWin->setDims(Dims(w, h));
01051   LINFO("Dims: (%d,%d)", w, h);
01052 
01053   float mn,mx; getMinMax(image, mn,mx);
01054   LINFO("min: %f, max: %f", mn, mx);
01055   itsWin->drawImage(image,0,0); 
01056   Raster::waitForKey();
01057 }
01058 
01059 // ######################################################################
01060 template <class T>
01061 void SpatioTemporalEnergyPyrBuilder<T>::display(ImageSet<float> images)
01062 {
01063   uint w         = images[0].getWidth();
01064   uint h         = images[0].getHeight();
01065 
01066   if(itsWin.is_invalid())
01067     {
01068       std::string ntext(sformat("t=%5.2f", itsGaborAngle));
01069       itsWin.reset(new XWinManaged(Dims(w,h), 0,0, ntext.c_str()));
01070     }
01071 
01072   uint numLevels = images.size();
01073   itsWin->setDims(Dims(w, h));
01074   Image<float> disp(w, h, ZEROS);
01075   LINFO("Depth: %d Dim(%d,%d)", numLevels, w, h);  
01076   for (uint i = 0; i < numLevels; i++)
01077     {
01078       uint scale = pow(2.0, i);
01079 
01080       if(w >= uint(images[i].getWidth()  * scale) && 
01081          h >= uint(images[i].getHeight() * scale) )
01082         {
01083           Image<float> temp = images[i];
01084           float mn,mx; getMinMax(images[i], mn,mx);
01085           LINFO("min: %f, max: %f", mn, mx);
01086 
01087           inplaceNormalize(temp, 0.0F, 255.0F);
01088           inplacePaste(disp, zoomXY(temp, scale) , Point2D<int>(0,  0));
01089           itsWin->drawImage(disp,0,0); Raster::waitForKey();
01090         }
01091       else{ LINFO("Too big. Not drawn."); }
01092     }
01093 }
01094 
01095 
01096 template class SpatioTemporalEnergyPyrBuilder<byte>;
01097 template class SpatioTemporalEnergyPyrBuilder<float>;
01098 
01099 // ######################################################################
01100 /* So things look consistent in everyone's emacs... */
01101 /* Local Variables: */
01102 /* indent-tabs-mode: nil */
01103 /* End: */
Generated on Sun May 8 08:41:18 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3