Seg3D  2.4
Seg3D is a free volume segmentation and processing tool developed by the NIH Center for Integrative Biomedical Computing at the University of Utah Scientific Computing and Imaging (SCI) Institute.
fft.hxx
1 /*
2  For more information, please see: http://software.sci.utah.edu
3 
4  The MIT License
5 
6  Copyright (c) 2016 Scientific Computing and Imaging Institute,
7  University of Utah.
8 
9 
10  Permission is hereby granted, free of charge, to any person obtaining a
11  copy of this software and associated documentation files (the "Software"),
12  to deal in the Software without restriction, including without limitation
13  the rights to use, copy, modify, merge, publish, distribute, sublicense,
14  and/or sell copies of the Software, and to permit persons to whom the
15  Software is furnished to do so, subject to the following conditions:
16 
17  The above copyright notice and this permission notice shall be included
18  in all copies or substantial portions of the Software.
19 
20  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26  DEALINGS IN THE SOFTWARE.
27 */
28 
29 // File : fft.hxx
30 // Author : Pavel A. Koshevoy
31 // Created : 2005/06/03 10:16
32 // Copyright : (C) 2004-2008 University of Utah
33 // Description : Wrapper class and helper functions for working with
34 // FFTW3 and ITK images.
35 
36 #ifndef FFT_HXX_
37 #define FFT_HXX_
38 
39 // FFTW includes:
40 #include <fftw3.h>
41 
42 // ITK includes:
43 #include <itkImage.h>
44 
45 // system includes:
46 #include <complex>
47 #include <stdlib.h>
48 
49 #include <Core/Utils/Exception.h>
50 
51 
52 namespace itk_fft
53 {
54  //----------------------------------------------------------------
55  // set_num_fftw_threads
56  //
57  // set's number of threads used by fftw, returns previous value:
58  extern std::size_t set_num_fftw_threads(std::size_t num_threads);
59 
60  //----------------------------------------------------------------
61  // itk_image_t
62  //
63  typedef itk::Image<float, 2> itk_image_t;
64 
65  //----------------------------------------------------------------
66  // itk_imageptr_t
67  //
68  typedef itk_image_t::Pointer itk_imageptr_t;
69 
70  //----------------------------------------------------------------
71  // fft_complex_t
72  //
73  typedef std::complex<float> fft_complex_t;
74 
75  //----------------------------------------------------------------
76  // fft_data_t
77  //
78  class fft_data_t
79  {
80  public:
81  fft_data_t(): data_(NULL), nx_(0), ny_(0) {}
82  fft_data_t(const unsigned int w, const unsigned int h);
83  explicit fft_data_t(const itk_imageptr_t & real);
84  fft_data_t(const itk_imageptr_t & real,
85  const itk_imageptr_t & imag);
86  fft_data_t(const fft_data_t & data);
87  ~fft_data_t() { cleanup(); }
88 
89  fft_data_t & operator = (const fft_data_t & data);
90 
91  void cleanup();
92 
93  void resize(const unsigned int w, const unsigned int h);
94 
95  void fill(const float real, const float imag = 0.0);
96 
97  void setup(const itk_imageptr_t & real,
98  const itk_imageptr_t & imag = itk_imageptr_t(NULL));
99 
100  // ITK helpers:
101  itk_imageptr_t component(const bool imag = 0) const;
102  inline itk_imageptr_t real() const { return component(0); }
103  inline itk_imageptr_t imag() const { return component(1); }
104 
105  // Apply a low-pass filter to this image. This function will
106  // zero-out high-frequency components, where the cutoff frequency
107  // is specified by radius r in [0, 1]. The sharpness of the
108  // cutoff may be controlled by parameter s, where s == 0 results in
109  // an ideal low-pass filter, and s == 1 is a low pass filter defined
110  // by a scaled and shifted cosine function, 1 at the origin,
111  // 0.5 at the cutoff frequency and 0 at twice the cutoff frequency.
112  void apply_lp_filter(const double r, const double s = 0);
113 
114  // accessors:
115  inline const fft_complex_t * data() const { return data_; }
116  inline fft_complex_t * data() { return data_; }
117 
118  inline unsigned int nx() const { return nx_; }
119  inline unsigned int ny() const { return ny_; }
120 
121  inline const fft_complex_t & operator() (const unsigned int & x,
122  const unsigned int & y) const
123  { return at(x, y); }
124 
125  inline fft_complex_t & operator() (const unsigned int & x,
126  const unsigned int & y)
127  { return at(x, y); }
128 
129  inline const fft_complex_t & at(const unsigned int & x,
130  const unsigned int & y) const
131  { return data_[y + ny_ * x]; }
132 
133  inline fft_complex_t & at(const unsigned int & x,
134  const unsigned int & y)
135  { return data_[y + ny_ * x]; }
136 
137  protected:
138  fft_complex_t * data_;
139  unsigned int nx_;
140  unsigned int ny_;
141  };
142 
143 
144  //----------------------------------------------------------------
145  // fft
146  //
147  extern bool
148  fft(const itk_image_t::Pointer & in, fft_data_t & out);
149 
150  //----------------------------------------------------------------
151  // fft
152  //
153  extern bool
154  fft(const fft_data_t & in, fft_data_t & out, int sign = FFTW_FORWARD);
155 
156  //----------------------------------------------------------------
157  // ifft
158  //
159  extern bool
160  ifft(const fft_data_t & in, fft_data_t & out);
161 
162  //----------------------------------------------------------------
163  // ifft
164  //
165  inline fft_data_t
166  ifft(const fft_data_t & in)
167  {
168  fft_data_t out;
169 //#ifndef NDEBUG // get around an annoying compiler warning:
170 // bool ok =
171 //#endif
172  bool ok = ifft(in, out);
173 // assert(ok);
174  if (! ok)
175  {
176  CORE_THROW_EXCEPTION("ifft failed");
177  }
178  return out;
179  }
180 
181 
182  //----------------------------------------------------------------
183  // fn_fft_c_t
184  //
185  typedef fft_complex_t(*fn_fft_c_t)(const fft_complex_t & in);
186 
187  //----------------------------------------------------------------
188  // fn_fft_cc_t
189  //
190  typedef fft_complex_t(*fn_fft_cc_t)(const fft_complex_t & a,
191  const fft_complex_t & b);
192 
193  //----------------------------------------------------------------
194  // elem_by_elem
195  //
196  extern void
197  elem_by_elem(fn_fft_c_t f,
198  const fft_data_t & in,
199  fft_data_t & out);
200 
201  //----------------------------------------------------------------
202  // elem_by_elem
203  //
204  extern void
205  elem_by_elem(fft_complex_t(*f)(const float & a,
206  const fft_complex_t & b),
207  const float & a,
208  const fft_data_t & b,
209  fft_data_t & c);
210 
211  //----------------------------------------------------------------
212  // elem_by_elem
213  //
214  extern void
215  elem_by_elem(fft_complex_t(*f)(const fft_complex_t & a,
216  const float & b),
217  const fft_data_t & a,
218  const float & b,
219  fft_data_t & c);
220 
221  //----------------------------------------------------------------
222  // elem_by_elem
223  //
224  extern void
225  elem_by_elem(fft_complex_t(*f)(const fft_complex_t & a,
226  const fft_complex_t & b),
227  const fft_complex_t & a,
228  const fft_data_t & b,
229  fft_data_t & c);
230 
231  //----------------------------------------------------------------
232  // elem_by_elem
233  //
234  extern void
235  elem_by_elem(fft_complex_t(*f)(const fft_complex_t & a,
236  const fft_complex_t & b),
237  const fft_data_t & a,
238  const fft_complex_t & b,
239  fft_data_t & c);
240 
241  //----------------------------------------------------------------
242  // elem_by_elem
243  //
244  extern void
245  elem_by_elem(fn_fft_cc_t f,
246  const fft_data_t & a,
247  const fft_data_t & b,
248  fft_data_t & c);
249 
250 
251  //----------------------------------------------------------------
252  // conj
253  //
254  // element-by-element complex conjugate:
255  //
256  inline void
257  conj(const fft_data_t & in, fft_data_t & out)
258  { elem_by_elem(std::conj, in, out); }
259 
260  //----------------------------------------------------------------
261  // conj
262  //
263  inline fft_data_t
264  conj(const fft_data_t & in)
265  {
266  fft_data_t out;
267  conj(in, out);
268  return out;
269  }
270 
271 
272  //----------------------------------------------------------------
273  // sqrt
274  //
275  // element-by-element square root:
276  //
277  inline void
278  sqrt(const fft_data_t & in, fft_data_t & out)
279  { elem_by_elem(std::sqrt, in, out); }
280 
281  //----------------------------------------------------------------
282  // sqrt
283  //
284  inline fft_data_t
285  sqrt(const fft_data_t & in)
286  {
287  fft_data_t out;
288  sqrt(in, out);
289  return out;
290  }
291 
292 
293  //----------------------------------------------------------------
294  // _mul
295  //
296  template <class a_t, class b_t>
297  inline fft_complex_t
298  _mul(const a_t & a, const b_t & b)
299  { return a * b; }
300 
301  //----------------------------------------------------------------
302  // mul
303  //
304  // element-by-element multiplication, c = a * b:
305  //
306  template <class a_t, class b_t>
307  inline void
308  mul(const a_t & a, const b_t & b, fft_data_t & c)
309  { elem_by_elem(_mul, a, b, c); }
310 
311  //----------------------------------------------------------------
312  // mul
313  //
314  template <class a_t, class b_t>
315  inline fft_data_t
316  mul(const a_t & a, const b_t & b)
317  {
318  fft_data_t c;
319  mul<a_t, b_t>(a, b, c);
320  return c;
321  }
322 
323 
324  //----------------------------------------------------------------
325  // _div
326  //
327  template <class a_t, class b_t>
328  inline fft_complex_t
329  _div(const a_t & a, const b_t & b)
330  { return a / b; }
331 
332  //----------------------------------------------------------------
333  // div
334  //
335  // element-by-element division, c = a / b:
336  //
337  template <class a_t, class b_t>
338  inline void
339  div(const a_t & a, const b_t & b, fft_data_t & c)
340  { elem_by_elem(_div, a, b, c); }
341 
342  //----------------------------------------------------------------
343  // div
344  //
345  template <class a_t, class b_t>
346  inline fft_data_t
347  div(const a_t & a, const b_t & b)
348  {
349  fft_data_t c;
350  div<a_t, b_t>(a, b, c);
351  return c;
352  }
353 
354 
355  //----------------------------------------------------------------
356  // _add
357  //
358  template <class a_t, class b_t>
359  inline fft_complex_t
360  _add(const a_t & a, const b_t & b)
361  { return a + b; }
362 
363  //----------------------------------------------------------------
364  // add
365  //
366  // element-by-element addition, c = a + b:
367  //
368  template <class a_t, class b_t>
369  inline void
370  add(const a_t & a, const b_t & b, fft_data_t & c)
371  { elem_by_elem(_add, a, b, c); }
372 
373  //----------------------------------------------------------------
374  // add
375  //
376  template <class a_t, class b_t>
377  inline fft_data_t
378  add(const a_t & a, const b_t & b)
379  {
380  fft_data_t c;
381  add<a_t, b_t>(a, b, c);
382  return c;
383  }
384 
385 
386  //----------------------------------------------------------------
387  // _sub
388  //
389  template <class a_t, class b_t>
390  inline fft_complex_t
391  _sub(const a_t & a, const b_t & b)
392  { return a - b; }
393 
394  //----------------------------------------------------------------
395  // sub
396  //
397  // element-by-element subtraction, c = a - b:
398  //
399  template <class a_t, class b_t>
400  inline void
401  sub(const a_t & a, const b_t & b, fft_data_t & c)
402  { elem_by_elem(_sub, a, b, c); }
403 
404  //----------------------------------------------------------------
405  // sub
406  //
407  template <class a_t, class b_t>
408  inline fft_data_t
409  sub(const a_t & a, const b_t & b)
410  {
411  fft_data_t c;
412  sub<a_t, b_t>(a, b, c);
413  return c;
414  }
415 }
416 
417 
418 #endif // FFT_HXX_
Definition: fft.cxx:57
Definition: fft.hxx:78