python fft库有哪些_Python图像处理库PIL中快速傅里叶变换FFT的实现(一)
离散傅里叶变换(discrete Fouriertransform)傅里叶分析方法是信号分析的最基本方法,傅里叶变换是傅里叶分析的核心,通过它把信号从时间域变换到频率域,进而研究信号的频谱结构和变化规律。FFT是一种DFT的高效算法,称为快速傅立叶变换(fastFourier
transform)。
在数字图像处理中,FFT的使用非常普遍,是图像处理中最重要的算法之一。在此,我们对FFT算法做一些简单研究,并使用python实现该算法,同时会对图像进行变换分析。
一、FFT算法的原理
FFT算法可分为按时间抽取算法和按频率抽取算法,我们可以从DFT的运算,来FFT的基本原理。
DFT的计算公式如下:
式中
在这两个求和公式中,可以认为x(n)和都是复数,两个复数乘法中,涉及4个乘法和3个加(减)法;再加上累加时的加法,对于每个K值,需要进行4N次实数相乘和(4N-1)次相加。对于N个k值,共需4N*N乘和N(4N-1)次实数相加。如果按照复数来计算的话,对于一个N长的序列,直接计算DFT需要N2次复数乘法以及N(N-1)=N2次复数加法。
由于DFT中的运算量非常大,需要改进DFT算法来减小它的运算量。对于DFT的改进,可以利用DFT中
的周期性和对称性,使整个DFT的计算变成一系列迭代运算,可大幅度提高运算过程和运算量,这就是FFT的基本思想。
FFT基本上可分为两类,时间抽取法和频率抽取法,而一般的时间抽取法和频率抽取法只能处理长度N=2M的情况,另外还有组合数基四FFT来处理一般长度的FFT。常用的FFT是以2为基数,其长度为N=2L。当要变换的序列长度不等于2的整数次方时,是为了使用以2为基数的FFT,可以用末位补零的方法,使其长度延长至2的整数次方。
本文将只对FFT的时间抽取法进行介绍并编程实现。
二、FFT的时间抽取法
设N点序列x(n),
,将x(n)按奇偶分组,公式如下图
改写为:
一个N点DFT分解为两个N/2点的DFT,
再对N/2阶的DFT做类似运算,在N为2的幂的情况下,最终可以分解成N/2个2阶的DFT运算。比较原先的DFT运算次数和后面的运算次数,原先的N阶DFT需要N2个复数乘法和加法,后面FFT需要Nlog2N个复数乘法和加法,使用简化蝶形计算更可以减少
个复数乘法。
按时间抽取,将8点DFT计算完全分解的图示如下:
使用蝶形计算8点DFT的图示如下:
三、FFT时间抽取法的实现
1、输入数据倒序
从上图可以看出,蝶形运算可以节省内存。整个计算分为三列,每列计算中的蝶形运算仅影响本蝶形运算的结果,我们可以在每次蝶形运算之后将运算结果存入原存储器中,这样仅需要一列长为N的存储器即可。
运算完毕后,序列A(1)、A(2),…,A(8),正好对应着最终输出的X(0),X(1),X(2),…,X(7),可以直接按顺序输出。但蝶形运算的输入x(0),x(1),x(2),…,x(7)却不能按照自然顺序存入存储器,而是按照x(0),x(4),x(2),x(6),…,x(7)的顺序存入存储单元。这种顺序看起来相当杂乱,然而它也是有规律的。当用二进制表示这个顺序时,它正好是“码位倒置”的顺序。
如果序列A(1)、A(2),…,A(8)按照数组方式表示A[8],其与蝶形运算的输入x[8]之间的关系可以表示为:
A[0]= A[000] = x[000] = x[0]
A[1]= A[001] = x[100] = x[4]
A[2]= A[010] = x[010] = x[2]
A[3]= A[011] = x[110] = x[6]
A[4]= A[100] = x[001] = x[1]
A[5]= A[101] = x[101] = x[5]
A[6]= A[110] = x[011] = x[3]
A[7]= A[111] = x[111] = x[7]
2、蝶形运算
蝶形运算是FFT中最基本的运算单元,在FFT程序设计中要找到蝶形运算地址与第几次迭代,第几组之间的关系。
根据FFT算法的特点,需要设置3个for循环的嵌套循环分别表示迭代、分组和蝶形运算,经过总结得出蝶形运算地址与迭代序号、分组序号间的关系如下:
上式种A-1表示前一次迭代运算的结果,i表示迭代序号,j表示分组序号,k表示蝶形运算序号。
对于旋转因子
,根据欧拉公式
可以得出WN的变形公式:
WN=cos(2pi/N)– isin(2pi/N)
四、1D FFT的编程实现
使用上述FFT算法,我使用python语言实现了一维FFT变换。具体的code如下:
import math
#define PI 3.1415
#复数类
class complex:
def __init__(self):
self.real = 0.0
self.image = 0.0
#复数乘法
def mul_ee(complex0, complex1):
complex_ret = complex()
complex_ret.real = complex0.real * complex1.real - complex0.image * complex1.image
complex_ret.image = complex0.real * complex1.image + complex0.image * complex1.real
return complex_ret
#复数加法
def add_ee(complex0, complex1):
complex_ret = complex()
complex_ret.real = complex0.real + complex1.real
complex_ret.image = complex0.image + complex1.image
return complex_ret
#复数减法
def sub_ee(complex0, complex1):
complex_ret = complex()
complex_ret.real = complex0.real - complex1.real
complex_ret.image = complex0.image - complex1.image
return complex_ret
#对输入数据进行倒序排列
def forward_input_data(input_data, num):
j = num / 2
for i in range(1, num - 2):
if(i < j):
complex_tmp = input_data[i]
input_data[i] = input_data[j]
input_data[j] = complex_tmp
print "forward x[%d] <==> x[%d]" % (i, j)
k = num / 2
while (j >= k):
j = j - k
k = k / 2
j = j + k
#实现1D FFT
def fft_1d(in_data, num):
PI = 3.1415926
forward_input_data(in_data, num) #倒序输入数据
#计算蝶形级数,也就是迭代次数
M = 1 #num = 2^m
tmp = num / 2;
while (tmp != 1):
M = M + 1
tmp = tmp / 2
print "FFT level:%d" % M
complex_ret = complex()
for L in range(1, M + 1):
B = int(math.pow(2, L -1)) #B为指数函数返回值,为float,需要转换integer
for J in range(0, B):
P = math.pow(2, M - L) * J
for K in range(J, num, int(math.pow(2, L))):
print "L:%d B:%d, J:%d, K:%d, P:%f" % (L, B, J, K, P)
complex_ret.real = math.cos((2 * PI / num) * P)
complex_ret.image = -math.sin((2 * PI / num) * P)
complex_mul = mul_ee(complex_ret, in_data[K + B])
complex_add = add_ee(in_data[K], complex_mul)
complex_sub = sub_ee(in_data[K], complex_mul)
in_data[K] = complex_add
in_data[K + B] = complex_sub
print "A[%d] real: %f, image: %f" % (K, in_data[K].real, in_data[K].image)
print "A[%d] real: %f, image: %f" % (K + B, in_data[K + B].real, in_data[K + B].image)
def test_fft_1d():
in_data = [2,3,4,5,7,9,10,11] #待测试的8点元素
#变量data为长度为8、元素为complex类实例的list,用于存储输入数据
data = [(complex()) for i in range(len(in_data))]
#将8个测试点转换为complex类的形式,存储在变量data中
for i in range(len(in_data)):
data[i].real = in_data[i]
data[i].image = 0.0
#输出FFT需要处理的数据
print "The input data:"
for i in range(len(in_data)):
print "x[%d] real: %f, image: %f" % (i, data[i].real, data[i].image)
fft_1d(data, 8)
#输出经过FFT处理后的结果
print "The output data:"
for i in range(len(in_data)):
print "X[%d] real: %f, image: %f" % (i, data[i].real, data[i].image)
#test the 1d fft
test_fft_1d()
运行该程序后,其输出如下:
The input data:
x[0] real: 2.000000, image: 0.000000
x[1] real: 3.000000, image: 0.000000
x[2] real: 4.000000, image: 0.000000
x[3] real: 5.000000, image: 0.000000
x[4] real: 7.000000, image: 0.000000
x[5] real: 9.000000, image: 0.000000
x[6] real: 10.000000, image: 0.000000
x[7] real: 11.000000, image: 0.000000
forward x[1] <==> x[4]
forward x[3] <==> x[6]
FFT level:3
L:1 B:1, J:0, K:0, P:0.000000
A[0] real: 9.000000, image: 0.000000
A[1] real: -5.000000, image: 0.000000
L:1 B:1, J:0, K:2, P:0.000000
A[2] real: 14.000000, image: 0.000000
A[3] real: -6.000000, image: 0.000000
L:1 B:1, J:0, K:4, P:0.000000
A[4] real: 12.000000, image: 0.000000
A[5] real: -6.000000, image: 0.000000
L:1 B:1, J:0, K:6, P:0.000000
A[6] real: 16.000000, image: 0.000000
A[7] real: -6.000000, image: 0.000000
L:2 B:2, J:0, K:0, P:0.000000
A[0] real: 23.000000, image: 0.000000
A[2] real: -5.000000, image: 0.000000
L:2 B:2, J:0, K:4, P:0.000000
A[4] real: 28.000000, image: 0.000000
A[6] real: -4.000000, image: 0.000000
L:2 B:2, J:1, K:1, P:2.000000
A[1] real: -5.000000, image: 6.000000
A[3] real: -5.000000, image: -6.000000
L:2 B:2, J:1, K:5, P:2.000000
A[5] real: -6.000000, image: 6.000000
A[7] real: -6.000000, image: -6.000000
L:3 B:4, J:0, K:0, P:0.000000
A[0] real: 51.000000, image: 0.000000
A[4] real: -5.000000, image: 0.000000
L:3 B:4, J:1, K:1, P:1.000000
A[1] real: -5.000000, image: 14.485281
A[5] real: -5.000000, image: -2.485281
L:3 B:4, J:2, K:2, P:2.000000
A[2] real: -5.000000, image: 4.000000
A[6] real: -5.000000, image: -4.000000
L:3 B:4, J:3, K:3, P:3.000000
A[3] real: -5.000000, image: 2.485281
A[7] real: -4.999999, image: -14.485281
The output data:
X[0] real: 51.000000, image: 0.000000
X[1] real: -5.000000, image: 14.485281
X[2] real: -5.000000, image: 4.000000
X[3] real: -5.000000, image: 2.485281
X[4] real: -5.000000, image: 0.000000
X[5] real: -5.000000, image: -2.485281
X[6] real: -5.000000, image: -4.000000
X[7] real: -4.999999, image: -14.485281
经过确认,输出X[]是符合预期的。
(未完待续)
原文:http://blog.csdn.net/icamera0/article/details/50985165
相关文章:

转: Android ListView 滑动背景为黑色的解决办法
2019独角兽企业重金招聘Python工程师标准>>> 在Android中,ListView是最常用的一个控件,在做UI设计的时候,很多人希望能够改变一下它的背景,使他能够符合整体的UI设计,改变背景背很简单只需要准备一张图片然…

BZOJ1901Zju2112 Dynamic Rankings——树状数组套主席树
题目描述 给定一个含有n个数的序列a[1],a[2],a[3]……a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i1],a[i2]……a[j]中第k小的数是多少(1≤k≤j-i1),并且,你可以改变一些a[i]的值,改变后&#…
Git与github基本操作
一. git安装与简单配置 1. git的安装 首先进入git的官方网站git-scm.com 下载自己电脑对应的git版本,然后点击安装即可 点击上图的红色部分进行下载 安装的时候直接默认即可 找到你的Git安装位置,把快捷方式中的git bash发送到桌面࿰…

容器 root权限运行_【漏洞通告】Containerd容器逃逸漏洞通告 (CVE202015257)
2020年12月1日,Containerd发布更新,修复了一个可造成容器逃逸的漏洞CVE-2020-15257,并公开了相关说明。通过受影响的API接口,攻击者可以利用该漏洞以root权限执行代码,实现容器逃逸。深信服安全研究团队依据漏洞重要性…

IOS成长之路-NSMutableURLRequest实现Post请求
NSData *bodyData [[bodyString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]dataUsingEncoding:NSUTF8StringEncoding];//把bodyString转换为NSData数据 NSURL *serverUrl [[NSURL URLWithString:RequestUrl] URLByAppendingPathComponent:urlStr];//获…

rsync ssh文件同步
参考链接 下载 manual #rsync -avP -e ssh ./filename root192.68.1.38:/root/paths/ (本地到远程) #rsync -avP -e ssh root192.68.1.38:/root/paths/test.tar.gz /root /paths (远程到本地) rsync -av --progress --inpl…
【转】Linux思维导图
【原文】https://www.toutiao.com/i6591690511763898888/ 1、Linux学习路径: 2、Linux桌面介绍: 3、FHS(文件系统目录标准): 4、Linux需要特别注意的目录: 5、Linux 内核学习路线: 6、Linux Security Coaching…
Python中lxml库的安装(Windows平台)
之前写过《Python中requests包的安装》,今天我需要安装lxml库,这里我尝试之前安装requests方式,但是没有成功,几经周折,终于总结出来了一个方法,这里拿出来给大家分享。 首先就是自己的电脑已经安装好了Py…

hadoop fs命令无法使用_「大数据」「Hadoop」HDFS的配置与管理
HDFS(Hadoop Distributed File System)是Hadoop三个基础组件之一,为另外的组件以及大数据生态中的其他组件提供了最基本的存储功能,具有高容错、高可靠、可扩展、高吞吐率等特点。HDFS运行在java环境中,因此我们都需要安装JDK。安装完成之后是…

Oracle 触发器 Update 不能操作本表的疑问
今天要解决一个需求,类似表A有个字段叫flag存储的是0 or 1 ,当一行记录更改为1的时候,其他行同字段要变为0。 这样的需求第一个思路想尝试下能否用触发器来实现 create or replace trigger tr_equiptreeweatherstation before UPDATE ON con…

前景检测算法_3(GMM)
摘要 本文通过opencv来实现一种前景检测算法——GMM,算法采用的思想来自论文[1][2][4]。在进行前景检测前,先对背景进行训练,对图像中每个背景采用一个混合高斯模型进行模拟,每个背景的混合高斯的个数可以自适应。然后在测试阶段&…

ADO.Net五个对象
Connection Command DataAdapter DataSet DataReader 取5个单词的首字母CCDDD,在拼音输入法里面打一下,出来5个字,然后就记忆为曹操打豆豆。 制作了一张图片,用来帮助记忆曹操打豆豆。 Reference ADO.NET的五大对象转载于:ht…
XPath与多线程爬虫
一. Xpath的介绍与配置 1. XPath是什么 XPath是一门语言 XPath可以在XML文档中查找信息 XPath支持HTML XPath通过元素和属性进行导航 总结: XPath可以用来提取信息(和正则表达式类似) XPath比正则表达式更加厉害 XPath比正则表…

html无序列表空心圆_列表样式的使用CSS入门基础(018)
今天我们分享关于列表样式的内容。列表项list-sytle-type:在HTML学习中,我们知道有有序列表和无序列表,都是使用type属性来定义的。1、有序列表有序列表 有序列表 有序列表 属性值type:1,数字1、2、3……;…

2013年3月百度之星B题
Sigma Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other) Problem Description 小H是一个程序员。他很喜欢做各种各样的数学题,尤其喜欢做《水泥数学》。 在看了《水泥数学》的2.5章后,小H终于会用9种计算 1^22^2...n^…

TCP/IP 10.1集成IS-IS协议
樱桃小小的 软软的甜甜的好吃哈!感谢上帝 , 恩呢 , 让我吃的这么满足,开心!第十章 集成IS-IS协议建议在学习ISIS的时候联系2个<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office"…

运维基础-文件权限管理
Linux是一个多用户操作系统,在多用户操作系统上我们需要一种方法来允许或者拒绝访问特定的文件和目录。文件有所属人和相关的单个组。我们可以设置所属人或者租的权限,以及所有其他人的权限。 文件只具有三个应用权限的用户类别。文件的所有者࿰…

android帧动画实现方法之一
好多动画离不开帧动画的使用,下面就实现帧动画的制作方式之一,以后会推出其他方法。 上面是文件存放位置。 a.xml文件的代码如下: <?xml version"1.0" encoding"utf-8"?> <animation-list xmlns:android"…

python技术晨讲_python系列教程14
声明:在人工智能技术教学期间,不少学生向我提一些python相关的问题,所以为了让同学们掌握更多扩展知识更好的理解人工智能技术,我让助理负责分享这套python系列教程,希望能帮到大家!好了,是开始…

三字母词和转义字符
1. 三字母词 在C语言中有一种三字母词的说法,trigraph sequences,目前为止有九种三字母词,如下 ?? # ??) ] ??! | ??( [ …

写了个Python脚本监控nginx进程
写了个Python脚本监控nginx进程 Xiaoxia[PG]写了个Python脚本监控nginx进程接上一文用iptables让SSH服务对陌生人说不。还是有点担心这个学期内,nginx可能会因为系统各种原因而出现异常退出,导致Web服务暂停。所以,又来了一个方案。view pla…

Linux shell 脚本报错:/bin/bash^M: bad interpreter: No such file or directory
今天遇到一个很诡异的问题,一直运行很正常的shell脚本失败了,只是昨天增加了一个参数而已。 报错信息: /bin/bash^M: bad interpreter: No such file or directory 后来发现root cause, 昨天修改文件的时候在windows中修改保存,然…

C语言volatile关键字详解
volatile提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,都会直接从变量地址中读取数据。如果没有volatile关键字,则编译器可能优化读取和存储,可能暂时使用寄存器中的值&#…

python储存数据的容器_Python基础四容器类数据
一、上周内容回顾int bool str 之间的互相转换int str:str(int)int(str) #字符串必须是数字组成int bool:bool(int):非零即TrueTrue --->1 Fasle --->0bool str:str-->bool #非空即Truestr:BIF自己去背吧二、列表why:1.取值费劲。2.对字符串…

Android 清单文件 详解
转载于:https://www.cnblogs.com/mohe/archive/2013/03/31/2991642.html

android屏幕分辨率详解 ldpi mdpi hdpi 程序UI自适应 《官方翻译》
2019独角兽企业重金招聘Python工程师标准>>> 看世界杯的空闲 时间,翻译一下 官方文档。分辨率 问题是大家都很关心的(720480会不会悲剧),而关于这个问题,android官方的文档无疑最有说服力。由于不是所有的人…

010 并发的三个特性
一 . 概述 在之前,我们使用synchronized关键词解决了原子性的操作,本节我们分析一个JVM内存模型导致的另外的两个问题. 二 . 可见性 为了加速线程的运行的速度,JVM的内存模型中设置了线程栈中的缓存,当一个线程使用了堆内存的数据的时候,首先会将这个数据缓存到线程栈之中, 当这…

LeetCode: Longest Consecutive Sequence
想到map了,可惜没想到用erase来节省空间,看了网上答案 1 class Solution {2 public:3 int longestConsecutive(vector<int> &num) {4 // Start typing your C/C solution below5 // DO NOT write int main() function6 …

python做测试书籍推荐_学习pytest应该观看的书籍?
这本书有中文版了pytest是动态编程语言Python专用的测试框架,它具有易于上手、功能强大、第三方插件丰富、效率高、可扩展性好、兼容性强等特点。《pytest测试实战》深入浅出地讲解了pytest的使用方法,尤其是具有特色的fixture的用法。作者通过丰富的测试…

路由器、路由与路由表
2019独角兽企业重金招聘Python工程师标准>>> 路由器、路由与路由表 路由器就是一台网络设备,它配备多个网络接口卡(NIC),能利用它的网络知识正确转发入口流量。 决定一个入口封包应当送给本地主机还是转发所需要的信息,以及在转发…