Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
FFT2D_Tiles.cpp
1 /*
2 This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4 Copyright (C) 2003-2009 (see file CONTACT for details)
5 Multimediale Systeme der Informationsverarbeitung
6 Institut fuer Informatik
7 Christian-Albrechts-Universitaet Kiel
8 
9 
10 BIAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
13 (at your option) any later version.
14 
15 BIAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Lesser General Public License for more details.
19 
20 You should have received a copy of the GNU Lesser General Public License
21 along with BIAS; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24 
25 
26 #include "FFT2D_Tiles.hh"
27 #include <fftw3.h>
28 #include <Base/Debug/Error.hh>
29 
30 
31 using namespace BIAS;
32 using namespace std;
33 
34 template <class InputStorageType, class OutputStorageType>
37 {
38  this->_TileSizeX = 0;
39  this->_TileSizeY = 0;
40  this->_NumTilesX = 0;
41  this->_NumTilesY = 0;
42 }
43 
44 template <class InputStorageType, class OutputStorageType>
46 {
47  Release();
48  fftw_cleanup();
49 }
50 
51 template <class InputStorageType, class OutputStorageType>
53 Init(int width, int height, int tilewidth, int tileheight)
54 {
55 #ifdef BIAS_DEBUG
56  if (this->_SizeX!=0 || this->_SizeY!=0 || this->_OutNum!=0 || this->_out || this->_in || this->_p_forward){
57  BIASERR("FFT2D_Tiles: call Release() before calling Init() a second time");
58  BIASEXIT(EXIT_FAILURE, "FFT2D_Tiles: call Release() before calling Init() a second time");
59  }
60 #endif
61  this->_SizeX=height;
62  this->_SizeY=width;
63 
64  this->_TileSizeX = tileheight;
65  this->_TileSizeY = tilewidth;
66  this->_NumTilesX = this->_SizeX / this->_TileSizeX;
67  if (this->_SizeX % this->_TileSizeX >0) this->_NumTilesX++;
68  this->_NumTilesY = this->_SizeY / this->_TileSizeY;
69  if (this->_SizeY % this->_TileSizeY >0) this->_NumTilesY++;
70 
71 
72 
73  this->_Size = this->_TileSizeX*this->_TileSizeY;
74  this->_OutSizeY = (this->_TileSizeY>>1)+1;
75  this->_OutNum=this->_TileSizeX * this->_OutSizeY;
76  this->_out =(fftw_complex*)fftw_malloc(sizeof(fftw_complex) * this->_OutNum);
77  this->_in = (double*)fftw_malloc(sizeof(double) * this->_Size);
78  // this is slow a few seconds
79  this->_p_forward = fftw_plan_dft_r2c_2d(this->_TileSizeX, this->_TileSizeY, this->_in, this->_out, FFTW_MEASURE);
80  this->_p_reverse = fftw_plan_dft_c2r_2d(this->_TileSizeX, this->_TileSizeY, this->_out, this->_in, FFTW_MEASURE);
81 }
82 
83 
84 
85 
86 
87 
88 template <class InputStorageType, class OutputStorageType>
91 {
92  if (this->_p_forward) fftw_destroy_plan(this->_p_forward);
93  if (this->_in) fftw_free(this->_in);
94  if (this->_out) fftw_free(this->_out);
95  this->_in=NULL;
96  this->_out=NULL;
97  this->_p_forward=NULL;
98  this->_SizeX=this->_SizeY=this->_Size=this->_OutNum=0;
99 }
100 
101 
102 template <class InputStorageType, class OutputStorageType>
105 {
106  BIASERR("not implemented");
107  return 0;
108 }
109 
110 
111 template <class InputStorageType, class OutputStorageType>
114 {
115  BIASERR("not implemented");
116  return 0;
117 }
118 
119 
120 
121 
122 /** dst.GetChannelCount()==2*src.GetCHannelCount() */
123 template <class InputStorageType, class OutputStorageType>
126 {
127 
128  if (!dst.IsEmpty()) dst.Release();
129  dst.Init(this->_OutSizeY, this->_SizeX, 2);
130  // copy and cast back int dst, two channel mode
131  fftw_complex *outp = this->_out;
132  OutputStorageType *oimgp = dst.GetImageData();
133  for ( int i=0;i<this->_OutNum; i++){
134  *oimgp = (OutputStorageType) (*outp)[0];
135  oimgp++;
136  *oimgp = (OutputStorageType) (*outp)[1];
137  oimgp++;
138  outp++;
139  }
140  return 0;
141 }
142 
143 
144 
145 /** dstX.GetChannelCount()==src.GetCHannelCount() */
146 template <class InputStorageType, class OutputStorageType>
149  Image<OutputStorageType>& /*dst1*/,
150  Image<OutputStorageType>& /*dst2*/)
151 {
152  BIASERR("not implemented");
153  return 0;
154 }
155 
156 
157 /** dst.GetChannelCount()==src.GetCHannelCount() */
158 template <class InputStorageType, class OutputStorageType>
161 {
163  InputStorageType **Iida ;
164 
165  if ( ((int) src.GetHeight() != this->_TileSizeX * this->_NumTilesX)
166  || ((int) src.GetWidth() != this->_TileSizeY * this->_NumTilesY)) {
167  tmpImg = src;
168  tmpImg.ZeroPad( this->_TileSizeX * this->_NumTilesX, this->_TileSizeY * this->_NumTilesY );
169  Iida = tmpImg.GetImageDataArray();
170  }
171  else {
172  tmpImg = src;
173  Iida = tmpImg.GetImageDataArray();
174  }
175  // prepare Image
176  if (!dst.IsEmpty()) dst.Release();
177  dst.Init( this->_OutSizeY * this->_NumTilesY,this->_TileSizeX * this->_NumTilesX,1);
178 
179  OutputStorageType **Oida = dst.GetImageDataArray();
180  // for all tiles
181  for ( int ty=0; ty<this->_NumTilesY; ty++) {
182  for ( int tx=0; tx<this->_NumTilesX; tx++) {
183  double *inp = this->_in;
184  fftw_complex *outp = this->_out;
185 
186  // copy this tile int _in;
187  for ( int y = ty*this->_TileSizeY; y<(ty+1)*this->_TileSizeY; y++)
188  for ( int x = tx*this->_TileSizeX; x<(tx+1)*this->_TileSizeX; x++) {
189  *inp++ = Iida[y][x];
190  }
191  // fft it
192  fftw_execute(this->_p_forward);
193  // copy result back
194  for ( int y = ty*this->_OutSizeY; y<(ty+1)*this->_OutSizeY; y++)
195  for ( int x = tx*this->_TileSizeX; x<(tx+1)*this->_TileSizeX; x++) {
196  // remeber: x is height and y is width
197  Oida[x][y] = (OutputStorageType) sqrt((*outp[0]* *outp[0]) +
198  (*outp[1]* *outp[1]));
199  outp++;
200  }
201  }
202  }
203 
204  return 0;
205 }
206 
207 
208 
209 
210 
211 template <class InputStorageType, class OutputStorageType>
215 {
216  Reverse_(src);
217  if (!dst.IsEmpty()) dst.Release();
218  dst.Init(this->_SizeX, this->_SizeY,1);
219  // copy and cast back int dst, abs mode
220  double *inp = this->_in;
221  InputStorageType *oimgp = dst.GetImageData();
222  for ( int i=0;i<this->_Size; i++){
223  *oimgp = (InputStorageType) *inp;
224  oimgp++;
225  inp++;
226  }
227 
228  return 0;
229 }
230 
231 //////////////////////////////////////////////////////////////////////////
232 // instantiation
233 //////////////////////////////////////////////////////////////////////////
234 //#define FILTER_INSTANTIATION_CLASS FFT2D_Tiles
235 //#define FILTER_INSTANTIATION_NO_UNSIGNED_OUTPUT
236 //#include "Filter/Filterinst.hh"
237 
238 
239 #if defined(BUILD_IMAGE_FLOAT)
240 template class BIASImage_EXPORT FFT2D_Tiles<float, float>;
241 #endif
242 #if defined(BUILD_IMAGE_DOUBLE)
243 template class BIASImage_EXPORT FFT2D_Tiles<double, double>;
244 #endif
245 #if defined(BUILD_IMAGE_UCHAR) && defined(BUILD_IMAGE_FLOAT)
246 template class BIASImage_EXPORT FFT2D_Tiles<unsigned char, float>;
247 #endif
248 #if defined(BUILD_IMAGE_UCHAR) && defined(BUILD_IMAGE_DOUBLE)
249 template class BIASImage_EXPORT FFT2D_Tiles<unsigned char, double>;
250 #endif
251 
void Release()
reimplemented from ImageBase
Definition: Image.cpp:1579
void Release()
cal this before a second call to Init()
Definition: FFT2D_Tiles.cpp:90
bool IsEmpty() const
check if ImageData_ points to allocated image buffer or not
Definition: ImageBase.hh:245
virtual void Init(int, int)
Definition: FFT2D_Tiles.hh:54
Wrapper to the fftw3 library, which is supposed to perform the FFT patch- (tile-) wise...
Definition: FFT2D_Tiles.hh:47
int ZeroPad(const unsigned int newwidth, const unsigned int newheight, unsigned char bgcolor=0)
backward compatibility interface for Pad.
Definition: ImageBase.cpp:1122
virtual int Reverse_(const Image< OutputStorageType > &src)
unsigned int GetWidth() const
Definition: ImageBase.hh:312
virtual int Filter(const Image< InputStorageType > &src, Image< OutputStorageType > &dst)
dst.GetChannelCount()==2*src.GetCHannelCount() The result is not normalized!
virtual int Forward_(const Image< InputStorageType > &src)
virtual int TransformAbs(const Image< InputStorageType > &src, Image< OutputStorageType > &dst)
Transform forward and get absolute value from complex result The result is not normalized! ...
virtual int TransformReverse(const Image< OutputStorageType > &src, Image< InputStorageType > &dst)
Transform reverse, src must be of _SizeX,_OutSizeY,2.
unsigned int GetHeight() const
Definition: ImageBase.hh:319
void Init(unsigned int Width, unsigned int Height, unsigned int channels=1, enum EStorageType storageType=ST_unsignedchar, const bool interleaved=true)
calls Init from ImageBase storageType is ignored, just dummy argument
Definition: Image.cpp:421
const StorageType * GetImageData() const
overloaded GetImageData() from ImageBase
Definition: Image.hh:137
const StorageType ** GetImageDataArray() const
overloaded GetImageDataArray() from ImageBase
Definition: Image.hh:153