00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00020 #include<ImLib3D/Image3D.hpp>
00021
00022 #include<ImLib3D/FFT.hpp>
00023 #include<ImLib3D/Display.hpp>
00024
00025
00026
00027 #include<fftw3.h>
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 void
00043 IP3D::FFT(const Image3Dcomplexf& src,Image3Dcomplexf &res0, bool resultFullSize)
00044 {
00045 ImageProcessorArgs<Image3Dcomplexf> args(ImArgs(src),res0);
00046 args.SameSize();
00047 Image3Dcomplexf &res=args.GetDest();
00048
00049
00050 double t0=DTime();
00051 fftwf_complex *in =(fftwf_complex *)((void *)src.GetData());
00052 fftwf_complex *out=(fftwf_complex *)((void *)res.GetData());
00053 fftwf_plan fftwPlan=fftwf_plan_dft_3d(src.Depth(),src.Height(),src.Width(),
00054 in,out,
00055 FFTW_FORWARD,FFTW_ESTIMATE);
00056 fftwf_execute(fftwPlan);
00057 fftwf_destroy_plan(fftwPlan);
00058 mprintf("fft complex:float elapsed time:%f\n",DTime(t0));
00059 }
00060
00061 void
00062 IP3D::FFT(const Image3Dcomplexd& src,Image3Dcomplexd &res0, bool resultFullSize)
00063 {
00064 ImageProcessorArgs<Image3Dcomplexd> args(ImArgs(src),res0);
00065 args.SameSize();
00066 Image3Dcomplexd &res=args.GetDest();
00067
00068
00069 double t0=DTime();
00070 fftw_complex *in =(fftw_complex *)((void *)src.GetData());
00071 fftw_complex *out=(fftw_complex *)((void *)res.GetData());
00072 fftw_plan fftwPlan=fftw_plan_dft_3d(src.Depth(),src.Height(),src.Width(),
00073 in,out,
00074 FFTW_FORWARD,FFTW_ESTIMATE);
00075 fftw_execute(fftwPlan);
00076 fftw_destroy_plan(fftwPlan);
00077 mprintf("fft complex:double elapsed time:%f\n",DTime(t0));
00078 }
00079
00080
00081 void
00082 IP3D::FFT(const Image3Df& src,
00083 Image3Dcomplexf &res0,
00084 bool resultFullSize)
00085 {
00086 Size3D halfSize(src.Width()/2+1,src.Height(),src.Depth());
00087
00088 Image3Dcomplexf *tres;
00089 if(resultFullSize){tres=new Image3Dcomplexf(halfSize);}
00090 else{res0.Resize(halfSize);tres=&res0;}
00091 Image3Dcomplexf &res=*tres;
00092
00093
00094 double t0=DTime();
00095 float *in =(float *) src.GetData();
00096 fftwf_complex *out=(fftwf_complex *)((void *)res.GetData());
00097 fftwf_plan fftwPlan=fftwf_plan_dft_r2c_3d(src.Depth(),
00098 src.Height(),
00099 src.Width(),
00100 in,out,
00101 FFTW_ESTIMATE);
00102
00103 fftwf_execute(fftwPlan);
00104 mprintf("FFTRealToComplex:: (float) fft elapsed time:%f\n",DTime(t0));
00105
00106
00107 if(resultFullSize)
00108 {
00109 res0.Resize(src.Size());
00110 Image3Dcomplexf::iteratorXYZ p;
00111 for(p=res.begin();p!=res.end();++p)
00112 {
00113 res0(p.Pos())=complexf((*p).real(),(*p).imag());
00114 if(p.x>0)
00115 {
00116 res0(src.Width()-p.x,p.y,p.z)=complexf((*p).real(),(*p).imag());
00117 }
00118 }
00119 delete tres;
00120 }
00121 }
00122
00123
00124 void
00125 IP3D::FFT(const Image3Dd& src, Image3Dcomplexd &res0,bool resultFullSize)
00126 {
00127 Size3D halfSize(src.Width()/2+1,src.Height(),src.Depth());
00128
00129 Image3Dcomplexd *tres;
00130 if(resultFullSize){tres=new Image3Dcomplexd(halfSize);}
00131 else{res0.Resize(halfSize);tres=&res0;}
00132 Image3Dcomplexd &res=*tres;
00133
00134
00135 double t0=DTime();
00136 double *in =(double *) src.GetData();
00137 fftw_complex *out=(fftw_complex *)((void *)res.GetData());
00138 fftw_plan fftwPlan=fftw_plan_dft_r2c_3d(src.Depth(),
00139 src.Height(),
00140 src.Width(),
00141 in,out,
00142 FFTW_ESTIMATE);
00143
00144 fftw_execute(fftwPlan);
00145 mprintf("FFTRealToComplex:: (float) fft elapsed time:%f\n",DTime(t0));
00146
00147
00148 if(resultFullSize)
00149 {
00150 res0.Resize(src.Size());
00151 Image3Dcomplexd::iteratorXYZ p;
00152 for(p=res.begin();p!=res.end();++p)
00153 {
00154 res0(p.Pos())=complexf((*p).real(),(*p).imag());
00155 if(p.x>0)
00156 {
00157 res0(src.Width()-p.x,p.y,p.z)=complexf((*p).real(),(*p).imag());
00158 }
00159 }
00160 delete tres;
00161 }
00162 }
00163
00164
00165 void
00166 IP3D::FFTInverse(const Image3Dcomplexf& src,Image3Dcomplexf &res0,
00167 int resultWidth,bool overwriteSrc)
00168 {
00169 ImageProcessorArgs<Image3Dcomplexf> args(ImArgs(src),res0);
00170 args.SameSize();
00171 Image3Dcomplexf &res=args.GetDest();
00172
00173 double t0=DTime();
00174 fftwf_complex *in =(fftwf_complex *)((void *)src.GetData());
00175 fftwf_complex *out=(fftwf_complex *)((void *)res.GetData());
00176 fftwf_plan fftwPlan=fftwf_plan_dft_3d(src.Depth(),src.Height(),src.Width(),
00177 in,out,
00178 FFTW_BACKWARD,FFTW_ESTIMATE);
00179 fftwf_execute(fftwPlan);
00180 fftwf_destroy_plan(fftwPlan);
00181 mprintf("FFTInverse:: complex<float> -> complex<float> elapsed time:%f\n",
00182 DTime(t0));
00183 }
00184
00185
00186 void
00187 IP3D::FFTInverse(const Image3Dcomplexd& src,Image3Dcomplexd &res0,
00188 int resultWidth,bool overwriteSrc)
00189 {
00190 ImageProcessorArgs<Image3Dcomplexd> args(ImArgs(src),res0);
00191 args.SameSize();
00192 Image3Dcomplexd &res=args.GetDest();
00193
00194 double t0=DTime();
00195 fftw_complex *in =(fftw_complex *)((void *)src.GetData());
00196 fftw_complex *out=(fftw_complex *)((void *)res.GetData());
00197 fftw_plan fftwPlan=fftw_plan_dft_3d(src.Depth(),src.Height(),src.Width(),
00198 in,out,
00199 FFTW_BACKWARD,FFTW_ESTIMATE);
00200 fftw_execute(fftwPlan);
00201 fftw_destroy_plan(fftwPlan);
00202 mprintf("FFTInverse:: complex<double> -> complex<double> elapsed time:%f\n",
00203 DTime(t0));
00204 }
00205
00206
00207 void
00208 IP3D::FFTInverse(const Image3Dcomplexf& src0,Image3Df& res,
00209 int resultWidth,bool overwriteSrc)
00210 {
00211
00212 if(resultWidth==src0.Width() || resultWidth==0)
00213 {
00214 Image3Dcomplexf tmp;
00215 IP3D::FFTInverse(src0,tmp);
00216 tmp.ComplexReal(res);
00217 return;
00218 }
00219
00220
00221
00222
00223
00224
00225 Image3Dcomplexf *psrc=(Image3Dcomplexf *)&src0;
00226 if(!overwriteSrc){psrc=new Image3Dcomplexf(src0);}
00227 Image3Dcomplexf& src=*psrc;
00228
00229
00230 if(src.Width()!=resultWidth/2+1)
00231 {
00232 ThrowError("FFTInverse:: (ComplexToReal) src.Width incompatible with resultWidth argument. src.Width:%d resultWidth:%d",src.Width(),resultWidth);}
00233 res.Resize(Size3D(resultWidth,src.Height(),src.Depth()));
00234
00235 double t0=DTime();
00236 fftwf_complex *in =(fftwf_complex *)((void *)src.GetData());
00237 float *out=(float *)((void *)res.GetData());
00238 fftwf_plan fftwPlan=fftwf_plan_dft_c2r_3d(res.Depth(),
00239 res.Height(),
00240 res.Width(),
00241 in,out,
00242 FFTW_ESTIMATE);
00243 fftwf_execute(fftwPlan);
00244 fftwf_destroy_plan(fftwPlan);
00245 mprintf("FFTInverse:: ComplexToReal float, elapsed time:%f\n",DTime(t0));
00246
00247 if(!overwriteSrc){delete psrc;}
00248 }
00249
00250 void
00251 IP3D::FFTInverse(const Image3Dcomplexd& src0,Image3Dd& res,
00252 int resultWidth,bool overwriteSrc)
00253 {
00254
00255 if(resultWidth==src0.Width() || resultWidth==0)
00256 {
00257 Image3Dcomplexd tmp;
00258 IP3D::FFTInverse(src0,tmp);
00259 res.Resize(src0.Size());
00260 Image3Dcomplexd::const_iteratorFast pSrc;
00261 Image3Dd::iteratorFast pRes;
00262 for (pSrc = src0.begin(),pRes=res.begin(); pSrc != src0.end();
00263 pSrc++,pRes++)
00264 {
00265 *pRes=(*pSrc).real();
00266 }
00267 return;
00268 }
00269
00270
00271
00272
00273
00274
00275 Image3Dcomplexd *psrc=(Image3Dcomplexd *)&src0;
00276 if(!overwriteSrc){psrc=new Image3Dcomplexd(src0);}
00277 Image3Dcomplexd& src=*psrc;
00278
00279
00280 if(src.Width()!=resultWidth/2+1)
00281 {
00282 ThrowError("FFTInverse:: (ComplexToReal) src.Width incompatible with resultWidth argument. src.Width:%d resultWidth:%d",src.Width(),resultWidth);}
00283 res.Resize(Size3D(resultWidth,src.Height(),src.Depth()));
00284
00285 double t0=DTime();
00286 fftw_complex *in =(fftw_complex *)((void *)src.GetData());
00287 double *out=(double *)((void *)res.GetData());
00288 fftw_plan fftwPlan=fftw_plan_dft_c2r_3d(res.Depth(),
00289 res.Height(),
00290 res.Width(),
00291 in,out,
00292 FFTW_ESTIMATE);
00293 fftw_execute(fftwPlan);
00294 fftw_destroy_plan(fftwPlan);
00295 mprintf("FFTInverse:: ComplexToReal double, elapsed time:%f\n",DTime(t0));
00296
00297 if(!overwriteSrc){delete psrc;}
00298 }