傅里叶变换

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

少将
图像的傅立叶变换,原始图像由N行N列构成,N必须是基2的,把这个N*N个包含图像的点称为实部,另外还需要N*N个点称为虚部,因为FFT是基于复数的,如下图所示:
(//实数DFT将时域内的N个点变换为频域中两组各N/2+1个点(分别对应实部和虚部))
计算图像傅立叶变换的过程很简单:首先对每一行做一维FFT,然后对每一列做一维FFT。

具体来说,先对第0行的N个点做FFT(实部有值,虚部为0),将FFT输出的实部放回原来第0行的实部,FFT输出的虚部放回第0行的虚部,这样计算完全部行之后,图像的实部和虚部包含的是中间数据,然后用相同的办法进行列方向上的FFT变换,这样N*N的图像经过FFT得到一个N*N的频谱。

下面展示了一副图像的二维FFT变换:
频域中可以包含负值,图像中灰色表示0,黑色表示负值,白色表示正值。

可以看到4个角上的黑色更黑,白色更白,表示其幅度更大,其实4个角上的系数表示的是图像的低频组成部分,而中心则是图像的高频组成部分。

除此以外,FFT的系数显得杂乱无章,基本看不出什么。

将上述直角坐标转换为极坐标的形式,稍微比较容易理解一点,幅度中4个角上白色的区域表示幅度较大,而相位中高频和低频基本看不出什么区别来。

上述以一种不同的方法展示了图像频谱,它将低频部分平移到了频谱的中心(//MATLAB中实现函数fftshift)。

这个其实很好理解,因为经2D-FFT的信号是离散图像,其2D-FFT的输
出就是周期信号,也就是将前面一张图周期性平铺,取了一张以低频为中心的图。

将原点放在中心有很多好处,比如更加直观更符合周期性的原理,但在这节中还是以未平移之前的图来解释。

行N/2和列N/2将频域分成四块。

对实部和幅度来说,右上角和左下角成镜像关系,左上角和右下角也是镜像关系;对虚部和相位来说,也是类似的,只是符号要取反(//共轭?),这种对称性和1维傅立叶变换是类似的,你可以往前看看。

为简单起见,先考虑4*4的像素,右边是其灰度值,对这些灰度值进行2维fft变换。

h和k的范围在-N/2到N/2-1之间。

通常I(n,m)是实数,F(0,0)总是实数(//直流分量),并且F(h,k)具有对偶性。

如果写成复数形式,即:
-------------------------------------------------------------
图像傅立叶变换的物理意义
如果只保留靠近中心的幅度,则图像的细节丢失,但是不同区域还是有着不同灰度。

如果保留的是远离中心的幅度,则图像的细节可以看得出,但是不同区域的灰度都一样了。

考虑一个黑色矩形的傅立叶变换,这个黑色矩形的背景为白色。

如果对频域中垂直方向高频分量进行截断,则图像中黑白将不那么分明了,表现为振荡。

可以得出结论:
傅立叶变换系数靠近中心的描述的是图像中慢变化的特性,或者说灰度变换比较缓慢的特性(频率比较慢的部分);
傅立叶变换系数远离中心的描述的是图像中快变化的特性,或者说灰度变换比较剧烈的特性(频率比较快的部分)。

-------------------------------------------------------------
傅立叶变换相位所含的信息
有两幅图像,如果用第一幅图像傅立叶变换的幅度和第二幅图像傅立叶变换的相位做反变换得到的图像是什么样子的?
如果反过来,将第一幅图像的相位和第二幅图像的幅度做反变换得到的图像又是什么样子的?
这里再用1维傅立叶变换解释一下:
在1维傅立叶变换中,可以看到相位包含了边沿何时出现的信息!在图像的傅立叶变换中也一样,相位决定了图像的边沿,所以决定了图像中你看到物体的样子!
关于相位所含的信息,你可以这样理解:
边沿的形成是当很多正弦波上升沿都发生在同一时刻,也就是这些正弦波的相位是相同的时刻,所以相位所含的信息决定了边沿所发生的位置,而正是边沿决定了图像的样子。

这个就是图像信号和声音信号的一个区别,声音信号的信息多数都包含在其傅立叶变换的幅度中,即不同频率幅度的大小,就是说你听到什么声音取决于你听到什么样的频率的信号,而对于这些信号时什么时候发生的并不十分重要。

-------------------------------------------------------------
相关代码
///***************************************************************/
/*函数名称:QFC(CNumber* t,CNumber* f,int r)
参数: t、f分别是指向时域和频域的指针,r是2的幂数
/*函数类型:void
/*功能:此函数实现快速傅立叶变换
/***************************************************************///此函数用来实现
void ZhengJiaoBianHuanDib::QFC(CNumber* t,CNumber* f,int r)
{
long count;//傅立叶变换点数
int i,j,k,p,bfsize;
CNumber *w,*x,*a,*b;//复数结构类型的指针变量,其中w指向加权系数
double angle;//计算加权系数所用的角度值
count=1<<r;//计算傅立叶变换点数
//分配所需运算空间
w=new CNumber[count/2];
a=new CNumber[count];
b=new CNumber[count];
//计算加权系数
for(i=0;i<count/2;i++)
{
angle=-i*pi*2/count;
w[i].re=cos(angle);
w[i].im=sin(angle);
}
memcpy(a,t,sizeof(CNumber)*count);
//采用频率分解法进行蝶形运算
for(k=0;k<r;k++)
{
for(j=0;j<1<<k;j++)
{
bfsize=1<<(r-k);
for(i=0;i<bfsize/2;i++)
{
p=j*bfsize;
b[i+p]=Add(a[i+p],a[i+p+bfsize/2]);
b[i+p+bfsize/2]=Mul(Sub(a[i+p],a[i+p+bfsize/2]),w[i*(1<<k)]);
}
}
x=a;
a=b;
b=x;
}
//将乱序的变换序列重新排序
for(j=0;j<count;j++)
{
p=0;
for(i=0;i<r;i++)
{
if(j&(1<<i))
p+=1<<(r-i-1);
}
f[j]=a[p];
}
//释放存储器空间
delete w;
delete a;
delete b;
}
///////////////////////////////////////////////
//此函数用来实现图象的傅立叶变换
//两次调用快速傅立叶变换QFC()实现二维傅立叶变换
///////////////////////////////////////////////
void ZhengJiaoBianHuanDib::QuickFourier()
{
LPBYTE p_data, p;//指向原图象数据区指针
int width,height;//原图象的宽度和高度
long w=1,h=1;//进行傅立叶变换的宽度和高度(2的整数次方)
int wp=0,hp=0;//迭代次数
int i,j;
double temp;//中间变量
CNumber *t,*f;
p_data=this->GetData();//指向原图象数据区
width=this->GetWidth();//得到图象宽度
height=this->GetHeight();//得到图象高度
long lLineBytes=WIDTHBYTES(width*8);//计算图象每行的字节数while(w*2<=width)//计算进行傅立叶变换的宽度(2的整数次方){
w*=2;
wp++;
}
while(h*2<=height)//计算进行傅立叶变换的高度(2的整数次方){
h*=2;
hp++;
}
t=new CNumber[w*h];//分配存储器空间
f=new CNumber[w*h];
for(j=0;j<h;j++)
{
for(i=0;i<w;i++)
{
p=p_data+lLineBytes*(height-j-1)+i;//指向第j行第i列象素
t[i+w*j].re=*(p);//给时域赋值
t[i+w*j].im=0;
}
}
for(j=0;j<h;j++)//在垂直方向上进行快速傅立叶变换
{
QFC(&t[w*j],&f[w*j],wp);
}
for(j=0;j<h;j++)//转换变换结果
{
for(i=0;i<w;i++)
{
t[j+h*i]=f[i+w*j];
}
}
for(i=0;i<w;i++)//水平方向进行快速傅立叶变换
{
QFC(&t[i*h],&f[i*h],hp);
}
for(j=0;j<h;j++)
{
for(i=0;i<w;i++)
{
temp=sqrt(f[i*h+j].re*f[i*h+j].re+f[i*h+j].im*f[i*h+j].im)/100;
if(temp>255)
temp=255;
p=p_data+lLineBytes*(height-(j<h/2?j+h/2:j-h/2)-1)+
(i<w/2?i+w/2:i-w/2);//将变换后的原点移到中心
*(p)=(BYTE)(temp);
}
}
delete t;
delete f;
}。

相关文档
最新文档