vil_fft.hxx
Go to the documentation of this file.
1 // This is core/vil/algo/vil_fft.hxx
2 #ifndef vil_fft_hxx_
3 #define vil_fft_hxx_
4 //:
5 // \file
6 // \brief Functions to apply the FFT to an image.
7 // \author Fred Wheeler
8 
9 #include <complex>
10 #include <vector>
11 #include "vil_fft.h"
12 #ifdef _MSC_VER
13 # include <vcl_msvc_warnings.h>
14 #endif
15 #include <vil/vil_image_view.h>
16 #include <vnl/algo/vnl_fft_1d.h>
17 
18 //: Perform in place FFT in one dimension.
19 template<class T>
20 static void
21 vil_fft_2d_base(std::complex<T> * data,
22  unsigned n0, std::ptrdiff_t step0, // ni, istep
23  unsigned n1, std::ptrdiff_t step1, // nj, jstep
24  unsigned n2, std::ptrdiff_t step2, // nplanes, planestep
25  int dir)
26 {
27  vnl_fft_1d<T> fft_1d(n0);
28  T factor = dir<0 ? T(1) : T(1)/static_cast<T>(n0);
29 
30  if (1 == step0) // use contiguous data memory directly
31  {
32  // FFT every pixel row (or column) in every colour band:
33  for (unsigned i1=0; i1<n1; i1++)
34  for (unsigned i2=0; i2<n2; i2++)
35  {
36  std::complex<T> * d = data + i1*step1 + i2*step2;
37  fft_1d.transform(d, dir);
38  if (dir >= 0)
39  for (unsigned i0=0; i0<n0; ++i0)
40  d[i0] *= factor; // proper scaling for forward FFT
41  }
42  }
43  else // must copy non-contiguous data memory to a std::vector
44  {
45  std::vector<std::complex<T> > v(n0);
46  for (unsigned i1=0; i1<n1; i1++)
47  for (unsigned i2=0; i2<n2; i2++)
48  {
49  std::complex<T> * d = data + i1*step1 + i2*step2;
50  for (unsigned i0=0; i0<n0; i0++, d+=step0)
51  v[i0] = *d;
52  fft_1d.transform(v, dir);
53  // copy std::vector back to non-contiguous data memory
54  d = data + i1*step1 + i2*step2;
55  for (unsigned i0=0; i0<n0; i0++, d+=step0)
56  *d = v[i0]*factor; // proper scaling for forward FFT
57  }
58  }
59 }
60 
61 template<class T>
62 void
63 vil_fft_2d_fwd(vil_image_view<std::complex<T> >& img)
64 {
65  vil_fft_2d_base(img.top_left_ptr(),
66  img.ni(), img.istep(),
67  img.nj(), img.jstep(),
68  img.nplanes(), img.planestep(),
69  1);
70  vil_fft_2d_base(img.top_left_ptr(),
71  img.nj(), img.jstep(),
72  img.ni(), img.istep(),
73  img.nplanes(), img.planestep(),
74  1);
75 }
76 
77 template<class T>
78 void
79 vil_fft_2d_bwd(vil_image_view<std::complex<T> >& img)
80 {
81  vil_fft_2d_base(img.top_left_ptr(),
82  img.nj(), img.jstep(),
83  img.ni(), img.istep(),
84  img.nplanes(), img.planestep(),
85  -1);
86  vil_fft_2d_base(img.top_left_ptr(),
87  img.ni(), img.istep(),
88  img.nj(), img.jstep(),
89  img.nplanes(), img.planestep(),
90  -1);
91 }
92 
93 #undef VIL_FFT_INSTANTIATE
94 #define VIL_FFT_INSTANTIATE(T) \
95 template void vil_fft_2d_base(std::complex<T >* data, \
96  unsigned n0, std::ptrdiff_t step0, \
97  unsigned n1, std::ptrdiff_t step1, \
98  unsigned n2, std::ptrdiff_t step2, \
99  int dir); \
100 template void vil_fft_2d_fwd(vil_image_view<std::complex<T > >& img); \
101 template void vil_fft_2d_bwd(vil_image_view<std::complex<T > >& img)
102 
103 #endif // vil_fft_hxx_
Concrete view of image data of type T held in memory.
Definition: vil_fwd.h:13
#define v
A base class reference-counting view of some image data.
void vil_fft_2d_fwd(vil_image_view< std::complex< T > > &img)
Perform in place forward FFT.
Definition: vil_fft.hxx:63
void vil_fft_2d_bwd(vil_image_view< std::complex< T > > &img)
Perform in place backward FFT.
Definition: vil_fft.hxx:79
Functions to apply the FFT to an image.