FFT通过傅里叶级数图解频域补零时域内插
在时域频域的信号分析的过程中,一个常见的说法叫:频域数据补零会让时域数据内插。
意思是在频域数据中多补几个零,再做ifft(逆傅里叶变换)后的时域数据,会变得更加“细腻”,分辨率会更高。
关于频域补零让时域内插,我有一点朴素的理解:
- 频域数据已经包含了所有正弦波的信息,IFFT解出的时域数据是否细腻,只能看时域数据的点数是否够多。
- 做FFT/IFFT运算前后时域和频域的数据的点数是一样多的。
哦,是两点,基于这两点,我们只能把频域数据中原本不存在的高频信息中加上0,再转成时域信号,这样点数就够多呀。频域补零会让时域采样点增加。
基于这样朴素的认知,看看下面两张傅里叶级数的图:
补两个零:
以上,整个正弦波的周期时间没变,但是采样点多了,也就更"细腻"了。
这个网页的的源码在https://gist.github.com/kazad/8bb682da198db597558c
对于学习频域时域的直观感受有很强的帮助。但是因为众所周知的原因,里面的个别js脚本访问不了。我已经将其下载好,放在github地址: https://github.com/Binfun/fourier_transform
如果补的零再增加的话,那么这些点数就慢慢趋近于一个正常的正弦波了:
通过以上示例,仅仅是直观地理解频域补零->时域插值是没有问题的。
但是上面的例子还是有点儿“问题”
在FFT的世界中,上图的描述不准确,而是下图:
在实践过程中,对FFT后的频域结果,如果要补零则是补在中间(高频补零),再进行IFFT(逆傅里叶变换)转成时域。 知道这句话则足够了,以下内容,则是我对于这个现象的朴素的解释。
在上两图中,四个点的频域数据,2HZ和-2Hz是一回事,3Hz和-1Hz也是一回事。就像观察一座山,3Hz是顺时针,分别从东南西北去观察,-1Hz是逆时针,分别从东北西南方向去看而已。
在DFT/FFT计算3Hz时,根据DFT的公式,会计算相位点(数字都会乘以2pi,为方便显示,以下省略2pi):
[0,-3/4, -6/4, -9/4]。该序列可以看作是,顺时针依次递增3/4个2pi。所以它可以看做是3Hz。
将序列[0,-3/4, -6/4, -9/4]中的整数去掉,一个整数就代表一个2pi,一个2pi就代表转动了一圈回到原点。
会得到[0,-3/4, -2/4, -1/4]。这样看序列的话,逆时针依次增加1/4个2pi,所以它可以看做是 -1Hz 。
如果频域数据的点数是N,假设任意一个点的正频率表示为A,那么其负频率表示就是A-N。
那么为什么FFT之后的频域数据,前半部分是以正频率表示,后半部分以负频率表示呢?
我们对1Hz的频点取个30度的初始相位(以1:30表示),然后在后面补零,此刻它是1Hz的正弦波:
我们对序列[0 1:30]中间插18个0,即数字1在序列的最后一位,此时序列有20个频点,最后一个频点正频率的角度是19Hz,负频率的角度是-1Hz。我们现在观察下图黄点连成的线,此刻它是一个 -1Hz的正弦波,并且也是30度的初始相位,而并非是19Hz。
可以把上面两张图结合起来看:
最后基于以上的实验,我朴素地再理解一下,在FFT的世界中,无法支撑起大于等于总点数一半的正频率,所以前半部分是正频率,后半部分是负频率。而高频的判断标准是其绝对值,所以高频在中间。
FFT通过傅里叶级数图解频域补零时域内插的更多相关文章
- PHP实现实现数字补零格式化
在接支付SDK的时候,第三方回调处理时需要IP,并且IP的需求是:去掉点号,补零到每地址段3位, 如:192168000001 先看看我的实现: <?php $IP = explode ( '. ...
- js整数补零
/* * * 整数前面补零 * * 质朴长存法 * num 要补灵的整数 * n个数,比整数位数多前面自动补零 * **/ function pad(num, n) { var len = num.t ...
- php数字补零的两种方法
在php中有两个函数——至少有两个是否有其他的我还不知道,能够实现数字补零,str_pad(),sprintf()详细如下 str_pad顾名思义这个函数是针对字符串来说的这个可以对指定的字符串填补任 ...
- MySQL 查询某时间段范围内的数据 补零
1.创建基础表 CREATE TABLE num (i INT); INSERT INTO num (i) VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9) ...
- Postgresql合并年月日、月份和日期左侧补零
在写一个统计查询的 SQL 语句时,需要根据年.月.日分组,但要求返回的字段是日期格式:yyyy年MM月dd日.刚开始我的做法是返回年.月.日,然后再手动拼接年月日,而且还要判断月份和日期是否为个位数 ...
- C# 左右补零
//不够4位补零 public static string addZero(int val) { string str = val + ""; int strLen = str.L ...
- PHP 字符串两边填充补零
str_pad顾名思义这个函数是针对字符串来说的这个可以对指定的字符串填补任何其它的字符串 例如:str_pad(带填补的字符串,填补后的长度,填补字符串,填补位置) 其中填补后的长度必须是个正整数, ...
- 机器学习进阶-图像基本操作-边界补全操作 1.cv2.copyMakeBoder(img, top_size, bottom_size, left_size, right_size, cv2.BORDER_REPLICATE) 进行边界的补零操作 2.cv2.BORDER_REPLICATE(边界补零复制操作)...
1.cv2.copyMakeBoder(img, top_size, bottom_size, left_size, right_size, cv2.BORDER_REPLICATE) 参数说明: i ...
- 【c++基础】int转string自动补零
前言 使用to_string函数可以将不同类型的数据转换为string类,请参考here和here.如果string的位数固定,如何进行自动补零呢?请看本文实例! 代码 确定位数,to_string ...
随机推荐
- Problem 2221 RunningMan(fuzoj)
Problem 2221 RunningMan Accept: 130 Submit: 404Time Limit: 1000 mSec Memory Limit : 32768 KB ...
- Docker 与 K8S学习笔记(四)—— Dockerfile的编写
在上一篇中我们简单介绍了Docker镜像的获取与使用,其中在镜像制作中提到在实际使用中一定要用Dockerfile方式去创建镜像而不要用docker commit方式,那么我们该如何编写Dockerf ...
- 使用.NET 6开发TodoList应用(10)——实现DELETE请求以及HTTP请求幂等性
系列导航及源代码 使用.NET 6开发TodoList应用文章索引 需求 先说明一下关于原本想要去更新的PATCH请求的文章,从目前试验的情况来看,如果是按照.NET 6的项目结构(即只使用一个Pro ...
- SOA 和微服务
====>场景 不可能让客户端与6个不同的应用/系统都一一去通信来去完成数据的展示.而是6个应用/系统之间进行彼此通信来完成调用,最后客户端只需要调用一个接口来获取数据即可. SOA架构 SOA ...
- 【C++】关键字回忆leetcode题解
20200515 前缀和 no.560 20200518 动态规划 no.152 20200520 状态压缩 no.1371 20200521 中心扩散 no.5 20200523 滑动窗口 no.7 ...
- Spring Boot实战三:集成RabbitMQ,实现消息确认
Spring Boot集成RabbitMQ相比于Spring集成RabbitMQ简单很多,有兴趣了解Spring集成RabbitMQ的同学可以看我之前的<RabbitMQ学习笔记>系列的博 ...
- matplotlib 进阶之origin and extent in imshow
目录 显示的extent Explicit extent and axes limits matplotlib教程学习笔记 import numpy as np import matplotlib.p ...
- 「MySql高级查询与编程」练习:企业员工管理
题目:企业员工管理 一.语言和环境 1.实现语言:SQL. 2.开发环境:MySQL,navicat for mysql. 二.题目(100分): 1.创建数据库及数据表: (1)创建数据库,名称为d ...
- 编写Java程序,利用List实现报数游戏的实现思路
返回本章节 返回作业目录 需求说明: 利用List实现报数游戏 在控制台输入一个大于3的正整数,该整数表示有多少人,如在控制台输入10,表示有10个人,10个人围成一个圆圈,从序号1开始为这些人依次编 ...
- 【JAVA今法修真】 第八章 仙道万维网 圣地元宇宙
您好,我是南橘,万法仙门的掌门,刚刚从九州世界穿越到地球,因为时空乱流的影响导致我的法力全失,现在不得不通过这个平台向广大修真天才们借去力量.你们的每一个点赞,每一个关注都是让我回到九州世界的助力,兄 ...