37 #ifndef VIGRA_GABORFILTER_HXX
38 #define VIGRA_GABORFILTER_HXX
40 #include "imagecontainer.hxx"
42 #include "stdimage.hxx"
43 #include "copyimage.hxx"
44 #include "transformimage.hxx"
45 #include "combineimages.hxx"
47 #include "multi_shape.hxx"
138 template <
class DestImageIterator,
class DestAccessor>
140 DestImageIterator destLowerRight, DestAccessor da,
141 double orientation,
double centerFrequency,
142 double angularSigma,
double radialSigma)
144 int w = int(destLowerRight.x - destUpperLeft.x);
145 int h = int(destLowerRight.y - destUpperLeft.y);
147 double squaredSum = 0.0;
148 double cosTheta= VIGRA_CSTD::cos(orientation);
149 double sinTheta= VIGRA_CSTD::sin(orientation);
151 double radialSigma2 = radialSigma*radialSigma;
152 double angularSigma2 = angularSigma*angularSigma;
154 double wscale = w % 1 ?
157 double hscale = h % 1 ?
161 int dcX= (w+1)/2, dcY= (h+1)/2;
164 for (
int y=0; y<h; y++, destUpperLeft.y++ )
166 typename DestImageIterator::row_iterator dix = destUpperLeft.rowIterator();
168 v = hscale * ((h - (y - dcY))%h - dcY);
169 for (
int x=0; x<w; x++, dix++ )
171 u= wscale*((x - dcX + w)%w - dcX);
173 double uu = cosTheta*u + sinTheta*v - centerFrequency;
174 double vv = -sinTheta*u + cosTheta*v;
177 gabor = VIGRA_CSTD::exp(-0.5*(uu*uu / radialSigma2 + vv*vv / angularSigma2));
178 squaredSum += gabor * gabor;
179 da.set( gabor, dix );
182 destUpperLeft.y -= h;
185 double dcValue = da(destUpperLeft);
186 squaredSum -= dcValue * dcValue;
187 da.set( 0.0, destUpperLeft );
190 double factor = VIGRA_CSTD::sqrt(squaredSum);
191 for (
int y=0; y<h; y++, destUpperLeft.y++ )
193 typename DestImageIterator::row_iterator dix = destUpperLeft.rowIterator();
195 for (
int x=0; x<w; x++, dix++ )
197 da.set( da(dix) / factor, dix );
202 template <
class DestImageIterator,
class DestAccessor>
204 createGaborFilter(triple<DestImageIterator, DestImageIterator, DestAccessor> dest,
205 double orientation,
double centerFrequency,
206 double angularSigma,
double radialSigma)
209 orientation, centerFrequency,
210 angularSigma, radialSigma);
213 template <
class T,
class S>
216 double orientation,
double centerFrequency,
217 double angularSigma,
double radialSigma)
220 orientation, centerFrequency,
221 angularSigma, radialSigma);
246 double sfactor = 3.0 * VIGRA_CSTD::sqrt(VIGRA_CSTD::log(4.0));
247 return centerFrequency / sfactor;
289 return VIGRA_CSTD::tan(M_PI/directionCount/2.0) * centerFrequency
290 * VIGRA_CSTD::sqrt(8.0 / (9 * VIGRA_CSTD::log(4.0)));
318 template <
class ImageType,
319 class Alloc =
typename ImageType::allocator_type::template rebind<ImageType>::other >
324 int scaleCount_, directionCount_;
325 double maxCenterFrequency_;
330 for(
int direction= 0; direction<directionCount_; direction++)
331 for(
int scale= 0; scale<scaleCount_; scale++)
334 double centerFrequency =
335 maxCenterFrequency_ / VIGRA_CSTD::pow(2.0, (
double)scale);
337 angle, centerFrequency,
344 enum { stdFilterSize= 128, stdDirectionCount= 6, stdScaleCount= 4 };
357 Alloc
const & alloc = Alloc())
373 Alloc
const & alloc = Alloc())
375 Size2D(width, height > 0 ? height : width), alloc),
402 ImageType
const &
getFilter(
int direction,
int scale)
const
404 return this->images_[
filterIndex(direction, scale)];
418 {
return scaleCount_; }
423 {
return directionCount_; }
442 {
return maxCenterFrequency_; }
458 #endif // VIGRA_GABORFILTER_HXX