DescriptorVec.C

Go to the documentation of this file.
00001 /*!@file Channels/DescriptorVec.C descriptor vector generator for obj rec */
00002 
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: Laurent Itti <itti@usc.edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Channels/DescriptorVec.C $
00035 // $Id: DescriptorVec.C 9412 2008-03-10 23:10:15Z farhan $
00036 //
00037 
00038 #include "Channels/DescriptorVec.H"
00039 
00040 #include "Channels/ChannelOpts.H"
00041 #include "Component/ModelOptionDef.H"
00042 #include "Component/OptionManager.H"
00043 #include "Image/CutPaste.H"
00044 #include "SIFT/VisualObject.H"
00045 #include "SIFT/Keypoint.H"
00046 #include "Image/ColorOps.H"
00047 #include "Image/FilterOps.H"
00048 #include "Image/MathOps.H"
00049 #include "Image/ShapeOps.H"
00050 #include "Image/Transforms.H"
00051 #include "Image/fancynorm.H"
00052 
00053 #include "GUI/DebugWin.H"
00054 #include "Image/DrawOps.H"
00055 
00056 #include <cstdlib>
00057 #include <iostream>
00058 
00059 // Used by: Retina
00060 static const ModelOptionDef OPT_DescriptorVecFOV =
00061   { MODOPT_ARG(Dims), "DescriptorVecFOV", &MOC_CHANNEL, OPTEXP_CORE,
00062     "Use the given fovea size for constructing DescriptorVec.",
00063     "descriptor-vec-fov", '\0', "<w>x<h>", "75x75" };
00064 
00065 // ######################################################################
00066 DescriptorVec::DescriptorVec(OptionManager& mgr,
00067     const std::string& descrName,
00068     const std::string& tagName,
00069     ComplexChannel *cc)
00070 : ModelComponent(mgr, descrName, tagName),
00071   itsComplexChannel(cc), itsFoveaSize(&OPT_DescriptorVecFOV, this),
00072   itsFeatureHistogram(100),
00073   itsFEngine(0),
00074   itsFV(0)
00075 {
00076   itsFoveaSize.setVal(Dims(80,80));
00077 }
00078 
00079 // ######################################################################
00080 DescriptorVec::~DescriptorVec()
00081 {}
00082 
00083 // ######################################################################
00084 void DescriptorVec::setInputImg(const Image<PixRGB<byte> >& img)
00085 {
00086   itsInputImg = img;
00087 }
00088 
00089 // ######################################################################
00090 void DescriptorVec::setFovea(Point2D<int> loc)
00091 {
00092   int locX = loc.i;
00093   int locY = loc.j;
00094   int foveaW = itsFoveaSize.getVal().w();
00095   int foveaH = itsFoveaSize.getVal().h();
00096 
00097   LINFO("Getting descriptor from loc %i,%i", loc.i, loc.j);
00098   LINFO("Fovea size: %ix%i", foveaW, foveaH);
00099   if (itsComplexChannel->hasInput()){
00100     //get the input image
00101     Image<PixRGB<byte> > img = itsInputImg;
00102     int imgW = img.getWidth();
00103     int imgH = img.getHeight();
00104 
00105     LINFO("Image size: %ix%i", imgW, imgH);
00106 
00107     //Adjest the fovea location so we dont go outside the image
00108     int tl_x = locX - ((foveaW-1)/2);
00109     int tl_y = locY - ((foveaH-1)/2);
00110 
00111     //Sift the fovea position if nessesary
00112     if (tl_x < 0) tl_x = 0; if (tl_y < 0) tl_y = 0;
00113     if (tl_x+foveaW > imgW) tl_x = imgW - foveaW;
00114     if (tl_y+foveaH > imgH) tl_y = imgH - foveaH;
00115 
00116     //adjust locX/locX if tl_x/tl_y has changed
00117     locX = tl_x + ((foveaW-1)/2);
00118     locY = tl_y + ((foveaH-1)/2);
00119 
00120     itsFoveaLoc = Point2D<int>(locX, locY);
00121 
00122     //get only the fovea region
00123     if (itsFoveaSize.getVal().w() < img.getWidth()) //crop if our fovea is smaller then img
00124     {
00125       img= crop(img, Point2D<int>(tl_x, tl_y), itsFoveaSize.getVal());
00126     }
00127 
00128     //float angle = getDominateOrientation(luminance(img));
00129 
00130     //Rotate the image around the main angle
00131     //itsFoveaImg = rotate(img, img.getWidth()/2, img.getHeight()/2, angle);
00132     itsFoveaImg = img; //rotate(img, img.getWidth()/2, img.getHeight()/2, angle);
00133 
00134     //itsFoveaImg = toRGB(img);
00135 
00136   } else {
00137     LINFO("No input image in VC");
00138   }
00139 
00140 
00141 }
00142 
00143 // ######################################################################
00144 void DescriptorVec::setFoveaSize(Dims &d)
00145 {
00146   itsFoveaSize.setVal(d);
00147 }
00148 
00149 // ######################################################################
00150 void DescriptorVec::setFoveaSize(int foveaRadius)
00151 {
00152   Dims fr(foveaRadius, foveaRadius);
00153   itsFoveaSize.setVal(fr);
00154 }
00155 
00156 // ######################################################################
00157 Dims DescriptorVec::getFoveaSize()
00158 {
00159   return itsFoveaSize.getVal();
00160 }
00161 
00162 // ######################################################################
00163 float DescriptorVec::getDominateOrientation(const Image<float> &img){
00164   //get main orientation
00165   const int ORIENTARRAY = 36;
00166   Image<float> gradmag, gradori;
00167   gradientSobel(luminance(img), gradmag, gradori);
00168 
00169   //Add orientations to the histogram
00170   Histogram OV(ORIENTARRAY);
00171   for (int y=0; y<img.getHeight(); y++){
00172     for(int x=0; x<img.getWidth(); x++){
00173       const float gradVal = gradmag.getVal(x, y);
00174       float angle = gradori.getVal(x, y) + M_PI;
00175 
00176       angle = 0.5F * angle * ORIENTARRAY / M_PI;
00177       while (angle < 0.0F) angle += ORIENTARRAY;
00178       while (angle >= ORIENTARRAY) angle -= ORIENTARRAY;
00179 
00180       OV.addValueInterp(angle, 1 * gradVal);
00181 
00182     }
00183   }
00184 
00185   // smooth the orientation histogram 3 times:
00186   for (int i = 0; i < 3; i++) OV.smooth();
00187 
00188   // find the max in the histogram:
00189   float maxPeakVal; int maxLoc;
00190   OV.findMax(maxLoc, maxPeakVal);
00191 
00192   // get value to the left of current value
00193   const float leftval = OV.getValue((maxLoc == 0) ? ORIENTARRAY-1 : maxLoc-1);
00194 
00195   // get value to the right of current value
00196   const float rightval = OV.getValue((maxLoc == ORIENTARRAY-1) ? 0 : maxLoc+1);
00197 
00198   // interpolate the values to get the orientation of the peak:
00199   //  with f(x) = ax^2 + bx + c
00200   //   f(-1) = x0 = leftval
00201   //   f( 0) = x1 = midval
00202   //   f(+1) = x2 = rightval
00203   //  => a = (x0+x2)/2 - x1
00204   //     b = (x2-x0)/2
00205   //     c = x1
00206   // f'(x) = 0 => x = -b/2a
00207   const float a  = 0.5f * (leftval + rightval) - maxPeakVal;
00208 
00209   const float b  = 0.5f * (rightval - leftval);
00210   float realangle = float(maxLoc) - 0.5F * b / a;
00211 
00212   realangle *= 2.0F * M_PI / ORIENTARRAY; // [0:36] to [0:2pi]
00213   realangle -= M_PI;                      // [0:2pi] to [-pi:pi]
00214 
00215 
00216   /*
00217      float realangle;
00218 
00219   // Find orientation peak:
00220   for (int bin = 0; bin < ORIENTARRAY; bin++)
00221   {
00222   // consider the peak centered around 'bin':
00223   const float midval = OV.getValue(bin);
00224 
00225   // if current value much smaller than global peak, forget it:
00226   if (midval < 0.8F * maxPeakValue) continue;
00227 
00228   // get value to the left of current value
00229   const float leftval = OV.getValue((bin == 0) ? ORIENTARRAY-1 : bin-1);
00230 
00231   // get value to the right of current value
00232   const float rightval = OV.getValue((bin == ORIENTARRAY-1) ? 0 : bin+1);
00233 
00234   // only consider local peaks:
00235   if (leftval >= midval) continue;
00236   if (rightval >= midval) continue;
00237 
00238   // interpolate the values to get the orientation of the peak:
00239   //  with f(x) = ax^2 + bx + c
00240   //   f(-1) = x0 = leftval
00241   //   f( 0) = x1 = midval
00242   //   f(+1) = x2 = rightval
00243   //  => a = (x0+x2)/2 - x1
00244   //     b = (x2-x0)/2
00245   //     c = x1
00246   // f'(x) = 0 => x = -b/2a
00247   const float a  = 0.5f * (leftval + rightval) - midval;
00248 
00249   const float b  = 0.5f * (rightval - leftval);
00250   realangle = float(bin) - 0.5F * b / a;
00251 
00252   realangle *= 2.0F * M_PI / ORIENTARRAY; // [0:36] to [0:2pi]
00253   realangle -= M_PI;                      // [0:2pi] to [-pi:pi]
00254   break;
00255   }*/
00256 
00257   return realangle;
00258 
00259 }
00260 
00261 // ######################################################################
00262 //! Return the image under the fovea
00263 Image<PixRGB<byte> > DescriptorVec::getFoveaImage() {
00264 
00265 
00266   if (itsFoveaImg.initialized()){
00267     /*rutz::shared_ptr<VisualObject>
00268       obj(new VisualObject("NewObject", "NewObject", itsFoveaImg));
00269 
00270       itsFoveaImg = obj->getKeypointImage();*/
00271 
00272   } else {
00273     LINFO("No input image in VC");
00274   }
00275 
00276   return itsFoveaImg;
00277 }
00278 
00279 // ######################################################################
00280 //! Return the image of the histogram under the fovea
00281 Image<PixRGB<byte> > DescriptorVec::getHistogramImage() {
00282 
00283   //return Image<PixRGB<byte> >();
00284   return itsFoveaImg;
00285 
00286 }
00287 
00288 // ######################################################################
00289 //! Build a SIFT descriptor vector
00290 void DescriptorVec::buildSIFTDV()
00291 {
00292   rutz::shared_ptr<VisualObject>
00293     obj(new VisualObject("NewObject", "NewObject", itsFoveaImg));
00294 
00295   std::vector< rutz::shared_ptr<Keypoint> > keypoints = obj->getKeypoints();
00296 
00297   //add the keypoints to our DV
00298   for (unsigned int  i=0; i<keypoints.size(); i++)
00299   {
00300 
00301     std::vector<double> fv;
00302 
00303     for(unsigned int j=0; j<keypoints[i]->getFVlength(); j++)
00304       fv.push_back((byte)keypoints[i]->getFVelement(j));
00305     //itsFV.push_back(fv);
00306   }
00307 
00308 }
00309 
00310 void DescriptorVec::buildFftDV()
00311 {
00312 
00313   /*
00314      Image<float> gradmag, gradori;
00315   //TODO: This was already computed in DomnateOri, can be opt
00316   gradientSobel(luminance(itsFoveaImg), gradmag, gradori);
00317 
00318 
00319   //   itsFoveaImg = toRGB(Image<byte>(gradmag));
00320 
00321   if (itsFEngine == 0)
00322   itsFEngine = new FourierEngine<double>(gradmag.getDims());
00323   itsFTImg = itsFEngine->fft(gradmag);
00324 
00325   if (!itsFV.initialized()){
00326   itsFV = logmagnitude(itsFTImg);
00327   // itsFV = phase(itsFTImg);
00328   } else {
00329   //itsFV = phase(itsFTImg);
00330   itsFV = logmagnitude(itsFTImg);
00331   }
00332 
00333   //inplaceNormalize(itsFV, 0.0f, 255.0f);
00334 
00335 */
00336   /*inplaceNormalize(img, 0.0f, 99.0f);
00337     Point2D<int> p; float maxval, minval;
00338     findMax(img, p, maxval);
00339     findMin(img, p, minval);
00340     LINFO("Max %f min %f", maxval, minval);
00341     itsFeatureHistogram.clear();
00342     for (int y=0; y<img.getHeight(); y++){
00343     for(int x=0; x<img.getWidth(); x++){
00344     float val = img.getVal(x, y);
00345     printf("%0.2f ", val);
00346     itsFeatureHistogram.addValueInterp(val, 1);
00347     }
00348     }
00349     printf("\n");*/
00350 
00351   //itsFeatureHistogram((Image<byte>)img);
00352 
00353 }
00354 // ######################################################################
00355 void DescriptorVec::buildParticleCountDV()
00356 {
00357 
00358   //Count the saliency values in the fovea region
00359   ComplexChannel& cc = dynamic_cast<ComplexChannel&>(*itsComplexChannel->subChan(0));
00360 
00361   const LevelSpec lspec = itsComplexChannel->getModelParamVal<LevelSpec>("LevelSpec");
00362   const int smlevel = lspec.mapLevel();
00363   int x=int(itsFoveaLoc.i / double(1 << smlevel) + 0.49);
00364   int y=int(itsFoveaLoc.j / double(1 << smlevel) + 0.49);
00365 
00366   itsFV.clear();
00367   int FVi = 0;
00368   for (uint i = 0; i < cc.numChans(); i++)
00369   {
00370     nub::ref<ChannelBase> cb = cc.subChan(i);
00371     if (dynamic_cast<ComplexChannel*>(cb.get()) != 0) //we have a complex channel
00372     {
00373       LINFO("Complex channel %i %s", i, cb->descriptiveName().c_str());
00374     } else {
00375       SingleChannel& sc = dynamic_cast<SingleChannel&>(*cb);
00376       LINFO("Single channel %i", i);
00377       for (uint j=0; j< sc.numSubmaps(); j++)
00378       {
00379         Image<float> submap = sc.getSubmap(j);
00380 
00381         itsFV.push_back(submap.getVal(x, y));
00382         LINFO("FV%i %s:%i", FVi++, sc.descriptiveName().c_str(), j);
00383         /*submap = crop(submap, //get only the fovea region
00384           Point2D<int>(itsFoveaLoc.i - ((itsFoveaSize.getVal().w()-1)/2),
00385           itsFoveaLoc.j - ((itsFoveaSize.getVal().h())-1)/2),
00386           itsFoveaSize.getVal());*/
00387 
00388 
00389         /*submap = maxNormalize(submap, 0.0F, 10.0F, VCXNORM_MAXNORM);
00390           Point2D<int> p; float maxVal, minVal, midVal;
00391           findMax(submap, p, maxVal);
00392           findMin(submap, p, minVal);
00393           midVal = (maxVal-minVal)/2;
00394 
00395           int nParticles = countThresh(submap, midVal); //countParticles(submap, 1.0F);
00396 
00397           LINFO("Channel %s:%i max is %0.2f min is %0.2f mid %0.2f, p=%i",
00398           sc.descriptiveName().c_str(),j, maxVal, minVal, midVal,
00399           nParticles);
00400           printf("%i ", nParticles);
00401         //SHOWIMG(submap);  */
00402       }
00403 
00404     }
00405   }
00406 }
00407 
00408 // ######################################################################
00409 void DescriptorVec::buildDV()
00410 {
00411   const LevelSpec lspec = itsComplexChannel->getModelParamVal<LevelSpec>("LevelSpec");
00412   const int smlevel = lspec.mapLevel();
00413 
00414   int x=int(itsFoveaLoc.i / double(1 << smlevel) + 0.49);
00415   int y=int(itsFoveaLoc.j / double(1 << smlevel) + 0.49);
00416 
00417   int foveaW = int(itsFoveaSize.getVal().w() / double(1 << smlevel) + 0.49);
00418   int foveaH = int(itsFoveaSize.getVal().h() / double(1 << smlevel) + 0.49);
00419 
00420   //Adjest the fovea location so we dont go outside the image
00421   int tl_x = x - (foveaW/2);
00422   int tl_y = y - (foveaH/2);
00423 
00424 
00425   //Go through all the submaps building the DV
00426   itsFV.clear(); //clear the FV
00427   uint numSubmaps = itsComplexChannel->numSubmaps();
00428   for (uint i = 0; i < numSubmaps; i++)
00429   {
00430     Image<float> submap = itsComplexChannel->getSubmap(i);
00431     //Image<float> submap = itsComplexChannel->getRawCSmap(i);
00432 
00433 
00434     //itsFV.push_back(submap.getVal(x,y));
00435 
00436     //get only the fovea region
00437     if (foveaW < submap.getWidth()) //crop if our fovea is smaller
00438       submap = crop(submap, Point2D<int>(tl_x, tl_y), Dims(foveaW, foveaH));
00439     //submap = maxNormalize(submap, 0.0F, 10.0F, VCXNORM_MAXNORM);
00440 
00441 
00442 
00443     /*   Point2D<int> p; float maxVal, minVal, midVal;
00444          findMax(submap, p, maxVal);
00445          findMin(submap, p, minVal);
00446          midVal = (maxVal-minVal)/2;
00447          int nParticles = countThresh(submap, 1.0F); //countParticles(submap, 1.0F);
00448          itsFV.push_back(nParticles); */
00449 
00450     float maxVal; Point2D<int> maxLoc;
00451     findMax(submap, maxLoc, maxVal);
00452 
00453     //SHOWIMG(rescale(submap, 255, 255));
00454 
00455     itsFV.push_back(maxVal);
00456 
00457   }
00458 }
00459 
00460 // ######################################################################
00461 void DescriptorVec::buildRawDV()
00462 {
00463 
00464   bool salientLocationWithinSubmaps = true;
00465   Point2D<int> objSalientLoc(-1,-1);  //the feature location
00466 
00467   const LevelSpec lspec = itsComplexChannel->getModelParamVal<LevelSpec>("LevelSpec");
00468   const int smlevel = lspec.mapLevel();
00469 
00470   int x=int(itsFoveaLoc.i / double(1 << smlevel) + 0.49);
00471   int y=int(itsFoveaLoc.j / double(1 << smlevel) + 0.49);
00472 
00473   int foveaW = int(itsFoveaSize.getVal().w() / double(1 << smlevel) + 0.49);
00474   int foveaH = int(itsFoveaSize.getVal().h() / double(1 << smlevel) + 0.49);
00475 
00476   int tl_x = x - (foveaW/2);
00477   int tl_y = y - (foveaH/2);
00478 
00479   Dims mapDims = itsComplexChannel->getSubmap(0).getDims();
00480 
00481   //Shift the fovea location so we dont go outside the image
00482   //Sift the fovea position if nessesary
00483   if (tl_x < 0) tl_x = 0; if (tl_y < 0) tl_y = 0;
00484   if (tl_x+foveaW > mapDims.w()) tl_x = mapDims.w() - foveaW;
00485   if (tl_y+foveaH > mapDims.h()) tl_y = mapDims.h() - foveaH;
00486 
00487   if (!salientLocationWithinSubmaps)
00488   {
00489     //Find the most salient location within the fovea
00490     Image<float> SMap = itsComplexChannel->getOutput();
00491 
00492     Image<float> tmp = SMap; //TODO need to resize to fovea
00493     //Find the max location within the fovea
00494 
00495     float maxVal; Point2D<int> maxLoc;
00496     findMax(tmp, maxLoc, maxVal);
00497     //convert back to original SMap cordinates
00498    // objSalientLoc.i=tl_x+maxLoc.i;
00499    // objSalientLoc.j=tl_y+maxLoc.j;
00500     objSalientLoc.i=x;
00501     objSalientLoc.j=y;
00502     itsAttentionLoc = objSalientLoc;
00503   }
00504 
00505   //Go through all the submaps building the DV
00506   itsFV.clear(); //clear the FV
00507   uint numSubmaps = itsComplexChannel->numSubmaps();
00508   for (uint i = 0; i < numSubmaps; i++)
00509   {
00510     //Image<float> submap = itsComplexChannel->getSubmap(i);
00511     Image<float> submap = itsComplexChannel->getRawCSmap(i);
00512 
00513     // resize submap to fixed scale if necessary:
00514     if (submap.getWidth() > mapDims.w())
00515       submap = downSize(submap, mapDims);
00516     else if (submap.getWidth() < mapDims.w())
00517       submap = rescale(submap, mapDims); //TODO convert to  quickInterpolate
00518 
00519 
00520     if (salientLocationWithinSubmaps) //get the location from the salient location within each submap
00521     {
00522       Image<float> tmp = submap;
00523       //get only the fovea region
00524 
00525       if (foveaW < tmp.getWidth()) //crop if our fovea is smaller
00526         tmp = crop(tmp, Point2D<int>(tl_x, tl_y), Dims(foveaW, foveaH));
00527      // tmp = maxNormalize(tmp, 0.0F, 10.0F, VCXNORM_MAXNORM);  //find salient locations
00528 
00529       //Find the max location within the fovea
00530       float maxVal; Point2D<int> maxLoc; findMax(tmp, maxLoc, maxVal);
00531       //LINFO("%i: Max val %f, loc(%i,%i)", i, maxVal, maxLoc.i, maxLoc.j);
00532 
00533       objSalientLoc.i=tl_x+maxLoc.i;
00534       objSalientLoc.j=tl_y+maxLoc.j;
00535 
00536     }
00537 
00538     if (objSalientLoc.i < 0) objSalientLoc.i = 0;
00539     if (objSalientLoc.j < 0) objSalientLoc.j = 0;
00540 
00541     if (objSalientLoc.i > submap.getWidth()-1) objSalientLoc.i = submap.getWidth()-1;
00542     if (objSalientLoc.j > submap.getHeight()-1) objSalientLoc.j = submap.getHeight()-1;
00543 
00544 
00545 
00546    // LINFO("Location from %i,%i: (%i,%i)", objSalientLoc.i, objSalientLoc.j,
00547     //    submap.getWidth(), submap.getHeight());
00548     float featureVal = submap.getVal(objSalientLoc.i,objSalientLoc.j);
00549     itsFV.push_back(featureVal);
00550  //   SHOWIMG(rescale(submap, 255, 255));
00551 
00552   }
00553 }
00554 
00555 // ######################################################################
00556 void DescriptorVec::buildLocalDV()
00557 {
00558 
00559   Point2D<int> objSalientLoc(-1,-1);  //the feature location
00560 
00561 
00562   //Go through all the submaps building the DV
00563   itsFV.clear(); //clear the FV
00564   uint numSubmaps = itsComplexChannel->numSubmaps();
00565   for (uint i = 0; i < numSubmaps; i++)
00566   {
00567     //Image<float> submap = itsComplexChannel->getSubmap(i);
00568     Image<float> submap = itsComplexChannel->getRawCSmap(i);
00569 
00570     //Find the max location within the fovea
00571     float maxVal; Point2D<int> maxLoc; findMax(submap, maxLoc, maxVal);
00572     //SHOWIMG(submap);
00573 
00574     float featureVal = submap.getVal(maxLoc.i,maxLoc.j);
00575     itsFV.push_back(featureVal);
00576  //   SHOWIMG(rescale(submap, 255, 255));
00577 
00578   }
00579 }
00580 // ######################################################################
00581 void DescriptorVec::buildSingleChannelFV(SingleChannel &sc)
00582 {
00583   const LevelSpec lspec = itsComplexChannel->getModelParamVal<LevelSpec>("LevelSpec");
00584   const int smlevel = lspec.mapLevel();
00585   int x=int(itsFoveaLoc.i / double(1 << smlevel) + 0.49);
00586   int y=int(itsFoveaLoc.j / double(1 << smlevel) + 0.49);
00587 
00588   //LINFO("Single channel %s", sc.descriptiveName().c_str());
00589   for (uint j=0; j< sc.numSubmaps(); j++)
00590   {
00591     Image<float> submap = sc.getSubmap(j);
00592     itsFV.push_back(submap.getVal(x, y));
00593   }
00594 
00595 }
00596 
00597 uint DescriptorVec::getFVSize()
00598 {
00599   ASSERT(itsComplexChannel != NULL);
00600   return itsComplexChannel->numSubmaps();
00601 }
00602 
00603 // ######################################################################
00604 const std::vector<double>& DescriptorVec::getFV() const
00605 {
00606   return itsFV;
00607 }
00608 
00609 // ######################################################################
00610 /* So things look consistent in everyone's emacs... */
00611 /* Local Variables: */
00612 /* indent-tabs-mode: nil */
00613 /* End: */
Generated on Sun May 8 08:04:34 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3