二维图像的傅立叶变换

博客已搬家,下面的文章中的图片可能显示不正常,请移步新博客查看:https://imlogm.github.io/%E5%9B%BE%E5%83%8F%E5%A4%84%E7%90%86/image-fft/

摘要:二维图像的傅立叶变换,与一维傅立叶相比,在理解上要抽象很多。我在网上找了几篇相对较好的文章,并用matlab自己做了几个实验图像,希望能对大家理解二维图像的傅立叶变换有所帮助。

关键字:二维傅立叶变换,图像处理

1. 一维傅立叶变换

如果是理工科的话,一维傅立叶变换应该在大学里都学过。如果有所遗忘的话,可以看这篇比较易懂又不失数学性的文章“如何理解傅里叶变换公式?-马同学的回答”。

一维傅立叶变换的公式为:

F(ω)=+f(t)eiωtdt F ( ω ) = ∫ − ∞ + ∞ f ( t ) e − i ω t d t

2. 二维傅立叶变换

二维傅立叶变换的公式为:

F(u,v)=++f(x,y)ei(ux+vy)dxdy F ( u , v ) = ∫ − ∞ + ∞ ∫ − ∞ + ∞ f ( x , y ) e − i ( u x + v y ) d x d y

由一维傅立叶的公式,能比较容易类比得到二维傅立叶变换公式。但注意,二维傅立叶不是x方向与y方向正弦余弦的简单叠加,而是乘积的叠加。

比如:一维傅立叶变换的三角函数系是 sin(nx) s i n ( n x ) cos(nx) c o s ( n x ) 以及常数1,二维傅立叶变换的三角函数系是 sin(ux+vy) s i n ( u x + v y ) cos(ux+vy) c o s ( u x + v y ) 和常数1.而 sin(ux+vy) s i n ( u x + v y ) cos(ux+vy) c o s ( u x + v y ) 可以继续分解为 sin(ux)sin(vy),sin(ux)cos(vy),cos(ux)sin(vy),cos(ux)cos(vy) s i n ( u x ) s i n ( v y ) , s i n ( u x ) c o s ( v y ) , c o s ( u x ) s i n ( v y ) , c o s ( u x ) c o s ( v y ) 这四个乘积的形式。

如果对上面一段话的内容有兴趣的话,可以参看这篇文章“二维傅里叶变换是怎么进行的?-CharlyGordon的回答”。看不懂也没关系,只需要知道二维傅立叶不是x方向与y方向正弦余弦的简单叠加。

注意1:二维傅立叶变换后生成的图像与原图上的像素点不存在一一对应关系。原图中的像素值是x,y坐标轴下的(即空间域),而傅立叶变换后的像素值是u,v坐标轴下的(即频域)。

注意2:图像的像素点是离散且有限的,故实际进行图像傅立叶变换时,使用的是离散傅立叶变换(DFT),需要把上述公式中的积分号 + ∫ − ∞ + ∞ 换成求和号

3. 二维傅立叶变换的直观理解

原始图像经过二维傅立叶变换后得到的是u,v坐标系下的二维矩阵,由 (u1,v1) ( u 1 , v 1 ) (u1,v2) ( u 1 , v 2 ) (u2,v1) ( u 2 , v 1 ) 等一系列点组成。每个位置 (un,vn) ( u n , v n ) 都有其对应的值 F(un,vn) F ( u n , v n ) 。如果把这个二维矩阵归一化成傅立叶后的图像来显示,那么傅立叶后图像上像素点位置和像素点亮度就表征二维矩阵相应的点和该点的值。

如图1所示,有左中右三幅小图,我们先不管右小图,左小图是原始图像,中小图是傅立叶变换后的。可以看到傅立叶变换后的图片的两个斜对角出现了两个白点,这两点处的亮度值最大,其余点处亮度值为0。这表示原始图像可以由这两点所对应的三角波组成,三角波的幅值为其对应点的亮度。

图1

那么这些三角波长什么样子呢?图2是我从网上找到的一幅图,原始出处未知。原来这张图是频移后的三角波,由于频移是下面才讲到的知识点,我感觉这样会对理解造成一定影响,所以我处理成频移前的,便于大家理解。相信对比图1和图2,你们能很快理解其中的关系。

图2

在图2的右小图中,我用红框标出了其中的一个三角波,这个三角波的外形与图1的原始图像最相似。结果也和我们预料的一样,傅立叶变换后,这个三角波的幅值是最大的,所以我们看到了图1中小图左上角的白点。

注意:图2的三角波对应于图1中小图的左上角的区域,所以我们得到了左上角的白点。至于图1中小图的右上、左下、右下区域的三角波长什么样子,请看下面一段话。

看到这里可能大家还有个疑问:左上角的白点明白了,但是右下角的白点怎么来的?如果你自己动手做实验的话,会发现这两个白点是对称的(换而言之,右下角区域的三角波和左上角区域的三角波对称)。这其实是由两个原因共同作用造成的:其一,傅立叶双边频谱关于原点对称;其二,上面提到过,二维图像傅立叶变换是离散傅立叶变换,离散傅里叶变换本质是周期信号求傅里叶级数,所以其实会有周期延拓

因为这两个性质涉及一些更深的知识,我不详细展开了。有兴趣的同学可以找信号处理方面的书来看,学过的同学应该能马上理解。

解决了图1中左小图、中小图的问题,那么图1的右小图是什么呢?右小图其实是中小图经过频移后的。为什么要频移,因为我们把傅立叶变换得到的二维矩阵用图像的方式显示时,默认的坐标原点(0, 0)位于图像的左上角。频移要做的就是把坐标原点移动到图像的中心。

可以想到,图1右小图的中间偏右下的点是由图1左小图左上角的点经过移动后得到的,而图1右小图的中间偏左上的点是由之前提到的“傅立叶双边频谱关于原点对称”这条性质得到的。

4. Matlab小实验

看了上面的内容,相信大家都已经对二维傅立叶有了一定的直观印象。我又用matlab写了个小程序,生成了几幅图片,帮助大家理解。

图3
图4
图5
图6
图7
图8

5. Matlab代码

最后附上我的matlab代码,便于大家自己做实验。

如果对傅立叶变换的代码有什么疑问的话,可以看这篇文章“使用matlab对图像进行傅里叶变换-三山音”。

% 用sin(x+y)的图像来帮助理解二维图像的傅立叶变换

img_size = 100;     % 图片尺寸
x_step = 1;     
y_step = 1;
image = zeros(img_size, img_size);
for x = x_step:x_step:x_step*img_size
    for y=y_step:y_step:y_step*img_size
        image(x/x_step, y/y_step)=sin(4*pi*x/img_size + 4*pi*y/img_size);
    end
end


subplot(1,3,1)
imshow(image)       % 原图
title('原图')

subplot(1,3,2)
image = im2double(image);
F_unshift = fft2(image); 
F_unshift_abs = abs(F_unshift);
T = log(F_unshift_abs+1);
imshow(T);   % 傅立叶变换后,未频移前
title('傅立叶变换后,未频移')

subplot(1,3,3)
F = fftshift(F_unshift);
F_abs = abs(F);
T = log(F_abs+1);
imshow(T)           % 傅立叶变换后,频移后
title('傅立叶变换后,频移后')

你可能感兴趣的:(图像处理)