core/vil/algo/vil_fft.txx
Go to the documentation of this file.
00001 // This is core/vil/algo/vil_fft.txx
00002 #ifndef vil_fft_txx_
00003 #define vil_fft_txx_
00004 //:
00005 // \file
00006 // \brief Functions to apply the FFT to an image.
00007 // \author Fred Wheeler
00008 
00009 #include "vil_fft.h"
00010 #include <vcl_complex.h>
00011 #include <vcl_vector.h>
00012 #include <vil/vil_image_view.h>
00013 #include <vnl/algo/vnl_fft_1d.h>
00014 
00015 //: Perform in place FFT in one dimension.
00016 template<class T>
00017 static void
00018 vil_fft_2d_base(vcl_complex<T> * data,
00019                 unsigned n0, vcl_ptrdiff_t step0, // ni, istep
00020                 unsigned n1, vcl_ptrdiff_t step1, // nj, jstep
00021                 unsigned n2, vcl_ptrdiff_t step2, // nplanes, planestep
00022                 int dir)
00023 {
00024   vnl_fft_1d<T> fft_1d(n0);
00025   T factor = dir<0 ? T(1) : T(1)/static_cast<T>(n0);
00026 
00027   if (1 == step0) // use contiguous data memory directly
00028   {
00029     // FFT every pixel row (or column) in every colour band:
00030     for (unsigned i1=0; i1<n1; i1++)
00031     for (unsigned i2=0; i2<n2; i2++)
00032     {
00033       vcl_complex<T> * d = data + i1*step1 + i2*step2;
00034       fft_1d.transform(d, dir);
00035       if (dir >= 0)
00036         for (unsigned i0=0; i0<n0; ++i0)
00037           d[i0] *= factor; // proper scaling for forward FFT
00038     }
00039   }
00040   else // must copy non-contiguous data memory to a vcl_vector
00041   {
00042     vcl_vector<vcl_complex<T> > v(n0);
00043     for (unsigned i1=0; i1<n1; i1++)
00044     for (unsigned i2=0; i2<n2; i2++)
00045     {
00046       vcl_complex<T> * d = data + i1*step1 + i2*step2;
00047       for (unsigned i0=0; i0<n0; i0++, d+=step0)
00048         v[i0] = *d;
00049       fft_1d.transform(v, dir);
00050       // copy vcl_vector back to non-contiguous data memory
00051       d = data + i1*step1 + i2*step2;
00052       for (unsigned i0=0; i0<n0; i0++, d+=step0)
00053         *d = v[i0]*factor; // proper scaling for forward FFT
00054     }
00055   }
00056 }
00057 
00058 template<class T>
00059 void
00060 vil_fft_2d_fwd(vil_image_view<vcl_complex<T> >& img)
00061 {
00062   vil_fft_2d_base(img.top_left_ptr(),
00063                   img.ni(), img.istep(),
00064                   img.nj(), img.jstep(),
00065                   img.nplanes(), img.planestep(),
00066                   1);
00067   vil_fft_2d_base(img.top_left_ptr(),
00068                   img.nj(), img.jstep(),
00069                   img.ni(), img.istep(),
00070                   img.nplanes(), img.planestep(),
00071                   1);
00072 }
00073 
00074 template<class T>
00075 void
00076 vil_fft_2d_bwd(vil_image_view<vcl_complex<T> >& img)
00077 {
00078   vil_fft_2d_base(img.top_left_ptr(),
00079                   img.nj(), img.jstep(),
00080                   img.ni(), img.istep(),
00081                   img.nplanes(), img.planestep(),
00082                   -1);
00083   vil_fft_2d_base(img.top_left_ptr(),
00084                   img.ni(), img.istep(),
00085                   img.nj(), img.jstep(),
00086                   img.nplanes(), img.planestep(),
00087                   -1);
00088 }
00089 
00090 #undef VIL_FFT_INSTANTIATE
00091 #define VIL_FFT_INSTANTIATE(T) \
00092 template void vil_fft_2d_base(vcl_complex<T >* data, \
00093                               unsigned n0, vcl_ptrdiff_t step0, \
00094                               unsigned n1, vcl_ptrdiff_t step1, \
00095                               unsigned n2, vcl_ptrdiff_t step2, \
00096                               int dir); \
00097 template void vil_fft_2d_fwd(vil_image_view<vcl_complex<T > >& img); \
00098 template void vil_fft_2d_bwd(vil_image_view<vcl_complex<T > >& img)
00099 
00100 #endif // vil_fft_txx_