00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00021 #include<ImLib3D/FFT.hpp>
00022 #include<ImLib3D/Convolution.hpp>
00023 #include<ImLib3D/Transformation.hpp>
00024 #include<ImLib3D/Arithmetic.hpp>
00025
00026 void
00027 IP3D::FFTLowPassFilterApodizedIdeal(const Image3Df& src,float cutoffFreq,Image3Df &res,float rolloffFactor)
00028 {
00029 Image3Dcomplexf fft;
00030 IP3D::FFT(src,fft,false);
00031 Vect3Di center=fft.SizeV()/2;
00032 center.x=0;
00033
00034 Vect3Df cutoff=cutoffFreq*.5*(Vect3Df)fft.SizeV();
00035 cutoff.x=cutoffFreq*fft.SizeV().x;
00036 cutoff.Show("cutoff:","\n");
00037 Vect3Df rolloff=cutoffFreq*rolloffFactor*(Vect3Df)cutoff;
00038 rolloff.Show("rolloff:","\n");
00039 for(Image3Dcomplexf::iteratorXYZ p=fft.begin();p!=fft.end();++p)
00040 {
00041 Vect3Di f=p.Pos();
00042 if((f.y+center.y)>=fft.Height()){f.y-=fft.Height();}
00043 if((f.z+center.z)>=fft.Depth ()){f.z-=fft.Depth();}
00044
00045 if(!rolloffFactor)
00046 {
00047 if(abs(f.x)>cutoff.x || abs(f.y)>cutoff.y || abs(f.z)>cutoff.z){*p=complexf(0);}
00048 }
00049 else
00050 {
00051 for(uint i=0;i<3;i++)
00052 {
00053 float u=(abs(f(i))-cutoff(i))/rolloff(i);
00054 if(u> 1){*p =complexf(0);break;}
00055 if(u>-1){double m=cos((1+u)*M_PI/4);*p*=complexf(m);}
00056 }
00057 }
00058 }
00059 IP3D::FFTInverse(fft,res,src.Width(),true);
00060 res*=1.0/res.GetNVoxels();
00061 }
00062
00063 void
00064 IP3D::FFTLowPassFilterButterworth(const Image3Df& src,float cutoffFreq,float order,Image3Df &res)
00065 {
00066 Image3Dcomplexf fft;
00067 IP3D::FFT(src,fft,false);
00068 Vect3Di center=fft.SizeV()/2;
00069 center.x=0;
00070 for(Image3Dcomplexf::iteratorXYZ p=fft.begin();p!=fft.end();++p)
00071 {
00072 Vect3Df f=p.Pos();
00073 if((f.y+center.y)>=fft.Height()){f.y-=fft.Height();}
00074 if((f.z+center.z)>=fft.Depth ()){f.z-=fft.Depth();}
00075 f.x/= fft.Width();
00076 f.y/=.5*fft.Height();
00077 f.z/=.5*fft.Depth();
00078 float r=f.Norm();
00079 (*p)*=1/(1+pow(r/cutoffFreq,2*order));
00080 }
00081 IP3D::FFTInverse(fft,res,src.Width(),true);
00082 res*=1.0/res.GetNVoxels();
00083 }
00084
00085 void
00086 IP3D::FFTLowPassFilterChebyscheff(const Image3Df& src,float cutoffFreq,float order,Image3Df &res)
00087 {
00088 Image3Dcomplexf fft;
00089 IP3D::FFT(src,fft,false);
00090 Vect3Di center=fft.SizeV()/2;
00091 center.x=0;
00092 for(Image3Dcomplexf::iteratorXYZ p=fft.begin();p!=fft.end();++p)
00093 {
00094 Vect3Df f=p.Pos();
00095 if((f.y+center.y)>=fft.Height()){f.y-=fft.Height();}
00096 if((f.z+center.z)>=fft.Depth ()){f.z-=fft.Depth();}
00097 f.x/= fft.Width();
00098 f.y/=.5*fft.Height();
00099 f.z/=.5*fft.Depth();
00100 float w=f.Norm()/cutoffFreq;
00101 float t;
00102 if(w<1){t=cos (order*acos (w));}
00103 else{ t=cosh(order*acosh(w));}
00104 (*p)*=1/(1+t*t);
00105 }
00106 IP3D::FFTInverse(fft,res,src.Width(),true);
00107 res*=1.0/res.GetNVoxels();
00108 }
00109