天天看点

python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)

python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)

时间为友,记录点滴。

这是对应《数字图像处理》第二章的最后一个例子,今天我们聊一聊傅里叶变换在数字图像处理领域中的应用。

作为一名工科生,即便早已经把什么傅里叶级数、DFT/FFT、变换/逆变换这些公式忘得一干二净了,但是提到傅里叶变换,总是不那么陌生。只要记得傅里叶变换是时域变频域,而且有对应的逆变换可以把频域变回时域,就这样,好像还差一点点。

下来,我们稍微深挖一下。

python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)

任意一个波形,都可以转换成N个频率单一的正弦波的叠加

  • 目的是啥:

可以把时域内的信号变换到频域中,更容易处理。

  • 怎么转换?

直接上公式,一般来说,大写的函数表达式代表了转换域。

python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)
  • 需要啥基础?

额,说实话,如果仅仅拿来用的话,复数域和欧拉公式还是要了解一下的。

复数域:

我们上小学的时候,只要知道有理数

python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)

就够了,可后来才知道原来还有负数这东西,怎么办?引入整数域

python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)

吧。可有人又发现了

python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)

无法用整数的加减乘除得到,我们再打个补丁,引入实数域

python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)

。那么既然补丁就是用来解决不可处理的无效问题的,那就把

python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)

也打打补丁呗。于是复数域

python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)

就出现了。先理解

python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)

=i,并且我们有复数平面。

python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)

4*i=4i; 4i*i=-4

理解了复平面对实数轴的补充后,我们要了解复数的两个概念

模和幅角

python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)

|z| 和 arg(z)

欧拉公式

欧拉大神可真是高产,都说欧拉公式是上帝公式。呵呵,那是你们理科生,我们计算机的工科生只认识图灵。

对于
python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)
,有
python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)
----维基百科

额,为什么?看图说话:

python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)

复数域中的A点是

python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)

可以理解,但为啥是

python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)

呢?那是你没看过e是怎么来的。

(怎么感觉扯远了?)e是一个最美的自然常数,他是有固定值的约等于2.71828, 听说就是当年雅各布·伯努利计算银行复利的时候发现的

python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)

,即当银行不断缩短付利息的时间,我们获得的复利是趋向于一个固定值2.71828,欧拉说,这个东西好啊,你就叫欧拉常数吧,我给你定义一个函数

python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)

于是(不能再讲泰勒公式了)

python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)
python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)
python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)

python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)

代入

python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)

可得:

python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)

完美!

好了,有这个基础,我们终于可以看傅里叶变换了。

(傅里叶理论部分大部分素材取自马同学高等数学, 高手!给他点个赞,希望他不会写代码)

傅里叶级数

好早之前,老数学家拉格朗日们发现一些周期函数可以由三角函数的和来表示,傅里叶站出来吹牛说:我认为

任意周期函数都可以写成三角函数之和

。大神的可怕之处就是所有吹过的牛,慢慢都实现了。于是傅里叶根据逻辑和公式找到了一堆级数序列限定周期为T的正弦和余弦三角函数,用来描述周期为T的任意波形。

python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)
python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)

不同频率三角波根据振幅an/bn叠加的过程

傅里叶变换(连续函数)

有了傅里叶级数就好办多了,这一堆的sin和cos函数多碍眼,我们不是有高斯公式吗?把他们都化到复数域上。

根据

python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)

, 把cos

python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)

和sin

python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)

代到傅里叶级数中,得到:

python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)

其中,

python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)

贴最终换算公式(表示工程人员千万别痴迷于自己公式推导,理解至上)

python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)

从此时域有了到频域的桥梁。

f(x) <=> F(X)

离散傅里叶变换(DFT)

如果把连续的f(x)的傅里叶变换找到了,那么离散的还远吗?忘了我们之前怎么把连续模拟信号变成离散信号了吗?采样呗。

如果定义FT为 (少个2π不影响表达):

python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)

那么DFT的公式就应该是:

python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)

公式总是简洁,那是因为我们用傅里叶级数的三角函数变换到了复数域,现在为了方便理解,我们再把DFT变回三角函数表达:

python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)

这样解释里面的内容

  • X(m):第m个DFT的输出。如X(0), X(1), ..., X(m)
  • m:频域DFT输出序列的指标。 m= 0, 1, 2, ...., N-1
  • x(n):输入样点序列。如x(0), x(1), ..., x(n)
  • n:时域输入样点序列指标。n=0, 1, 2, ..., N-1
  • i: 复数虚轴
  • N:输入序列和DFT输出序列的个数

所以:

输入N个采样点,DFT后也得到了N个等间距频点的输出值。N是一个重要参数。

令采样频率为

python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)
, 那么N个单点分析频率的表达式为f(m)=
python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)

介绍完了,收工。

啥?感觉怪怪的,这一堆冷冰冰的公式怎么跟实际联系起来呢?以DFT为例,我们想要把一个离散序列通过DFT后转换成N个单一频率的波形相加的形式,可以我们怎么来确定这N个谐波呢?我的意思是,如果我们定义一个单频波可以用正弦的形式表示:

python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)

我们要知道振幅(

python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)

)、相位(

python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)

)、频率(角速度

python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)

)才能完全确定这个谐波啊,这一堆公式,我要用代码如何表达呢?我们依次找一找:

python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)

取自《数字信号处理》一书

  • 振幅(
    python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)
    ):
    python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)
  • 相位(
    python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)
    ):
    python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)
  • 频率(角速度
    python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)
    ):f(m)=
    python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)

完美!

快速傅里叶变换(FFT)

至于FFT其实就是DFT的一种简化计算复杂度的快速傅里叶变换,它是根据离散傅氏变换的奇、偶、虚、实等特性,对离散傅立叶变换的算法进行改进获得的。在软件领域可以把复杂度降到又DFT的O(N*N)降到O(nlogn)(如果是二维图像应该是O( M*N*log(M*N) ))。

python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)

大概就是这样子

数字图像中的频谱

频率:对于图像来说就是指图像颜色值的梯度,即灰度级的变化速度

幅度:可以简单的理解为是频率的权,即该频率所占的比例

  1. 对于一个正弦信号,如果它的幅度变化很快,我们称之为高频信号,如果变化非常慢,我们称之为低频信号。迁移到图像中,图像哪里的幅度变化非常大呢?边界点或者噪声。所以我们说边界点和噪声是图像中的高频分量(这里的高频是指变化非常快,不是出现的次数多),图像的主要部分集中在低频分量。
  2. 由于图像变换的结果原点在边缘部分,不容易显示,所以将原点移动到中心部分。那么结果便是中间一个亮点朝着周围发散开来,越远离中心位置的能量越低(越暗)。
  3. 傅里叶转换的结果是复数,这也显示了傅里叶变换是一幅实数图像和虚数图像叠加或者是幅度图像和相位图像叠加的结果。
  4. 原图->DFT/FFT->中心化->频域显示(处理)->去中心化->IDFT/IFFT->原图

Python:

  1. 通过numpy的FFT模块,显示了FFT之后的频域的幅值和相位。
  2. 通过在频域特这,可以很容易设计低通/高通滤波器。
#!/usr/bin/env python
           

运行结果:

python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)

原图取自《数字图像处理》书中的例子;后面为频率和相位图

python傅里叶变换 信号处理 序列_(十六)数字图像处理中的傅里叶(DFT/FFT)

可以做一个高通/低通滤波器,做锐化和模糊(此处为降噪,因为干扰源是个高频信号)

继续阅读