00001
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00033
00034 #ifndef GROOVX_VISX_GABORPATCH_CC_UTC20050626084015_DEFINED
00035 #define GROOVX_VISX_GABORPATCH_CC_UTC20050626084015_DEFINED
00036
00037 #include "gaborpatch.h"
00038
00039 #include <map>
00040
00041 #include "rutz/trace.h"
00042
00043 namespace
00044 {
00045 typedef std::map<GaborSpec, GaborPatch*> MapType;
00046 MapType theMap;
00047
00048 const int NUM_THETA = 64;
00049 const int NUM_PHASE = 8;
00050 const double DELTA_THETA = M_PI / NUM_THETA;
00051 const double DELTA_PHASE = 2 * M_PI / NUM_PHASE;
00052 }
00053
00054 GaborSpec::GaborSpec(double s, double o, double t, double p) :
00055 theta(DELTA_THETA * (int(geom::rad_0_pi(t)/DELTA_THETA + 0.5) % NUM_THETA)),
00056 phi(DELTA_PHASE * (int(geom::rad_0_2pi(p)/DELTA_PHASE + 0.5) % NUM_PHASE)),
00057 sigma(s),
00058 omega(o)
00059 {}
00060
00061 bool GaborSpec::operator<(const GaborSpec& x) const
00062 {
00063 if (theta < x.theta) return true;
00064 else if (theta == x.theta)
00065 {
00066 if (phi < x.phi) return true;
00067 else if (phi == x.phi)
00068 {
00069 if (sigma < x.sigma) return true;
00070 else if (sigma == x.sigma)
00071 {
00072 return (omega < x.omega);
00073 }
00074 }
00075 }
00076
00077 return false;
00078 }
00079
00080 GaborPatch::GaborPatch(const GaborSpec& spec)
00081 :
00082 itsSpec ( spec ),
00083 itsSize ( int(8*spec.sigma + 0.5) ),
00084 itsCenter ( itsSize/2.0 + 0.5 ),
00085 itsCosTheta ( cos(spec.theta) ),
00086 itsSinTheta ( sin(spec.theta) ),
00087 itsSigmaSqr ( 2.0* spec.sigma * spec.sigma ),
00088 itsData ( 0 )
00089 {
00090 GVX_TRACE("GaborPatch::GaborPatch");
00091 }
00092
00093 GaborPatch::~GaborPatch()
00094 {
00095 GVX_TRACE("GaborPatch::~GaborPatch");
00096 delete [] itsData;
00097 }
00098
00099 const GaborPatch& GaborPatch::lookup(const GaborSpec& spec)
00100 {
00101 GVX_TRACE("GaborPatch::lookup");
00102
00103 GaborPatch*& patch = theMap[spec];
00104
00105 if (patch == 0)
00106 {
00107 patch = new GaborPatch(spec);
00108 patch->fillCache();
00109 }
00110
00111 return *patch;
00112 }
00113
00114 const GaborPatch& GaborPatch::lookup(double sigma, double omega,
00115 double theta, double phi)
00116 {
00117 GaborSpec spec(sigma, omega, theta, phi);
00118
00119 return lookup(spec);
00120 }
00121
00122 void GaborPatch::fillCache()
00123 {
00124 if (itsData == 0)
00125 {
00126 itsData = new double[itsSize*itsSize];
00127
00128 double* ptr = itsData;
00129
00130 for (int y = 0; y < itsSize; ++y)
00131 for (int x = 0; x < itsSize; ++x)
00132 *ptr++ = compute(x, y);
00133 }
00134 }
00135
00136
00137 double GaborPatch::compute(int x, int y) const
00138 {
00139 const double fy = y - itsCenter;
00140 const double fx = x - itsCenter;
00141
00142 const double dx = itsCosTheta * fx - itsSinTheta * fy;
00143 const double dy = itsSinTheta * fx + itsCosTheta * fy;
00144
00145 const double dsqr = (dx*dx + dy*dy) / itsSigmaSqr;
00146
00147 const double sinus = cos(itsSpec.omega * dx + itsSpec.phi);
00148
00149 const double gauss = exp(-dsqr);
00150 return sinus * gauss;
00151 }
00152
00153 static const char __attribute__((used)) vcid_groovx_visx_gaborpatch_cc_utc20050626084015[] = "$Id: gaborpatch.cc 10065 2007-04-12 05:54:56Z rjpeters $ $HeadURL: file:
00154 #endif // !GROOVX_VISX_GABORPATCH_CC_UTC20050626084015_DEFINED