知识点:重点讲解正弦函数和欧拉公式的关系,以及它们在傅里叶变换中的作用,附加:傅里叶变换和卷积公式
这是我第二次学习傅里叶变换,其实第一次就已经懂了时域和频域的关系,也知道一维傅里叶变换就是将一个函数转化为很多频率不同的正弦函数的和,二维图片傅里叶中的频率指的是图像中像素的梯度。频率高的代表图像的变换,频率低表示图像温和。
但是我还是不会自己编写代码,最让我不理解的就是为什么DFT的求解方程式就是 Xk=∑N−1n=0xn e−i 2π k n/N ,IDFT就是 xn=1N∑N−1k=0Xk ei 2π k n/N ??而且说好的正弦函数作为基呢!引入 e−it 是个什么鬼??而且当我输入的原函数f是正弦函数是,DFT分解后,并不是我想想中的,对应频率的正弦函数是一个振幅1,而其余频率的正弦函数函数振幅是0的结果??而且还有就是图像的频率, 一维傅里叶变换中,很多资料都给出一个函数具体怎么由其它基函数(正弦函数)组成的,每一个基长什么样子都可以看到,可是当讲到二维图像的时候,从来没人画出二维图像的基函数的图像??
下面是关于傅里叶一些资料,本文重点不是讲解傅里叶的直观上原理,而是帮助理解如何编程DFT。
傅里叶:
http://blog.jobbole.com/70549/
http://www.xuebuyuan.com/2052774.html
https://wenku.baidu.com/view/9687303f10661ed9ad51f3b6.html
快速傅里叶:
http://www.cnblogs.com/callback-w/p/4457507.html
https://www.zhihu.com/question/20456490
http://blog.jobbole.com/58246/
图像傅里叶:
http://homepages.inf.ed.ac.uk/rbf/CVonline/LOCAL_COPIES/OWENS/LECT4/node2.html
http://cns-alumni.bu.edu/~slehar/fourier/fourier.html#filtering
http://blog.csdn.net/abcjennifer/article/details/7622228
http://blog.163.com/zwg_1314@126/blog/static/35333246201041113154728/
一,正弦函数
这里说的正弦函数是指一类函数,就像
3x
和
(12)x
和
ex
都是指数函数、
log2x
和
logex
都是对数函数一样,只要符合
f(x)=Asin(Bx+C)
形式的函数都是正弦函数,其中
A
表示振幅,
asin(x)+bcos(x)=a2+b2−−−−−−√sin(x+y)
,其中
tan(y)=ba
。也是一种正弦函数。
正弦函数的一个理解就是一个点围绕原点做圆周运动,它的y轴分量的时候岁时间变化的曲线,如下图所示,这里和上面的公式对应有三个要素,就是振幅
A
对应圆周半径,周期
也就是确定了圆周运动的三要素后,对任给x,正弦函数给出,对应x时刻的点的y轴的坐标值。
二,欧拉公式
欧拉公式的推导过程大致如下:
将 ex 中的 x 换成
如果非要理解 e 的
https://betterexplained.com/articles/intuitive-understanding-of-eulers-formula/
我之前一直看不懂欧拉公式,不明白这是什么意思,我觉得最关键的错误就是试图去理解
e
的
三,正弦函数和欧拉公式
我的理解是正弦函数和欧拉公式都是在描述圆周运动。前面讲过一个圆周运动有三个要素:半径、角速度和初始位置。这都很容易对应到正弦函数,而欧拉公式也是可以。我们这里说的欧拉公式为:
fEuler(x)=Aei(Bx+C)=Acos(Bx+C)+iAsin(Bx+C)
。注意
Aei(Bx+C)
和
ei(Bx+C)+a
和
ea∗ei(Bx+C)
是一样的,因为总可以找到
a
来使得
欧拉公式也是在描述一种特定的圆周运动,而欧拉公式的返回值是x时刻的点的位置,用复数来表示,不同于正弦函数(它返回的是x时刻的点的有坐标值)。从描述圆周运动的角度,它们是一致的,它们都是根据时间x返回圆周运动上的点的一个指标上的值。复数和实数都是数,更或者说是信息的一种编码形式。欧拉公式返回的复数的实部表示点在x轴的坐标值,虚部表示点在y轴上的坐标值。
上图是wikipedia上关于欧拉公式的图,不过我修改了些部分。图中绿色线所标注的x轴,像时间在流失一样,一直往前走。y和z组成了一个平面空间,点就在这个平面空间上转动。欧拉公式中的自变量x是对应x轴上的时间点。欧拉公式返回的复数结果,对应点在yz平面上的坐标。随着自变量x的增大,点的移动轨迹就像红色的线所标注的一样,围绕x轴做螺旋圆周运动,如果映射到yz平面上就是做圆周运动。欧拉公式和正弦函数都是在描述这样一种运动,或者说映射规律,只不过欧拉公式根据x,输出的是点映射到yz平面上的坐标,用复数的形式来表示。而正弦函数将红色的点的运动轨迹映射到y轴上,如图中紫色的线所示,因为x轴信息已知,只需要输出y轴坐标即可。
欧拉函数的一个优点是,正弦函数一个周期内会输出重复的函数值,而欧拉公式在一个周期内不会输出重复的函数值。
总结一下,正弦函数和欧拉公式都是描述圆周运动随时间x变化的性质,都是一种映射,都是一种函数。欧拉公式更像是正弦函数的加强版,因为它返回了更多的信息。不要在意返回的是实数还是复数,因为都是数,都有完备的加减乘数运算。最原始的欧拉公式 eix 是在描述半径为1,周期为 2π ,初始点在 x 正半轴上的圆周运动。
最后说一下欧拉公式的编程实现。因为上面已知在强调欧拉公式就是一种映射,返回的是一个复数而已,而复数的实部和虚部的计算方式都给出来了,只要不在意
import numpy as np
def my_exp(x):
if x is complex:
res_real = np.exp(x.real)
res_imaginary = ( np.cos(x.imag) + 1j*np.sin(x.imag) )
return res_real * res_imaginary
else:
return np.exp(x)
x = 0.5
print np.exp(1+1j*x),my_exp(1+1j*x)
print np.exp(1+1j*x)==my_exp(1+1j*x)
最后再说下正弦函数和欧拉公式的正交性。
频率不相同的两个三角函数相乘,在它们两个共同的周期上积分为0。
因为频率不同,所以 |B1| != |B2| ,所以 cos[(B1−B2)x+(C1−C2)]和cos[(B1+B2)x+(C1+C2) 都是余弦函数,所以在它们共同的周期上进行积分,值为0。
离散的情况,当在它们共同周期内等间隔均匀采样的离散值求和也为0,例如:
对于欧拉公式也是一样的 fEuler(x)=Aei(Bx+C)=Acos(Bx+C)+iAsin(Bx+C) 。
同样的,只要 B1!=−B2 ,这一点和正弦函数不一样,那么 y(x) 在共同的周期内积分为0,离散的情况也一样。
同时我们可以看到,正余弦函数复杂的乘法运算,可以用简单的指数乘积来替代,它们的结果是一样的。
四,DFT编程的理解
很多文章都是从频域和正余弦函数来讲解傅里叶变换,可是DFT的编程公式里面偏偏出现了一个欧拉公式,让我费解好久。DFT: Xk=∑N−1n=0xn e−i 2π k n/N ,IDFT: xn=1N∑N−1k=0Xk ei 2π k n/N 。
这里假设需要进行离散傅里叶变换的信号是
X=(x0,x1,x2,x3)
,其DFT后的值为
Y=(y0,y1,y2,y3)
。从DFT和IDFT的公式中可以看出,就是向量内积的运算。
其中 {2πn/4} 表示欧拉公式的参数, fEuler_{2πn/4}(x)=ei(2πn/4)×x ,也即圆周运动的周期频率信息。所以很多资料才一直说的是域向频域的转换。下面写成矩阵的形式:
M−2π/4
和
M2π/4
分别描述的是振幅相同、相位相同、转速相同、但旋转方向相反的两种圆周运动。根据上一节欧拉公式的正交性可以容易计算出
M−2π/4×M2π/4=M2π/4×M−2π/4=4∗I
,如下所示:
其中 f{B}(0)∗f{−B}(0)=1 , f{B}(1)∗f{−B}(1)=1 , f{B}(2)∗f{−B}(2)=1 , f{B}(3)∗f{−B}(3)=1 , B可以是2π0/4 , 2π1/4 , 2π2/4 , 2π3/4 。
也就是说 M−2π/4和M2π/4/4 互为逆矩阵。
最初我们希望
X
可以分解为多个频域的向量相加,也就是
矩阵可以看做是一种变换器,乘以一个矩阵相当于对数据进行对应的变换。我们首先用矩阵
M−2π/N
对
X
进行转变得到
由
X=(1/N)M2π/N⋅Y
可知,我们选取频率的基向量
M2π/N=[f{2π∗1/N},f{2π∗2/N},⋯,f{2π∗(N−1)/N}]
来分解
X
。为什么选取
# 当然实际生活中用到的是快速傅里叶变换FFT
def my_DFT(x):
'一维离散傅里叶变换'
x = np.asarray(x,dtype=complex)
N = x.shape[0]
n = np.arange(N)
k = n.reshape((N,1))
M = np.exp(-2j*np.pi*k*n/N)
return np.dot(M,x)
def my_IDFT(y):
'一维逆离散傅里叶变换'
y = np.asarray(y,dtype=complex)
N = y.shape[0]
n = np.arange(N)
k = n.reshape((N,1))
M = np.exp(2j*np.pi*k*n/N)
print M
return np.dot(M,y)/N
简单的例子
X=(1/4)M2π/4⋅Y
如下:
总结一下,我们现在知道,随便一个可逆方阵都可以先用矩阵M进性正变换Y=MX,然后再用逆矩阵M进行逆变换得到原来的值X=MY=MMX=X。至于为什么选择的是欧拉函数作为频域的基向量: 第一点肯定是矩阵M和其逆矩阵都非常容易计算,从代码中可以看到,任给定N,都可以给出M和逆M。第二点,如果你同意用正弦函数作为频域的基向量的话,那你就更没办法拒绝欧拉函数作为基向量了,因为之前已经说了,欧拉函数是正弦函数的加强版,包含更多信息,正弦函数有的优点,它都有。或许还有其它原因。比如或许并不是任意一个可逆方阵都能够被当做频域信息。还有就是,正弦波作为基向量对应的矩阵是实可逆矩阵,而欧拉函数作为基向量对应的矩阵是复可逆矩阵,本质上没有区别,因为都满足基本的运算规则,加减乘除、一元、零元之类的。
五,2维 傅里叶 图像傅里叶
先推荐良心教材:
http://fourier.eng.hmc.edu/e101/lectures/Image_Processing/node6.html
http://fourier.eng.hmc.edu/e101/lectures/Image_Processing/Image_Processing.html
我是看了上面的的文章才懂了图像频率的含义,也真正知道了傅里叶变换后图像中点的含义,这里我做一个知识的搬运工。
(待续)
(草稿:)
先理解z=sin(x),理解z=Asin(Bx+C),在理解z=Asin(B(x+y)+C),再理解z=Ae^{j[Bx+C]},再理解z=Ae^{j[B(x+y)+C]}。
也要区别,为什么二维不能直接转为一维的来处理,它们之间的差别是什么。我想就像上面说的一样,不同的矩阵,理解为不同的视角,但有些矩阵,真的可能不能被解读为频域信息,所以矩阵的选择,和视角选择很重要。。。还有就是,正弦波作为基向量对应的矩阵是实可逆矩阵,而欧拉函数作为基向量对应的矩阵是复可逆矩阵,本质上没有区别,因为都满足基本的运算规则,加减乘除、一元、零元之类的。
六,傅里叶变换和卷积公式
卷积公式:
y(x)=∫+∞−∞f(α)g(x−α) dα=f(x)∗g(x)
如果两个函数的卷积的傅里叶变换等于两个函数的傅里叶变换的乘积,如下。
所以一些卷积运算可以先傅里叶运算,再乘积,再逆傅里叶运算即可,来降低运算复杂度。卷积运算复杂度为 n2 ,而两次快速傅里叶(FFT)是 2∗nlogn ,加上乘积运算 n ,最终是
上面的公式有点乱,注意的是卷积 y(x) 返回的是一个标量,而 F[y(x)] 返回的是向量,而在推理的过程中一直用的是标量,不过关系不大,除了推理公式的头和尾,其它没有什么问题。
卷积可以参考:
https://www.zhihu.com/question/22298352
我的另一篇关于傅里叶的杂乱的博客:
http://blog.sina.com.cn/s/blog_1541b2bcf0102x7pi.html