Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
FFT2D_free.cpp
1 
2 #include "FFT2D_free.hh"
3 //#include "fftpack5/fftpack5.h"
4 #include "fftpack/fftpack.h"
5 #include <iostream>
6 
7 using namespace BIAS;
8 using namespace std;
9 
10 template <class StorageType>
13 {
14  WorkSize0_ = WorkSize1_ = 0;
15  WorkArray0_ = WorkArray1_ = NULL;
16  TmpArray0_ = TmpArray1_ = NULL;
17  TmpArraySize0_ = TmpArraySize1_ = 0;
18  Normalize_ = 0;
19 }
20 
21 
22 template <class StorageType>
25 {
26 
27 }
28 
29 
30 template <class StorageType>
32 Init(int sizex, int sizey)
33 {
34  // if size matches, do nothing, if it it does not match, clear and re-init
35 
36  if (sizex != WorkSize0_) {
37  delete[] TmpArray0_;
38  delete[] WorkArray0_;
39  TmpArray0_ = NULL;
40  WorkArray0_ = NULL;
41  }
42  if (sizey != WorkSize1_) {
43  delete[] TmpArray1_;
44  delete[] WorkArray1_;
45  TmpArray1_ = NULL;
46  WorkArray1_ = NULL;
47  }
48 
49 
50  if (WorkArray0_ == NULL) {
51  WorkSize0_ = sizex;
52  TmpArraySize0_ = 4 * WorkSize0_+15;
53  TmpArray0_ = new float[TmpArraySize0_];
54  WorkArray0_ = new float[2*WorkSize0_];
55  cffti_(&WorkSize0_,TmpArray0_);
56  }
57  if (WorkArray1_ == NULL) {
58  WorkSize1_ = sizey;
59  TmpArraySize1_ = 4 * WorkSize1_+15;
60  TmpArray1_ = new float[TmpArraySize1_];
61  WorkArray1_ = new float[2*WorkSize1_];
62  cffti_(&WorkSize1_,TmpArray1_);
63  }
64  Normalize_ = sizex * sizey;
65 }
66 
67 
68 
69 template <class StorageType>
72  unsigned int col)
73 {
74  const float **ida=ComplexImg.GetImageDataArray();
75  unsigned int count = ComplexImg.GetHeight();
76  for (unsigned int j=0;j<count;j++){
77  WorkArray1_[j*2] = ida[j][col*2];
78  WorkArray1_[j*2+1] = ida[j][col*2+1];
79  }
80 }
81 
82 template <class StorageType>
85  unsigned int row)
86 {
87  const float **ida=ComplexImg.GetImageDataArray();
88  memcpy(WorkArray0_,ida[row],ComplexImg.GetWidth()*2*sizeof(float));
89 
90 }
91 
92 
93 
94 template <class StorageType>
96 WorkArray0ToComplexRow_(Image<float> &ComplexImg,unsigned int row)
97 {
98  float **out_ida=ComplexImg.GetImageDataArray();
99  memcpy(out_ida[row],WorkArray0_,ComplexImg.GetWidth()*2*sizeof(float));
100 
101 }
102 
103 
104 template <class StorageType>
106 WorkArray1ToComplexColumn_(Image<float> &ComplexImg,unsigned int col)
107 {
108  float **out_ida=ComplexImg.GetImageDataArray();
109  unsigned int count = ComplexImg.GetHeight();
110  for (unsigned int j=0;j<count;j++){
111  out_ida[j][col*2] = WorkArray1_[j*2];
112  out_ida[j][col*2+1] = WorkArray1_[j*2+1];
113  }
114 
115 }
116 
117 
118 template <class StorageType>
120 Forward(const Image<StorageType> &in, Image<float> &ComplexOut)
121 {
122  if (in.GetChannelCount() != 1)
123  BEXCEPTION("Can not FFT on more then one channel");
124  // first, extract ech row ad transform it
125  unsigned int NumRows=in.GetHeight();
126  unsigned int NumCols=in.GetWidth();
127  unsigned int NewNumCols = NumCols/2 +1;
128  Image<float> TmpImg(NumCols,NumRows,2);
129  ComplexOut.Init(NewNumCols,NumRows,2);
130  const StorageType **in_ida=in.GetImageDataArray();
131 
132  Init(NumCols, NumRows);
133 
134  // compute fft for each row and put into ComplexOut
135  for (unsigned int j=0;j<NumRows; j++) {
136  memset(WorkArray0_,0,2*WorkSize0_*sizeof(float)); //
137  for (unsigned int i=0;i<NumCols;i++)
138  WorkArray0_[i*2] = in_ida[j][i];
139  cfftf_(&WorkSize0_, WorkArray0_,TmpArray0_);
140  WorkArray0ToComplexRow_(TmpImg, j);
141  }
142 
143  // now for each col, same procedure again
144  // restrict to non-redundant half (see www.fftw3.org)
145  for (unsigned int i=0;i<NewNumCols; i++) {
146  ComplexColumnToWorkArray1_(TmpImg,i);
147  cfftf_(&WorkSize1_,WorkArray1_,TmpArray1_);
148  WorkArray1ToComplexColumn_(ComplexOut,i);
149  }
150 }
151 
152 template <class StorageType>
154 Reverse(const Image<float> &ComplexIn, Image<StorageType> &res)
155 {
156  unsigned int NumRows=ComplexIn.GetHeight();
157  unsigned int NumCols=ComplexIn.GetWidth();
158  unsigned int NewNumCols = (NumCols-1)*2;
159  res.Init(NewNumCols,NumRows,2);
160  Image<float> tmpImg(NewNumCols,NumRows,2);
161  // first the columns
162  Init( NewNumCols,NumRows);
163  for (unsigned int i=0;i<NumCols; i++) {
164  ComplexColumnToWorkArray1_(ComplexIn,i);
165  cfftb_(&WorkSize1_,WorkArray1_,TmpArray1_);
166  WorkArray1ToComplexColumn_(tmpImg,i);
167  WorkArray1ToComplexColumn_(tmpImg,NewNumCols-i-1);
168  }
169 
170 
171 
172  //// now the rows, then into res
173  StorageType **out_ida=res.GetImageDataArray();
174  for (unsigned int j=0;j<NumRows; j++) {
175  ComplexRowToWorkArray0_(tmpImg,j);
176  cfftb_(&WorkSize0_,WorkArray0_,TmpArray0_);
177  for (unsigned int i=0;i<NumCols*2; i++)
178  out_ida[j][i] = (StorageType)WorkArray0_[i];
179  }
180 }
181 
182 template <class StorageType>
185 {
186  float *data=Image.GetImageData();
187  unsigned int count = Image.GetWidth() *Image.GetHeight() *
188  Image.GetChannelCount();
189  for (unsigned int i=0;i<count;i++)
190  data[i] = data[i]/float(Normalize_);
191 
192 }
193 
194 
195 template <class StorageType>
197 GetMagnitude(const Image<float> &ComplexIn, Image<float> &value)
198 {
199  if (!value.IsEmpty()) value.Release();
200  value.Init(ComplexIn.GetWidth(),ComplexIn.GetHeight());
201 
202  const float *in=ComplexIn.GetImageData();
203  float *out = value.GetImageData();
204  unsigned int count = ComplexIn.GetWidth() *ComplexIn.GetHeight()*2;
205  unsigned int j=0;
206  for (unsigned int i=0;i<count;i+=2){
207  out[j++] = sqrt(in[i]*in[i] + in[i+1]*in[i+1]);
208  }
209 
210 
211 
212 }
213 
214 
215 namespace BIAS{
216 template class BIASImage_EXPORT FFT2D_free< unsigned char>;
217 
218 #if defined(BUILD_IMAGE_FLOAT)
219 template class BIASImage_EXPORT FFT2D_free< float>;
220 #endif
221 #if defined(BUILD_IMAGE_SHORT)
222 template class BIASImage_EXPORT FFT2D_free<short>;
223 #endif
224 
225 }
void Release()
reimplemented from ImageBase
Definition: Image.cpp:1579
void WorkArray1ToComplexColumn_(Image< float > &ComplexImg, unsigned int col)
Definition: FFT2D_free.cpp:106
bool IsEmpty() const
check if ImageData_ points to allocated image buffer or not
Definition: ImageBase.hh:245
void Init(int sizex, int sizey)
Definition: FFT2D_free.cpp:32
unsigned int GetWidth() const
Definition: ImageBase.hh:312
virtual ~FFT2D_free()
Definition: FFT2D_free.cpp:24
void WorkArray0ToComplexRow_(Image< float > &ComplexImg, unsigned int row)
Definition: FFT2D_free.cpp:96
unsigned int GetChannelCount() const
returns the number of Color channels, e.g.
Definition: ImageBase.hh:382
unsigned int GetHeight() const
Definition: ImageBase.hh:319
void ComplexRowToWorkArray0_(const Image< float > &ComplexImg, unsigned int row)
Definition: FFT2D_free.cpp:84
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
void GetMagnitude(const Image< float > &ComplexIn, Image< float > &value)
take the spectrum image (2-channel) and compute the absolute value for each pixel ...
Definition: FFT2D_free.cpp:197
Wrapper to the fftpack library from netlib (see fftpack/fft.c), implementing the fft (Fast Fourier Tr...
Definition: FFT2D_free.hh:42
void Reverse(const Image< float > &ComplexIn, Image< StorageType > &res)
Definition: FFT2D_free.cpp:154
void Forward(const Image< StorageType > &in, Image< float > &ComplexOut)
apply FFT on
Definition: FFT2D_free.cpp:120
void ComplexColumnToWorkArray1_(const Image< float > &ComplexImg, unsigned int col)
Definition: FFT2D_free.cpp:71
void Normalize(Image< float > &Image)
apply normalisation on spectrum image, which is float-type
Definition: FFT2D_free.cpp:184
const StorageType ** GetImageDataArray() const
overloaded GetImageDataArray() from ImageBase
Definition: Image.hh:153