GaborPatch.C

Go to the documentation of this file.
00001 /** @file Psycho/GaborPatch.C represent the physical parameters of a gabor patch */
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: Rob Peters <rjpeters at usc dot edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Psycho/GaborPatch.C $
00035 // $Id: GaborPatch.C 9078 2007-12-11 21:11:45Z rjpeters $
00036 //
00037 
00038 // Code herein is derived from GroovX, also licensed under the GPL
00039 // Copyright (c) 2002-2004 California Institute of Technology
00040 // Copyright (c) 2004-2007 University of Southern California
00041 // [http://ilab.usc.edu/rjpeters/groovx/]
00042 
00043 #ifndef PSYCHO_GABORPATCH_C_DEFINED
00044 #define PSYCHO_GABORPATCH_C_DEFINED
00045 
00046 #include "Psycho/GaborPatch.H"
00047 #include "Image/geom.h"
00048 
00049 #include <map>
00050 
00051 namespace
00052 {
00053   typedef std::map<GaborSpec, GaborPatch*> MapType;
00054   MapType theMap;
00055 
00056   const int NUM_THETA = 64;
00057   const int NUM_PHASE = 8;
00058   const double DELTA_THETA = M_PI / NUM_THETA;
00059   const double DELTA_PHASE = 2 * M_PI / NUM_PHASE;
00060 }
00061 
00062 GaborSpec::GaborSpec(double s, double o, double t, double p) :
00063   theta(DELTA_THETA * (int(geom::rad_0_pi(t)/DELTA_THETA + 0.5) % NUM_THETA)),
00064   phi(DELTA_PHASE * (int(geom::rad_0_2pi(p)/DELTA_PHASE + 0.5) % NUM_PHASE)),
00065   sigma(s),
00066   omega(o)
00067 {}
00068 
00069 bool GaborSpec::operator<(const GaborSpec& x) const
00070 {
00071   if (theta < x.theta) return true;
00072   else if (theta == x.theta)
00073     {
00074       if (phi < x.phi) return true;
00075       else if (phi == x.phi)
00076         {
00077           if (sigma < x.sigma) return true;
00078           else if (sigma == x.sigma)
00079             {
00080               return (omega < x.omega);
00081             }
00082         }
00083     }
00084 
00085   return false;
00086 }
00087 
00088 GaborPatch::GaborPatch(const GaborSpec& spec)
00089   :
00090   itsSpec      ( spec ),
00091   itsSize      ( int(8*spec.sigma + 0.5) ),
00092   itsCenter    ( itsSize/2.0 + 0.5 ),
00093   itsCosTheta  ( cos(spec.theta) ),
00094   itsSinTheta  ( sin(spec.theta) ),
00095   itsSigmaSqr  ( 2.0* spec.sigma * spec.sigma ),
00096   itsData      ( itsSize, itsSize, ZEROS )
00097 {
00098   Image<double>::iterator ptr = itsData.beginw();
00099 
00100   for (int y = 0; y < itsSize; ++y)
00101     for (int x = 0; x < itsSize; ++x)
00102       {
00103         const double fy = y - itsCenter;
00104         const double fx = x - itsCenter;
00105 
00106         const double dx = itsCosTheta * fx - itsSinTheta * fy;
00107         const double dy = itsSinTheta * fx + itsCosTheta * fy;
00108 
00109         const double dsqr  = (dx*dx + dy*dy) / itsSigmaSqr;
00110 
00111         const double sinus = cos(itsSpec.omega * dx + itsSpec.phi);
00112 
00113         const double gauss = exp(-dsqr);
00114         *ptr++ = sinus * gauss;
00115       }
00116 }
00117 
00118 GaborPatch::~GaborPatch()
00119 {}
00120 
00121 const GaborPatch& GaborPatch::lookup(const GaborSpec& spec)
00122 {
00123   GaborPatch*& patch = theMap[spec];
00124 
00125   if (patch == 0)
00126     patch = new GaborPatch(spec);
00127 
00128   return *patch;
00129 }
00130 
00131 const GaborPatch& GaborPatch::lookup(double sigma, double omega,
00132                                      double theta, double phi)
00133 {
00134   GaborSpec spec(sigma, omega, theta, phi);
00135 
00136   return lookup(spec);
00137 }
00138 
00139 GaborPatchItem::GaborPatchItem()
00140 {}
00141 
00142 GaborPatchItem::~GaborPatchItem()
00143 {}
00144 
00145 Image<double> GaborPatchItem::getPatch() const
00146 {
00147   const GaborPatch& p =
00148     GaborPatch::lookup(itsSigma, 2*M_PI/itsPeriod,
00149                        this->theta, this->phi);
00150 
00151   return p.image(this->contrast);
00152 }
00153 
00154 GaborPatchItemFactory::GaborPatchItemFactory(int thetaSeed,
00155                                              int phaseSeed,
00156                                              int contrastSeed,
00157                                              double period, double sigma)
00158   :
00159   itsThetaRand(thetaSeed),
00160   itsPhaseRand(phaseSeed),
00161   itsContrastRand(contrastSeed),
00162   itsThetaJitter(0.0),
00163   itsContrastJitter(0.0),
00164   itsPeriod(period),
00165   itsSigma(sigma)
00166 {
00167 }
00168 
00169 GaborPatchItemFactory::~GaborPatchItemFactory()
00170 {}
00171 
00172 rutz::shared_ptr<SearchItem>
00173 GaborPatchItemFactory::make(const geom::vec2d& pos)
00174 {
00175   rutz::shared_ptr<GaborPatchItem> el(new GaborPatchItem);
00176 
00177   el->type = SearchItem::BACKGROUND;
00178   el->pos = pos;
00179 
00180   el->phi = 2 * M_PI * itsPhaseRand.fdraw();
00181   el->theta = 2 * M_PI * itsThetaRand.fdraw();
00182   el->contrast = exp(-itsContrastJitter * itsContrastRand.fdraw());
00183 
00184   el->itsPeriod = this->itsPeriod;
00185   el->itsSigma = this->itsSigma;
00186 
00187   return el;
00188 }
00189 
00190 rutz::shared_ptr<GaborPatchItem>
00191 GaborPatchItemFactory::makeForeground(const geom::vec2d& pos,
00192                                               const double theta)
00193 {
00194   rutz::shared_ptr<GaborPatchItem> el(new GaborPatchItem);
00195 
00196   el->type = SearchItem::FOREGROUND;
00197   el->pos = pos;
00198 
00199   el->phi = 2 * M_PI * itsPhaseRand.fdraw();
00200   const double rand_theta = 2*M_PI * itsThetaRand.fdraw();
00201   el->theta =
00202     geom::rad_0_2pi(itsThetaJitter * (rand_theta - M_PI) +
00203                     (theta + M_PI_2));
00204   el->contrast = exp(-itsContrastJitter * itsContrastRand.fdraw());
00205 
00206   el->itsPeriod = this->itsPeriod;
00207   el->itsSigma = this->itsSigma;
00208 
00209   return el;
00210 }
00211 
00212 // ######################################################################
00213 /* So things look consistent in everyone's emacs... */
00214 /* Local Variables: */
00215 /* mode: c++ */
00216 /* indent-tabs-mode: nil */
00217 /* End: */
00218 
00219 #endif // PSYCHO_GABORPATCH_C_DEFINED
Generated on Sun May 8 08:41:13 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3