傅里叶变换快速入门

2023-11-02

 

网上关于傅里叶变换的解释特别多,但大部分都比较偏理论,导致我看来N多教程也还是懵懵懂懂。在某本书(信号完整性分析???)中看到一句震耳发聩的话:每个工程师都应该亲自动手计算一遍傅里叶变换

我知道很多工具可以直接给出傅里叶变换结果,但不清不楚一直是我心里过不去的坎,今天终于把坎踏平了,已经忘记了这是第几次冲锋。。。20200324

本文主要对一个连续周期信号进行采样所得的有限离散周期信号进行离散傅里叶变换(DFT)变换,期间对用到的一些原理进行解释说明并有详细计算过程。基本包括了处理过程的所有细节。

这里说明一下:快速傅里叶变换FFT是一种利用矩阵知识快速实现离散傅里叶变换DFT的方法,最终结果是一样的,FFT只是一种实现DFT的算法

首先假设我们已经了解了以下理论知识:

采样定理(采样频率至少要大于原始信号最高频率的2倍才能提取出原始信号信息);
欧拉公式的应用:   https://www.mscto.com/wp-content/uploads/2020/03/20200325105241801.png

假设我们的原始信号是:

                                   https://www.mscto.com/wp-content/uploads/2020/03/20200325105354885.png 

计算出上面两个正弦函数的周期分别是1 s 2/3 s,所以函数 Xt 的周期是2 s(最小公倍数)。

根据采样定理,我们的采样频率就至少需要0.5 Hz才能保证这两个频率都被正确处理(采样频率越高,失真越小)。我们这里就定采样频率Fs4 Hz吧(即每相邻两个采样点的采样时间间隔是0.25 s ,刚好两倍的采样频率结果观察起来不够明显)。

确定了采样频率,接下来就是采样点的个数了。对于周期信号,要使采样后的信号能完全还原出来,采样的范围必须至少包含一个周期吧。函数 Xt 的周期是2 s,采样频率4 Hz,于是得出采样点数N至少为8点。

下面开始计算啦!!!

傅里叶变换计算公式为:

                             https://www.mscto.com/wp-content/uploads/2020/03/20200325105429367.png

上式的https://img-blog.csdnimg.cn/2020032510555640.png就是我们采样点的值,https://img-blog.csdnimg.cn/2020032510555639.png就是傅里叶变换的结果。或许很多人看到这个式子这么复杂就头大,我也是[哭唧唧]。但我们的伟大领袖说过一切数学公式都是纸老虎。且看我将它大卸八块。(对于想要从感性上理解这个公式的同学,强烈建议上B站学习一下:https://www.bilibili.com/video/BV1pW411J7s8?from=search&seid=7806809382090131811

我们这里就只讲计算了,毕竟理论的东西我自己还不能说很懂呢。。。

因为要用到https://img-blog.csdnimg.cn/2020032510555641.png,那我们就先要把 https://img-blog.csdnimg.cn/2020032510555641.png 都计算出来:

                    第一个点:   https://www.mscto.com/wp-content/uploads/2020/03/20200325105729682.png = sin(2*pi*0) + sin(3*pi*0) + 1 = 1

                    第二个点:   https://www.mscto.com/wp-content/uploads/2020/03/20200325105729687.png  = sin(2*pi*0.25) + sin(3*pi*0.25) + 1 =   2.7071

                    第三个点:   https://www.mscto.com/wp-content/uploads/2020/03/20200325105729690.png = sin(2*pi*0.5) + sin(3*pi*0.5) + 1 =   0

                    第四个点:   https://www.mscto.com/wp-content/uploads/2020/03/20200325110003858.png = sin(2*pi*0.75) + sin(3*pi*0.75) + 1 =   0.70711

                    第五个点:   https://www.mscto.com/wp-content/uploads/2020/03/20200325110003865.png = sin(2*pi*1) + sin(3*pi*1) + 1 =   1

                    第六个点:   https://www.mscto.com/wp-content/uploads/2020/03/20200325110003857.png = sin(2*pi*1.25) + sin(3*pi*1.25) + 1 =   1.2929

                    第七个点:   https://www.mscto.com/wp-content/uploads/2020/03/20200325110003863.png = sin(2*pi*1.5) + sin(3*pi*1.5) + 1 =   2

                    第八个点:   https://www.mscto.com/wp-content/uploads/2020/03/20200325110003862.png = sin(2*pi*1.75) + sin(3*pi*1.75) + 1 =   -0.70711

好了现在可以开始计算傅里叶变换了:(N = 8

                https://www.mscto.com/wp-content/uploads/2020/03/20200325110307531.png

                    https://www.mscto.com/wp-content/uploads/2020/03/20200325110437490.png

(虽然看起来上面的计算狠复杂(其实真的很复杂呀),但至少上面没有未知数,结果是一定存在的,不管是按计算器,matlab工具,或者欧拉公式,只有能计算出正确结果,就是好方法。)

坚持住,到了这里基本就要结束啦!

接下来对结果稍加整理,就是我们需要的频谱图啦!

由:     https://img-blog.csdnimg.cn/2020032511061221.png      可得:

                      https://www.mscto.com/wp-content/uploads/2020/03/2020032511061219.png

根据上面推荐的B站视频可知,傅里叶变换是计算的N个点的向量和,所以之前计算得到的结果要除以采样点数Nabs是求模长(绝对值)的函数,因为频谱图纵坐标的幅值是正值。(好吧我知道解释的很牵强,其实我也不知道为啥要这样。。。这个教程只负责指导你亲手计算一次傅里叶变换,关于理论知识,其他教程说的比我精彩)

上面就是频谱图的一些点了,但是我怎么知道每一个点对应什么频率呢?

其实傅里叶变换后的频率分辨率是https://www.mscto.com/wp-content/uploads/2020/03/2020032511061225.png(其中https://www.mscto.com/wp-content/uploads/2020/03/2020032511061225.png为采样的总时长)。为啥呢?

对以上的结果可以理解为:我们采样的数据只有https://img-blog.csdnimg.cn/2020032511061223.png 秒,信号的成分中周期最大也就是https://img-blog.csdnimg.cn/20200325110612199.png秒,频率最低就是。那么频率分辨率就是 https://www.mscto.com/wp-content/uploads/2020/03/20200325111034480.png了。也就是说频率分辨率只和总采样时间有关。采样时间越长,能区分的频率就越小,即分辨率越好。

这里假设采样周期为T,采样总时长为https://www.mscto.com/wp-content/uploads/2020/03/2020032511061225.png,那么就有如下关系:

                                          https://www.mscto.com/wp-content/uploads/2020/03/2020032511061222.png

本例子中解释分辨率就是:傅里叶变换的第一个结果表示频率为0的信号幅值,第二个结果就是表示频率为Fs/N = 4/8 = 0.5Hz 的信号幅值了,依次第三个结果表示1Hz信号幅值。。。第八个表示频率为3.5Hz信号的幅值。

我们把上面的结果在坐标轴中画出来,就是我们说的频谱图啦:(Fs = 4Hz, N = 8, 对称处理前)

                                https://www.mscto.com/wp-content/uploads/2020/03/20200325111224528.png

我们发现f=0.5f=3.5的结果关于f=2对称,即X(N-k) = X(k)   (其中k=1:N-1)

(对称的理论证明,传送门在此:https://www.zhihu.com/question/264560305

我们看频率为0的时候幅值为1,表示原始信号中有一个幅值为1的直流信号,和我们的给出的原始信号相符(加了一个常数1)。

频谱图中频率为1时幅值是0.5,但我们的原始信号频率为1 sin(2*pi*t) )的分量幅值可是1啊。这是为啥呢?这是由上面说的对称所引起的。频谱图中频率为1和频率为3的点对称,两个点幅值都是0.5,两个加起来,就刚好是原始信号的幅值1了。同理sin(3*pi*t)的幅值是由频谱图中频率为1.5Hz和频率为2.5Hz的两个幅值相加而来,幅值也是1

但图形既然对称,为啥我们要选择相信原始信号是由频率为1Hz和频率为1.5Hz的正弦波合成的,而不是频率为2.5Hz3Hz呢?我们的采样频率是4Hz,根据采样定理,最大只能处理到2Hz的情况,所以我们只能选择1Hz1.5Hz啦。

上面已经是频谱图了,但是不够完美,既然我们只需要对称的前半部分,那就再处理一下吧:

我们只取上面结果的频率在2Hz前的部分,且对频率不为0的信号幅值加倍,就得到了最终结果:(Fs = 4Hz, N = 8

                               https://www.mscto.com/wp-content/uploads/2020/03/20200325111509999.png

怎么样,这个结果够完美了吧!!!

但是这个实验的采样点太少导致频率分辨率太低(频率为0.75的幅值是什么呢,我们不知道,图中只是把前后两个点连线过渡而已,并不表示中间区域的幅值。注意:周期信号在频域中一定是离散的)。

频率分辨率太低怎么办呢? 根据之前的分析知道,需要加长总的采样时间,那就保持采样频率不变,采样点数加到16试试吧,结果如下:(Fs = 4Hz, N = 16

                                      https://www.mscto.com/wp-content/uploads/2020/03/20200325111607709.png

现在,从图中我们已经可以看出频率为0.75的信号分量幅值为0,基本能够确定原始信号中只有这三个波峰对应的频率分量了。

再把采样点加到512个点,结果如下:(Fs = 4Hz, N = 512

                                  

这下够清楚了吧。。。

 

在此附上matlab代码:( %后跟注释,如有需要可以删除%查看中间结果,但中文前面的那个%不能删除)

————————-程序开始(可在线运行https://octave-online.net/ ——————————

Fs = 4;                                % 设置采样率

T = 1/Fs;                            % 采样周期

N = 512;                            % 设置采样点数,设为8即可得到上面的实验结果

t = (0:N-1)*T;                   % 确定采样值,: 表示变量的取值范围

%t                                       % matlab中变量不加分号时会打印出变量的值

y = sin(2*pi*t)+sin(3*pi*t)+1;     % 本例子的原始信号,可以看出f = 0Hz, f=1Hz, f=1.5Hz 的信号分量

%y

Y = fft(y);                           % FFT是通过矩阵计算傅里叶变换的一种算法,和DFT结果是一样的

%Y                                      % Y前面的百分号去掉,就可以快速得到上面的计算结果啦!

Y1 = Y/N;                           % 上面有说,我也不知道为啥要除以N

%Y1

P2 = abs(Y1);                    % 求复数的模长

%P2

%f = Fs*(0:N-1)/N;          % 频率分辨率为Fs/N,  频率范围是0Fs(N-1)/N

%plot(f,P2);                      % fx轴坐标的格点,画出对称的变换结果

%xlabel(‘frequens(Hz)’);              % 设置x轴坐标名称

%ylabel(‘amplifer’);                      % 设置y轴坐标名称

%title(‘DFT result for \”y=sin(2*pi*t)+sin(3*pi*t)+1\”‘);                 % 设置图像标题

P1 = P2(1:N/2+1);                          % 把对称的部分图形去掉

%P1

P1(2:end-1) = 2*P1(2:end-1);      % 从第二个结果开始幅值都加倍(end表示最后一个值)

%P1

f = Fs*(0:N/2)/N;                           % 频率分辨率为Fs/N,  频率范围是0Fs/2

%f

plot(f,P1);                                       %fx轴坐标的格点,画出去掉对称部分的变换结果

xlabel(‘frequens(Hz)’);

ylabel(‘amplifer’);

title(‘DFT result for \”y=sin(2*pi*t)+sin(3*pi*t)+1\”‘);

恭喜我们都学习完啦,写这篇总结的时候对傅里叶变换也有了更深刻的认识,好开心呀!

 

注:本文转自:https://www.mscto.com/void/429270.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

傅里叶变换快速入门 的相关文章

  • 我的傅立叶逆变换中的尖峰

    我正在尝试在 MATLAB 中比较两个数据集 为此 我需要通过傅里叶变换数据来过滤数据集 对其进行过滤 然后对其进行逆傅里叶变换 然而 当我对数据进行逆傅里叶变换时 我在红色数据集的两端都出现了一个尖峰 图片显示了第一个尖峰 它在开始时应该
  • 如何从 Matlab 在 vi​​rtualenv 中执行 Python 代码

    我正在创建一个用于研究的 Matlab 工具箱 我需要执行 Matlab 代码 但也需要执行 Python 代码 我想允许用户从 Matlab 执行 Python 代码 问题是 如果我立即执行此操作 我将必须在 Python 环境中安装所有
  • 从彩色背景中提取黑色对象

    人眼很容易辨别black来自其他颜色 但是计算机呢 我在普通的A4纸上打印了一些色块 由于组成彩色图像有青色 品红色和黄色三种墨水 所以我设置每个块的颜色C 20 C 30 C 40 C 50 以及其余两种颜色是 0 这是我的源图像的第一列
  • 如何在matlab中绘制彩色一维直方图

    我有一个一维数组 X 其中包含相关系数的统计数据 我想绘制一个彩色直方图 我使用以下代码 histogram X 10 它可以创建具有单色的直方图 现在我想绘制一个直方图 其中每个条形都有不同的颜色 但 FaceColor 选项只能调整整个
  • 在 Matlab 2014b 中移动等高线图的 z 值

    我正在尝试绘制曲面图 在曲面下方我希望显示轮廓线 但我希望轮廓位于z 1而不是默认值0 我找到了之前关于这个问题的帖子here https stackoverflow com questions 8054966 matlab how to
  • 是否有一个函数可以将两个元胞数组“压缩”在一起? [复制]

    这个问题在这里已经有答案了 假设我有一个元胞数组A and B as so A A B C D B 1 2 3 4 我想创建元胞数组C通过将 A 和 B 压缩 在一起 如下所示 C zip A B C A 1 B 2 C 3 D 4 这样的
  • 使用 libsvm 交叉验证后重新训练

    我知道交叉验证用于选择好的参数 找到它们后 我需要在不使用 v 选项的情况下重新训练整个数据 但我面临的问题是 在使用 v 选项训练后 我得到了交叉验证精度 例如 85 没有模型 我看不到 C 和 gamma 的值 在这种情况下我该如何重新
  • 增加 .fig 文件中的散点标记大小

    我有一个图形文件 scatter fig 该图有许多使用 scatter 的散点绘图仪 现在我只有这个无花果文件 我需要增加所有散点的标记大小 手动尝试过 但非常困难 有没有办法我可以做类似的事情 H 图形句柄 s 点 h 设置 s 标记大
  • MATLAB 是否已有 YAML 库/解析器?

    我想使用 YAML 跨多种语言交流一些数据 将其视为 与语言无关的序列化 其中一种语言是 MATLAB 但我似乎找不到该语言的 YAML 库 我在 Google 上检查了 matlab yaml 和 matlab yaml parse 似乎
  • 如何建立数据流挖掘的滑动窗口模型?

    我们遇到的情况是 流 来自传感器的数据或服务器上的点击流数据 采用滑动窗口算法 我们必须将最后 例如 500 个数据样本存储在内存中 然后 这些样本用于创建直方图 聚合并捕获有关输入数据流中异常的信息 请告诉我如何制作这样的滑动窗 如果您询
  • Microsoft Visual C++ 2008 和 R2007b 的 Mex 类型

    我想对 vs2008 和 matlab2007b 使用 mex 类型 我尝试了下面的代码 include
  • opencv中矩阵的超快中值(与matlab一样快)

    我正在 openCV 中编写一些代码 想要找到一个非常大的矩阵数组 单通道灰度 浮点数 的中值 我尝试了几种方法 例如对数组进行排序 使用 std sort 和选择中间条目 但与 matlab 中的中值函数相比 它非常慢 准确地说 在 ma
  • 如何以编程方式指定 MATLAB 编辑器键绑定

    我想将键盘键绑定设置为Windows 默认设置我想在启动时使用startup m因为我希望在大量系统上设置此设置 首选项对话框中的等效设置是 MATLAB gt Keyboard gt Shortcuts gt Active Setting
  • 在 MATLAB 中用两个值替换向量值

    我必须创建一个以向量作为输入的函数v和三个标量a b and c 该函数替换了的每个元素v等于a有一个二元素数组 b c 例如 给定v 1 2 3 4 and a 2 b 5 c 5 输出将是 out 1 5 5 3 4 我的第一次尝试是尝
  • 是否有一个函数可以检查矩阵是否对角占优(行占优)

    矩阵是对角占优 http en wikipedia org wiki Diagonally dominant matrix 按行 如果对角线处的值在绝对意义上大于该行中所有其他绝对值的总和 对于列也是如此 只是相反 matlab中有没有函数
  • MATLAB:比较两个不同长度的数组

    我有两个长度不同的数组 由于采样率不同 需要比较 我想对较大的数组进行下采样以匹配较小的数组的长度 但是该因子不是整数而是小数 举个例子 a 1 1 375 1 75 2 125 2 5 2 875 3 25 b 1 2 3 有什么方法可以
  • 通过傅里叶空间填充进行插值

    我最近尝试在 matlab 上实现一个在傅立叶域中使用零填充的插值方法的简单示例 但我无法正常工作 我总是有一个小的频移 在傅里叶空间中几乎不可见 但它在时空上产生了巨大的误差 由于傅里叶空间中的零填充似乎是一种常见 且快速 的插值方法 因
  • 同时重新排序和旋转图像的高效方法

    为了快速加载 jpeg 我为turbojpeg 实现了一个 mex wrapper 以有效地将 大 jpeg 读入 MATLAB 对于 4000x3000px 的图像 实际解码只需要大约 120 毫秒 而不是 5 毫秒 然而 像素顺序是 R
  • 在 MATLAB 中定义其他中缀运算符

    有没有办法在 MATLAB 中定义额外的中缀运算符 具体来说 我想定义两个中缀运算符 gt and lt gt 这些符号是理想的 但如果需要 它可以是单个字符 它调用函数implies and iff以同样的方式 calls and and
  • 如何在Matlab中将世界坐标转换为像素索引

    我有 512x512x313 体积的 dicom 图像 并且我有一个以世界坐标表示的点 57 7475 63 4184 83 1515 我如何在 Matlab 中获得该世界坐标的相应像素坐标 我不想戳破你的幻想 但你所要求的是不可能的 我能

随机推荐

  • oracle tmp表空间不足,临时表空间不足引起的ORA-01114错误

    数据库程序突遇ORA 01114错误 提示内容如下 错误原因 Select error ORA 01114 将块写入文件 时出现 IO 错误 块 ORA 27069 skgfdisp 尝试在文件范围外执行 I O OSD 04026 无效的
  • Unity + vuforia 开发虚拟按钮

    首先在创建虚拟按钮之前 还是要首先了解imageTarget的创建方式 我自己时参考dzyi的博客弄的 推荐大家 写的很详细 地址 http blog csdn net dzyi article details 22898929 创建虚拟按
  • 有了Auto Layout,为什么你还是害怕写UITabelView的自适应布局?

    Apple 算是最重视应用开发体验的公司了 从Xib到StoryBoard 从Auto Layout到Size Class 每一次的更新 都会给iOS应用的开发带来不小的便利 但是 对于绝对多数iOS攻城狮来说 我们依然还是很害怕写UITa
  • 解决docker pull 很慢的问题

    再docker拉取镜像时 花费时间太长 用如下方法可以解决 root localhost mkdir p etc docker root localhost cat etc docker daemon json registry mirro
  • mysql Undo Tablespaces

    分离 undo 表空间相关的参数 innodb undo directory 指定单独存放 undo 表空间的目录 默认为 即 datadir 可以设置相对路径或者绝对路径 该参数实例初始化之后虽然不可直接改动 但是可 以通过先停库 修改配
  • 联想工作站光盘或WinPE重装Win7找不到SSD和另外一个2T磁盘

    工作站比较老了 苏州重启系统修了 应该是原来的SSD硬盘损坏 修复工具无法修复 只能重装了 由于某一应用软件要求 只能装Win7系统 使用老毛桃制作的WinPE进去看了分区 安装系统时无法找到新的SSD盘和之前的2T磁盘
  • PLC的通信模式

    说到PLC的通讯模式 主要有两种 一种是并行通讯模式 一种是串行通讯模式 这两种通信模式有什么区别呢 PLC串行通信 串行通信一般是用二进制的位 BIT 为单位的数据传输方式 每次都只传送一位 然后除了地线之外 在一个数据传输方向上面只要一
  • element tree树形结构接口不支持搜索、懒加载情况下实现搜索

    目前项目中 element tree树形结构由于数据太多使用了懒加载 并且接口不支持搜索 只能由前端实现搜索功能 暂时按照自己思路实现功能 思路为 输入搜索内容后 直接遍历树形结构的数据 通过filter筛选出结果之后再赋值给树形结构 de
  • matlab径向分布函数作图_分子动力学的径向分布函数绘制

    这是过冷水之前在工作中的一张图片 这张图片的实际含义是以坐标原点为参考点 距离原点距离x处的小球个数f x 分布图 这个问题理解起来好容易 统计距离和小球个数的关系 but实际问题是过冷水要处理的是这样的问题 请问请告诉我随意找一个小球为原
  • 小团队管理核心(一)

    主管应该投身具体业务还是专注于管理 投身业务 or 专注管理 主管应该投身具体业务还是专注于管理 一 主管的定位 二 如何实现老板目标 三 主管应当专注管理 一 主管的定位 定位简述 通过下属实现经营者目标的人 定位解析 由此看来我们的目标
  • ThreeJS第一人称视角处理

    简介 第一人称控件指针锁定API允许您在游戏界面中锁定鼠标或其他指针设备 以便您不用绝对定位光标就可以获得坐标变化值 从而准确地判断用户正在做什么 并且还可以防止用户意外地进入另一块屏幕或别的什么地方 从而导致误操作 在ThreeJs中实现
  • Python 查看数据类型与格式

    一般我们拿到一个数据 会先看一下这个数据有多少行多少列 各个字段是什么 数据格式类型是什么 在开始讲数据格式前 需要先梳理一下各个数据类型 我们常使用的库一般是numpy和pandas Numpy下的核心是数组 array ndarray
  • Redis支持哪几种数据类型?

    Redis支持哪几种数据类型 1 什么是Redis 2 优缺点 3 Redis相比Memcached有哪些优势 4 Redis支持的数据类型 4 1 String 字符串 4 2 List 列表 4 3 Set 集合 4 4 Sorted
  • HTTPS原理(证书验证+数据传输)

    HTTPS协议相关的概念有SSL 非对称加密 CA证书等 为什么用了HTTPS就是安全的 HTTPS底层原理如何实现 用了HTTPS就一定安全吗 HTTPS实现原理 HTTPS在内容传输上的加密使用的是对称加密 证书验证阶段使用非对称加密
  • 图像评价指标(python)

    图像评价指标的综合记录 一 信息熵 熵是衡量图像中所包含的信息量的大小 熵越大说明包含的信息越多 意味着可以从处理后的图像中获取更多的信息 用信息熵来计算图像的熵值 代码 import cv2 import numpy as np impo
  • C 标准库 - 《stdio.h》

    原文链接 https www runoob com cprogramming c standard library stdio h html 简介 stdio h 头文件定义了三个变量类型 一些宏和各种函数来执行输入和输出 库变量 下面是头
  • 前端页面间数据传递常用的几种方式

    1 常用方式 url页面路径携带参数传递 localStorage方式传递 sessionStorage方式传递 cookie的方式传递 2 方式对比 url字节限制可以参考这一篇文章 HTTP中的URL长度限制 其中cookie的setC
  • 开关电源的时钟倍频 辐射发射超标RE+ 噪声源+干扰原因

    1 收藏 史上最全开关电源传导与辐射超标整改方案 医疗设备低频30 50Mhz超标 2 https bbs elecfans com m jishu 941580 1 1 html 3 辐射噪声的产生机理 知乎 1 电流源 噪声源 2 天线
  • 【华为OD机试】叠积木(C++ Python Java)2023 B卷

    时间限制 C C 1秒 其他语言 2秒 空间限制 C C 262144K 其他语言524288K 64bit IO Format lld 语言限定 C clang11 C clang 11 Pascal fpc 3 0 2 Java jav
  • 傅里叶变换快速入门

    网上关于傅里叶变换的解释特别多 但大部分都比较偏理论 导致我看来N多教程也还是懵懵懂懂 在某本书 信号完整性分析 中看到一句震耳发聩的话 每个工程师都应该亲自动手计算一遍傅里叶变换 我知道很多工具可以直接给出傅里叶变换结果 但不清不楚一直是