LGN.C

Go to the documentation of this file.
00001 /*!@file SceneUnderstanding/LGN.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 <elazary@usc.edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/plugins/SceneUnderstanding/LGN.C $
00035 // $Id: LGN.C 14397 2011-01-14 20:33:47Z lior $
00036 //
00037 
00038 #ifndef LGN_C_DEFINED
00039 #define LGN_C_DEFINED
00040 
00041 #include "plugins/SceneUnderstanding/LGN.H"
00042 
00043 #include "Image/DrawOps.H"
00044 //#include "Image/OpenCVUtil.H"
00045 #include "Image/MathOps.H"
00046 #include "Image/Layout.H"
00047 #include "Simulation/SimEventQueue.H"
00048 #include "Simulation/SimEvents.H"
00049 #include "Media/MediaSimEvents.H"
00050 #include "Channels/InputFrame.H"
00051 #include "Image/Kernels.H"
00052 #include "Image/FilterOps.H"
00053 #include "Image/Convolutions.H"
00054 #include "GUI/DebugWin.H"
00055 #include <math.h>
00056 #include <fcntl.h>
00057 #include <limits>
00058 #include <string>
00059 
00060 const ModelOptionCateg MOC_LGN = {
00061   MOC_SORTPRI_3,   "LGN-Related Options" };
00062 
00063 // Used by: SimulationViewerEyeMvt
00064 const ModelOptionDef OPT_LGNShowDebug =
00065   { MODOPT_ARG(bool), "LGNShowDebug", &MOC_LGN, OPTEXP_CORE,
00066     "Show debug img",
00067     "lgn-debug", '\0', "<true|false>", "false" };
00068 
00069 
00070 //Define the inst function name
00071 SIMMODULEINSTFUNC(LGN);
00072 
00073 // ######################################################################
00074 LGN::LGN(OptionManager& mgr, const std::string& descrName,
00075     const std::string& tagName) :
00076   SimModule(mgr, descrName, tagName),
00077   SIMCALLBACK_INIT(SimEventInputFrame),
00078   SIMCALLBACK_INIT(SimEventSaveOutput),
00079   itsShowDebug(&OPT_LGNShowDebug, this),
00080   itsInitialized(false)
00081 
00082 {
00083 }
00084 
00085 // ######################################################################
00086 LGN::~LGN()
00087 {
00088 
00089 }
00090 
00091 // ######################################################################
00092 void LGN::init(Dims numCells)
00093 {
00094   Image<float> img(numCells, ZEROS);
00095   for(int i=0; i<3; i++)
00096   {
00097     itsCellsInput.push_back(img);
00098     itsCellsMu.push_back(img);
00099     img.clear(1.0);
00100     itsCellsSig.push_back(img);
00101   }
00102 
00103 
00104   //NOTE: Should the LGN cells be initalizied randomly from the
00105   //using the learned sigma?
00106   //
00107 
00108   itsInitialized = true;
00109 
00110 }
00111 
00112 // ######################################################################
00113 void LGN::onSimEventInputFrame(SimEventQueue& q,
00114                                   rutz::shared_ptr<SimEventInputFrame>& e)
00115 {
00116   // here is the inputs image:
00117   GenericFrame frame = e->frame();
00118 
00119   const Image<PixRGB<byte> > inimg = rescale(frame.asRgb(), 640, 480);
00120   itsCurrentImg = inimg;
00121 
00122   if (!itsInitialized)
00123     init(itsCurrentImg.getDims());
00124 
00125 
00126   rutz::shared_ptr<GenericFrame::MetaData> metaData;
00127   if (frame.hasMetaData(std::string("ObjectsData")))
00128     metaData = frame.getMetaData(std::string("ObjectsData"));
00129 
00130   //set the LGN input
00131   Image<float>  lum,rg,by;
00132   //getDKL(inimg, lum, rg, by);
00133   getLAB(inimg, lum, rg, by);
00134 
00135   //Normalize all values to the same level
00136   inplaceNormalize(lum, 0.0F, 255.0F);
00137   inplaceNormalize(rg, 0.0F, 255.0F);
00138   inplaceNormalize(by, 0.0F, 255.0F);
00139 
00140   Image<float> kernel = gaussian<float>(0.0F, 1.4, lum.getWidth(),1.0F);
00141   Image<float> kernel2 = gaussian<float>(0.0F, 1.5, lum.getWidth(),1.0F);
00142   Image<float> kernel3 = gaussian<float>(0.0F, 1.5, lum.getWidth(),1.0F);
00143   //// do the convolution:
00144   itsCellsInput[LUM] = sepFilter(lum, kernel, kernel, CONV_BOUNDARY_CLEAN);
00145   itsCellsInput[RG] = sepFilter(rg, kernel2, kernel2, CONV_BOUNDARY_CLEAN);
00146   itsCellsInput[BY] = sepFilter(by, kernel3, kernel3, CONV_BOUNDARY_CLEAN);
00147 
00148   itsCellsMu[LUM] = itsCellsInput[LUM];
00149   itsCellsMu[RG] = itsCellsInput[RG];
00150   itsCellsMu[BY] = itsCellsInput[BY];
00151   //evolve();
00152 
00153   //Output the cells
00154   q.post(rutz::make_shared(new SimEventLGNOutput(this, itsCellsMu, metaData)));
00155 
00156 }
00157 
00158 // ######################################################################
00159 void LGN::onSimEventSaveOutput(SimEventQueue& q, rutz::shared_ptr<SimEventSaveOutput>& e)
00160 {
00161   if (itsShowDebug.getVal())
00162     {
00163       // get the OFS to save to, assuming sinfo is of type
00164       // SimModuleSaveInfo (will throw a fatal exception otherwise):
00165       nub::ref<FrameOstream> ofs =
00166         dynamic_cast<const SimModuleSaveInfo&>(e->sinfo()).ofs;
00167       Layout<PixRGB<byte> > disp = getDebugImage();
00168       ofs->writeRgbLayout(disp, "LGN", FrameInfo("LGN", SRC_POS));
00169     }
00170 }
00171 
00172 
00173 void LGN::setBias(const ImageSet<float>& prior)
00174 {
00175 
00176 }
00177 
00178 // ######################################################################
00179 void LGN::evolve()
00180 {
00181   float R = 2; //5; //Sensor noise variance
00182   float Q=0.1;  //Prcess noise variance
00183 
00184   //getchar();
00185   for(int i=0; i<3; i++)
00186   {
00187 
00188     //Update the gagnlion cells
00189     Image<float>::const_iterator inPtr = itsCellsInput[i].begin();
00190     Image<float>::const_iterator inStop = itsCellsInput[i].end();
00191 
00192     Image<float>::iterator muPtr = itsCellsMu[i].beginw();
00193     Image<float>::iterator sigPtr = itsCellsSig[i].beginw();
00194 
00195     //Kalman filtering  for each LGN cell
00196     while(inPtr != inStop)
00197     {
00198       //Predict
00199       float mu_hat = *muPtr; // + *gangPriorPtr;
00200       float sig_hat = *sigPtr + Q;
00201 
00202       //update
00203       float K = (sig_hat)/(sig_hat + R);
00204       //*muPtr = mu_hat + K * (*inPtr - mu_hat);
00205       *muPtr =*inPtr;
00206       *sigPtr = (1-K)*sig_hat;
00207 
00208       //Calculate surprise KL(P(M|D),P(M))
00209       //P(M|D) = N(*muPtr, * sigPtr);
00210       //P(M) = N(mu_hat, sig_hat);
00211 
00212       float surprise = (((*muPtr-mu_hat)*(*muPtr-mu_hat)) + (*sigPtr * *sigPtr) + (sig_hat*sig_hat));
00213       surprise = surprise / (2*sig_hat*sig_hat);
00214       surprise += log(sig_hat / *sigPtr);
00215 
00216       //if (surprise > 0.1)
00217       //  *outPtr = *inPtr;
00218       //else
00219       //*outPtr = surprise;
00220 
00221       ++inPtr;
00222       ++muPtr;
00223       ++sigPtr;
00224     }
00225   }
00226 
00227 }
00228 
00229 Layout<PixRGB<byte> > LGN::getDebugImage()
00230 {
00231   //Display the results
00232   Image<float> lumPerc = itsCellsMu[0];
00233   Image<float> rgPerc = itsCellsMu[1];
00234   Image<float> byPerc = itsCellsMu[2];
00235 
00236   //Display result
00237   inplaceNormalize(lumPerc, 0.0F, 255.0F);
00238   inplaceNormalize(rgPerc, 0.0F, 255.0F);
00239   inplaceNormalize(byPerc, 0.0F, 255.0F);
00240   //inplaceNormalize(gangPercSig, 0.0F, 255.0F);
00241   //inplaceNormalize(gangOut, 0.0F, 255.0F);
00242 
00243   Layout<PixRGB<byte> > disp;
00244   disp = hcat(itsCurrentImg, toRGB(Image<byte>(lumPerc)));
00245   disp = hcat(disp, toRGB(Image<byte>(rgPerc)));
00246   disp = hcat(disp, toRGB(Image<byte>(byPerc)));
00247 
00248   return disp;
00249 
00250 }
00251 
00252 
00253 // ######################################################################
00254 /* So things look consistent in everyone's emacs... */
00255 /* Local Variables: */
00256 /* indent-tabs-mode: nil */
00257 /* End: */
00258 
00259 #endif
00260 
Generated on Sun May 8 08:41:09 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3