「这是我参与2022首次更文挑战的第18天,活动详情查看:2022首次更文挑战」。
傅立叶变换,表示能将满足一定条件的某个函数表示成三角函数(正弦和/或余弦函数)或者它们的积分的线性组合。在不同的研究领域,傅立叶变换具有多种不同的变体形式,如连续傅立叶变换和离散傅立叶变换。本文梳理基本知识。
概述
Fourier transform或Transformée de Fourier有多个中文译名,常见的有“傅里叶变换”、“付立叶变换”、“傅立叶转换”、“傅氏转换”、“傅氏变换”、等等。
- 傅立叶变换是一种分析信号的方法,它可分析信号的成分,也可用这些成分合成信号。所谓信号,从狭义上说可以认为是自然界中作为信息载体的各类波,一般来说简谐震动产生的正弦波是最常见的研究对象。许多波形可作为信号的成分,比如正弦波、方波、锯齿波等,傅立叶变换用正弦波作为信号的成分。
- 对于自然界存在的所有波,我们可以利用所谓的傅立叶级数展开法将它们分解为有限或无限个不同频率不同振幅的正弦、余弦波的集合
定义
连续傅里叶变换
- 是的周期函数,如果满足狄里赫莱条件:在一个以 为周期内连续或只有有限个第一类间断点,附单调或可划分成有限个单调区间,则以为周期的傅里叶级数收敛,和函数也是以为周期的周期函数,且在这些间断点上,函数是有限值;在一个周期内具有有限个极值点;绝对可积。
- 则有下式成立,称为积分运算的傅立叶变换:
叫做 的象函数, 叫做 的象原函数。
是 的象, 是原象。
- 傅里叶变换可以通过逆变换将象函数变换为象原函数
其中叫做的象函数,叫做 的象原函数。 是 的象。 是 原象。
- 傅立叶逆变换
离散傅里叶变换
- 设 是一个长度为 的有限长序列,则定义 的 点离散傅里叶变换为
- 的离散傅里叶逆变换(Inverse Discrete Fourier Transform, IDFT)为
式中, 称为 变换区间长度, 通常称上述两式为离散傅里叶变换对。
为了叙述简洁,常常用 和 分别表示 点离散傅里叶变换和 点离散傅里叶逆变换。
相关概念
虽然讲了定义,相信没人能直接看懂,了解一些相关概念明白一下傅里叶变换是在干嘛。
时域
是描述数学函数或物理信号对时间的关系。例如一个信号的时域波形可以表达信号随着时间的变化。是真实世界,是惟一实际存在的域。因为我们的经历都是在时域中发展和验证的,已经习惯于事件按时间的先后顺序地发生。
频域
频域(frequency domain)是描述信号在频率方面特性时用到的一种坐标系。在电子学,控制系统工程和统计学中,频域图显示了在一个频率范围内每个给定频带内的信号量。频域,尤其在射频和通信系统中运用较多,在高速数字应用中也会遇到频域。频域最重要的性质是:它不是真实的,而是一个数学构造。时域是惟一客观存在的域,而频域是一个遵循特定规则的数学范畴,频域也被一些学者称为上帝视角。
时域频域的关系
时域分析与频域分析是对模拟信号的两个观察面。时域分析是以时间轴为坐标表示动态信号的关系;频域分析是把信号变为以频率轴为坐标表示出来。一般来说,时域的表示较为形象与直观,频域分析则更为简练,剖析问题更为深刻和方便。信号分析的趋势是从时域向频域发展。然而,它们是互相联系,缺一不可,相辅相成的。
- 傅里叶正变换和反变换,就是将信号在二者之间变换。
- 不同频率的正弦波相互正交,构成了频域空间上的基
- 傅里叶正变换就是当前的信号与所有频率不同相位的正弦信号计算点积,得到各个频率波上的分量,叠加构成当前的时域信号
实际应用
- 给出一幅图像,我们求出图像中圆形的周期和相位
- 将图像极坐标变换
- 叠加减去均值得到时域信号:
- 离散傅里叶变换,计算模长
-
其中能量最大的就是信号的周期 12,与实际相符
-
计算频率为12的相位,得到 -10.279644688897708,与实际相符
参考代码
import matplotlib.pyplot as plt
import cv2
import numpy as np
from scipy.fftpack import fft
if __name__ == '__main__':
image_path = 'test.png'
image = cv2.imread(image_path)
center = (np.array(image.shape[:2]) / 2).astype('int')[::-1].tolist()
assert center[0] == center[1]
radius = center[0]
size_x = 200
size_y = 200
output_img = cv2.warpPolar(image, (size_x, size_y), tuple(center), radius, 12)
output_img = output_img[:, :, 0]
signal = np.sum(output_img, axis=1)
signal = signal - signal.mean()
scipy_fft_y = fft(signal)
scipy_fft_y = scipy_fft_y[:len(scipy_fft_y)//2]
# energy_fft
abs_y = np.abs(scipy_fft_y)
# phase_fft
angle_y = np.angle(scipy_fft_y)
cycle_num = np.argmax(abs_y)
# cycle angle
cycle_angle = 360 / cycle_num
# phase
phase = cycle_angle / 2 / np.pi * angle_y[cycle_num]
print(f"周期 : {cycle_num}")
print(f"角度 : {cycle_angle}")
print(f"相位 : {phase}")
plt.plot(abs_y)
plt.show()
pass