matlab:快速傅里叶(反)变换 FFT&IFFT

2023-11-13


前言

傅里叶变换就是信号的分解过程
即把时域(空域)信号分解成一系列频率下的正弦信号。
傅立叶变换之后的正弦信号每个点都是复数,如a+bi
幅值是:根号下a平方+b平方
相位是:arctan(b/a)
实部是:a
虚步是:b
幅度和相位结合在一起,就能完全表示傅立叶变换的结果;实部和虚步结合在一起也能完全表示。但是并不是说相位等于虚部。
频谱图:频域和幅值图像&频域和相位图像统称频谱图
◼ 傅里叶变换的好处
✓ 正弦信号比原信号更简单 → 已被充分地研究
✓ 处理正弦信号 → 比处理原信号更简单
✓ 线性系统 → 正弦信号的频率保持性
➢ 输入为正弦信号 → 输出仍是同频率的正弦信号
➢ 幅值和相位可能发生变化 → 但频率与输入信号保持一致
➢ 频率保持性具有很高的工程实用价值


提示:以下是本篇文章正文内容,下面案例可供参考

一、傅里叶变换的离散性与周期性

在这里插入图片描述
计算机只能处理有限长度的离散数据序列,所以只有DFS可以通过计算机进行计算
FFT只是加速 DFT 运算的一种快速算法, 在信号理论上没有新的贡献 。其计算的结果和本质内容仍然是离散傅里叶变换 (DFT)

二、MATLAB 实现快速傅里叶变换 FFT (DFT) 的计算

MATLAB 函数的调用格式 → X = fft (x) // X = fft (x, n)
x 是一个时域序列 → 通常为时域信号的采样值
n 用于定义 → 进行 FFT 计算的数据个数
➢ 如果 n 大于 x 的长度 → 自动在 x 的末尾添加 0 → 使得 x 的长度等于 n
➢ 如果 n 小于 x 的长度 → 自动截取 x 中的前 n 个数来进行 FFT 计算
X 返回 FFT 的计算结果 → 通常是一个复数序列

三,FFT 频谱的对称性

从实部和虚部角度分析:
在这里插入图片描述
从幅值和相位角度分析
在这里插入图片描述
即,两个角度关于N/2都是共轭对称的。

四,FFT 频谱的频率刻度

在这里插入图片描述
这里解释一下绿框文字。其实是奈奎斯特采样定理(Nyquist sampling theorem),解释了采样率和所测信号频率之间的关系:
采样率Fs必须大于被测信号频率范围的两倍。

另外,有必要解释一下负频率是怎么一回事:
先说结论,所有具有实际物理意义的信号(即实信号,比如f(x)=cos(t))经过傅里叶变换之后的频谱图都是左右对称的(幅频图关于Y轴偶对称,相频图奇对称)。也就是说实信号都是同时有正负频率的,那种只有正频率或负频率的信号(比如f(x)=e^jt)现实中是不存在的,只有数学上的抽象意义。因此无论采样前后,信号都是有负频率的。next,好好的信号为什么会有负频率,该如何理解?下面我们从傅里叶级数的角度理解一下(比较好解释,傅里叶变换大同小异)。傅里叶级数的物理意义很明确:把一个周期信号表示为一系列不同频率的复指数信号的线性组合。上公式:

作者:卡夫链接:https://www.zhihu.com/question/27385185/answer/40799101来源:知乎著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
注意!这个公式的最小组成单位是复指数信号,也就是这个
[公式]
我们知道,复指数信号不是实信号,它在现实中是不存在的,因为它带有虚部j。
那如何用复指数信号合成实信号呢?
答案很简单:只要两个复数共轭就好,实部相加,虚部相抵。也就是欧拉公式:
在这里插入图片描述
所以我们在傅里叶级数分析信号的时候,频谱绝对是对称的,用很多对指数相反的复指数信号,就可以合成实信号,也就是说:有k,那必然有-k,否则无法合成实信号。综上,出现负频率的根本原因就是傅里叶级数(变换)的最小单位是复指数信号,如果用傅里叶级数的另一种形式,把信号表示为一系列正余弦信号的组合,就不存在负频率了。

五,频谱图的绘制(半谱图&全谱图)

半谱图(没有负频率)
在这里插入图片描述序列 Y 对应的频率刻度 → (0 : 1 : N/2) x df
→ 0 : Fs/N : Fs/2
全谱图:由于频率刻度正频率在左,负频率在右不符合我们的计算习惯,所以通过ffshift函数进行交换。
在这里插入图片描述
针对一维信号, 一般情况下, 更习惯于绘制半谱图

六 练习 绘制cos信号的频谱图

半谱图

clear;clc;close all

%% 定义时域采样信号 x
Fs=100;             % 信号采样频率
Ts=1/Fs;            % 采样时间间隔
N=200;             % 采样信号的长度
t=(0:1:N-1)*Ts;     % 定义信号采样的时间点 t
t=t';               % 为了方便查看, 将行向量 t 转置成列向量

f1=16;              % 第一个余弦信号的频率
f2=45;              % 第二个余弦信号的频率
x=4.5+2.7*cos(2*pi*f1*t+pi/4)+8.2*cos(2*pi*f2*t-pi/6);  % 定义时域采样信号 x

%% 对时域采样信号, 执行快速傅里叶变换 FFT
X=fft(x);           % 执行 FFT 计算, 结果保存在 X 里

%% 提取 X 里正频率的部分, 并且将 X 里负频率的部分合并到正频率  
Y=X(1:N/2+1);              % 提取 X 里正频率的部分
Y(2:end-1)=2*Y(2:end-1);   % 将 X 里负频率的部分合并到正频率

%% 计算频域序列 Y 的幅值和相角
A=abs(Y);           % 计算频域序列 Y 的幅值
Pha=angle(Y);       % 计算频域序列 Y 的相角 (弧度制)
R = real(Y);	% 计算频域序列 Y 的实部
I = imag(Y);	% 计算频域序列 Y 的虚部

%% 定义序列 Y 对应的频率刻度
df=Fs/N;            % 频率间隔
f=(0:1:N/2)*df;     % 频率刻度
f=f';               % 为了方便查看, 将行向量 f 转置成列向量

%% 绘制时域采样信号 x 的波形
figure
plot(t,x)
xlabel('时间 [s]')
ylabel('信号值 x(t)')

%% 绘制频域序列 Y 的幅频图 & 相频图
figure
subplot(2,1,1)
plot(f,A)         % 绘制频域序列 Y 的幅频图
grid on
xlabel('频率 [Hz]')
ylabel('Y 的幅值')

subplot(2,1,2)
plot(f,Pha)       % 绘制频域序列 Y 的相频图
grid on
xlabel('频率 [Hz]')
ylabel('Y 的相角')


%% 绘制频域序列 Y 的实部图 & 虚部图
figure
subplot(2,1,1)
plot(f,R)         % 绘制频域序列 Y 的实部图
grid on
xlabel('频率 [Hz]')
ylabel('Y 的实部')

subplot(2,1,2)
plot(f,I)       % 绘制频域序列 Y 的虚部图
grid on
xlabel('频率 [Hz]')
ylabel('Y 的虚部')



结果如下
在这里插入图片描述
我们发现频率16hz和45hz正好对应,但是幅值过大(540,1640)并且相位混乱。这是因为MATLAB计算误差导致的(fft变换后的虚部大多数极为接近0的小数,我们需要设置一个阈值将这些小数置0来解决相位混乱)。至于幅值只需要/N即可。代码如下


%% 消除相位混乱
X(abs(X)<1e-8)=0;   % 将频域序列 X 中, 幅值小于 1e-8 的数值置零

%% 修正频域序列的幅值, 使得 FFT 变换的结果有明确的物理意义
X=X/N;              % 将频域序列 X 除以序列的长度 N

最终结果如下:
在这里插入图片描述
x=4.5+2.7cos(2pif1t+pi/4)+8.2cos(2pif2t-pi/6);

全谱图


%% 定义时域采样信号 x
Fs=100;             % 信号采样频率
Ts=1/Fs;            % 采样时间间隔
N=200;             % 采样信号的长度
t=(0:1:N-1)*Ts;     % 定义信号采样的时间点 t
t=t';               % 为了方便查看, 将行向量 t 转置成列向量

f1=16;              % 第一个余弦信号的频率
f2=45;              % 第二个余弦信号的频率
x=4.5+2.7*cos(2*pi*f1*t+pi/4)+8.2*cos(2*pi*f2*t-pi/6);  % 定义时域采样信号 x

%% 对时域采样信号, 执行快速傅里叶变换 FFT
X=fft(x);           % 执行 FFT 计算, 结果保存在 X 里


%% 消除相位混乱
X(abs(X)<1e-8)=0;   % 将频域序列 X 中, 幅值小于 1e-8 的数值置零

%% 修正频域序列的幅值, 使得 FFT 变换的结果有明确的物理意义
X=X/N;              % 将频域序列 X 除以序列的长度 N


%% 将 X 重新排列, 把负频率部分搬移到序列的左边, 把正频率部分搬移到序列的右边
Y=fftshift(X);      % 新的频域序列 Y

%% 计算频域序列 Y 的幅值和相角
A=abs(Y);           % 计算频域序列 Y 的幅值
Pha=angle(Y);       % 计算频域序列 Y 的相角 (弧度制)
R = real(Y);	% 计算频域序列 Y 的实部
I = imag(Y);	% 计算频域序列 Y 的虚部

%% 定义序列 Y 对应的频率刻度
df=Fs/N;            % 频率间隔
f=(-N/2:1:N/2-1)*df;     % 频率刻度
f=f';               % 为了方便查看, 将行向量 f 转置成列向量

%% 绘制时域采样信号 x 的波形
figure
plot(t,x)
xlabel('时间 [s]')
ylabel('信号值 x(t)')

%% 绘制频域序列 Y 的幅频图 & 相频图
figure
subplot(2,1,1)
plot(f,A)         % 绘制频域序列 Y 的幅频图
grid on
xlabel('频率 [Hz]')
ylabel('Y 的幅值')

subplot(2,1,2)
plot(f,Pha)       % 绘制频域序列 Y 的相频图
grid on
xlabel('频率 [Hz]')
ylabel('Y 的相角')


%% 绘制频域序列 Y 的实部图 & 虚部图
figure
subplot(2,1,1)
plot(f,R)         % 绘制频域序列 Y 的实部图
grid on
xlabel('频率 [Hz]')
ylabel('Y 的实部')

subplot(2,1,2)
plot(f,I)       % 绘制频域序列 Y 的虚部图
grid on
xlabel('频率 [Hz]')
ylabel('Y 的虚部')



在这里插入图片描述

七,IFFT反傅里叶变换

我们可以通过ifft函数将频域信号X反变换回原本的空域信号

IX = ifft(X);
%% 绘制频域信号 x 的反傅里叶变换波形
figure
plot(t,IX)
xlabel('时间 [s]')
ylabel('信号值 x(t)')

这里注意,ifft之后结果又从频域的复数变成了空域里的实数,即结果的虚部为0.

八,采样规则

采样频率 Fs // 频率刻度间隔 df = Fs/N
采样定理: 采样频率 Fs ≥ 2Fc( Fc 为信号里的最高频率成分)
设信号含有 60 Hz 和 72 Hz 两个频率成分 → 采样频率 Fs = 2000 Hz
➢ 时域里采集 N = 100 个数据点 → 频率刻度间隔 df = Fs/N = 20 Hz > (72 – 60 = 12 Hz)
不满足采样定理,此时分不开数据
➢ 时域里采集 N = 500 个数据点 → 频率刻度间隔 df = Fs/N = 4 Hz < (72 – 60 = 12 Hz)

九,二维傅里叶变换

附神贴链接link!!!!!!!!!!!!!!!

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

matlab:快速傅里叶(反)变换 FFT&IFFT 的相关文章

  • 在 MATLAB 中模拟 C++ 模板

    我试图找出创建 C 模板或 Java 通用对象的替代方案的最佳方法 出于多种不同的原因 我过去曾多次想这样做 但现在我想做的是为几个相关的类创建 saveobj 和 loadobj 函数 我的想法是 我想要一组通用的例程来创建默认结构 然后
  • 禁止 MATLAB 自动获取焦点[重复]

    这个问题在这里已经有答案了 我有以下问题 在我的 MATLAB 代码中 我使用如下语句 figure 1 更改某些数据的目标数字 问题是 在此 MATLAB 之后 系统将焦点集中在具有该图形的窗口上 当我在后台运行一个大脚本并尝试在计算机上
  • 将 Matlab 数组移植到 C/C++

    我正在将 matlab 程序移植到 C C 我有几个问题 但最重要的问题之一是 Matlab 将任何维度的数组都视为相同 假设我们有一个这样的函数 function result f A B C result A 2 B C A B and
  • FMINCON 的替代方案

    除了 fmincon 之外还有其他更快 更高效的求解器吗 我正在使用 fmincon 来解决特定问题 但对于中等大小的向量变量来说 我的内存不足 我也没有任何超级计算机或云计算选项可供使用 我知道任何替代解决方案仍然会耗尽内存 但我只是想看
  • MATLAB - 通过垂直连接子矩阵重新排列矩阵

    我在执行以下任务时遇到问题 假设一个 3x6 矩阵 A 0 2787 0 2948 0 4635 0 8388 0 0627 0 0435 0 6917 0 1185 0 3660 0 1867 0 2383 0 7577 0 6179 0
  • MATLAB:将当前文件夹设置为脚本位置

    我在不同的文件夹中有一些脚本和数据 我使用addpath和相对路径经常 我的问题是 只有当我的当前文件夹是我执行的脚本所在的位置时 这才有效 例如 如果我执行添加路径 X 的脚本 A 然后执行位于路径 X 中的脚本 B 则 Matlab 不
  • matlab 中的动画绘图

    我正在尝试创建一个三角形的动画图 最终结果应该是十个三角形 后面跟着两个更大的三角形 后面跟着一条直线 使用matlab文档 https de mathworks com help matlab ref drawnow html 我最终得到
  • 保存符号方程以供以后使用?

    From here http www mathworks com help releases R2011a toolbox symbolic brvfu8o 1 html brvfxem 1 我正在尝试求解这样的符号方程组 syms x y
  • 优先连接,Matlab 中的复杂网络

    大家好 我现在正在 MATLAB 中研究优先附件模型 在理解以下内容时遇到一些困难 假设我一开始有 4 个节点 连接如下 time 0 1 lt gt 2 3 lt gt 4 在下一个时间步骤中 我添加一个节点和 4 个连接 然后添加另一个
  • 考虑预分配速度[重复]

    这个问题在这里已经有答案了 我正在做以下事情 for i 1 m index 0 for j 1 n index index values i j 2 j 1 if j 1 symbol chip chip values index 1 e
  • 氡变换线检测

    我正在尝试检测灰度图像中的线条 为此 我在 MATLAB 中使用 Radon 变换 我的 m 文件的示例如下所示 我可以使用此代码检测多行 我还使用线条的移位和旋转属性来绘制线条 但是 我不明白在获取rho和theta值后如何获取检测线的起
  • MATLAB问题:在图块中引用变量的值[重复]

    这个问题在这里已经有答案了 可能的重复 matlab 绘图标题中的变量 https stackoverflow com questions 5629458 matlab variable in plot title 我想在图中引用 m 文件
  • 如何在Matlab中将图像从笛卡尔坐标更改为极坐标?

    我正在尝试将图像的像素从 x y 坐标转换为极坐标 但我遇到了问题 因为我想自己编写该函数 这是我到目前为止所做的代码 function newImage PolarCartRot read and show the image image
  • MATLAB 中的逻辑数组与数值数组

    我正在比较两个二进制数组 我有一个数组 其中值可以是一或零 如果值相同则为 1 如果不同则为零 请注意 我正在做检查之外的其他事情 因此我们不需要进入矢量化或代码的性质 在 MATLAB 中使用数值数组和逻辑数组哪个更有效 Logical
  • 基本矩阵错误?

    我试图通过扫描从相机拍摄的两个图像 检测图像中的特征 匹配它们 创建基本矩阵 使用相机内在函数计算基本矩阵 然后分解它以找到旋转和翻译 这是matlab代码 I1 rgb2gray imread 1 png I2 rgb2gray imre
  • Blob 的簇生长

    考虑以下来自 Mathworks 的图像 我已经用标签标记了斑点 L num bwlabel I 如何迭代连接所有斑点 即从一个斑点开始 找到离它最近的一个 考虑最左边的两个斑点 可以从一个斑点的许多点绘制许多条线来连接到另一个斑点blob
  • 使用网络计算机进行 Matlab 并行处理

    我熟悉matlabpool and parfor用法 但我仍然需要加快计算速度 我的 1GB 网络中有一台功能更强大的计算机 两台计算机都有 R2010b 并且具有相同的代码和路径 使用两台计算机进行并行计算的最简单方法是什么 我今天使用的
  • 使用 scipy.io 将 python pandas dataframe 转换为 matlab 结构

    我正在尝试使用 scipy io 将 pandas 数据帧保存到 matlab mat 文件 我有以下内容 array1 np array 1 2 3 array2 np array a b c array3 np array 1 01 2
  • Python 中 Matlab 'fscanf' 的等价物是什么?

    Matlab函数fscanf 似乎很强大 python 或numpy 中是否有相同的等效项 具体来说 我想从文件中读取矩阵 但我不想迭代每一行来读取矩阵 类似的东西 来自 matlab 用于读取 2D 1000x1000 矩阵 matrix
  • Matlab的uicontrol在Octave中的实现?

    我正在尝试在 Octave 中运行我们实验室中使用的图形程序的 m Matlab 代码 Octave 告诉我代码中使用的函数 uicontrol 没有定义 经过一番搜索 我发现 JHandles 包有一个 uicontrol GUI 功能的

随机推荐

  • git:分支管理策略

    主分支Master 首先 代码库应该有一个 而且仅有一个主分支 所有提供给用户使用的正式版本 都在这个主分支上发布 Git主分支的名字 默认叫做Master 它是自动建立的 版本库初始化以后 默认就是在主分支在进行开发 主分支 也是用于部署
  • 微信订阅号和公众号的区别

    第一 定位不同 订阅号为用户提供信息和资讯 服务号主要为用户提供服务 第二 群发信息量不同 订阅号每天 24小时内 可以发送1条群发消息 最新公众平台 服务号1个月 30天 内仅可以发送4条群发消息 第三 用户收到信息提醒方式不同 群发信息
  • Golang如何配置国内镜像

    1 打开国内镜像官网 GOPROXY IO 一个全球代理 为 Go 模块而生 2 您只需通过简单设置 PowerShell Windows 配置 GOPROXY 环境变量 env GOPROXY https goproxy io direc
  • Django 快速搭建博客 第六节

    上节我们用模板弄出来第一个hello world 这节课 我们把数据库里面真正的数据跟单篇文章的详情页显示出来 一 模板的下载 这里的模板下载指的是 下载js和css文件 一个网站想要变得漂亮 变得可以稍微好看点 这里我们使用是bootst
  • vue 使用nuxt创建工程

    1 按回车确定项目名称 2 选择语法 3 选择npm 4 选择框架 5 选择请求方式 6 7 8 9 10 11 回车 12 显示下面提示则创建成功 13
  • 数字电路与系统学习笔记(戚金清)

    第一章 数字逻辑基础 1 1模拟信号 模拟电路 数字信号 数字电路 连续变化的物理量是模拟量 表示模拟量的信号是模拟信号 字符数量无限 离散变化的物理量是数字量 表示数字量的信号是数字信号 字符数量有限 构成模拟电路的元件是电子管 模拟计算
  • stm32F4修改时钟频率,更换为8MHz晶振

    stm32F4修改时钟的方法和stm32F103修改时钟的方法不大一样 毕竟库都换了嘛 一个F1的库一个F4的库 而且F1的库默认晶振时钟就是8MHz 大多数开发板也用的8MHz时钟 给我们提供了很多的方便 F1的库关于PLL的写法也很直观
  • access_token

    access token是公众号的全局唯一接口调用凭据 公众号调用各接口时都需使用access token 开发者需要进行妥善保存 access token的存储至少要保留512个字符空间 access token的有效期目前为2个小时 需
  • 【Maven】jar包冲突原因与最优解决方案

    Maven jar包冲突原因与最优解决方案 文章目录 前言 jar包冲突原因 依赖传递 冲突原因 jar包冲突解决方案 Maven默认处理策略 排除依赖 版本锁定 maven shade plugin插件 总结 前言 你是否经常遇到这样的报
  • 机械革命Z2如何Ubuntu安装

    机械革命Z2如何Ubuntu安装 准备 一个4G大的U盘下载了Ubuntu系统 1 首先要进入BIOS F2 关闭Security Boot 设置U盘启动第一启动顺序 2 这个时候将选项移动到此处不要按回车 按E 3 此时 进入编辑模式 大
  • 史上最难HelloWorld

    文章目录 Tomcat Servlet 创建一个项目 引入依赖 创建目录 编写代码 打包 部署 验证 优化一下打包和部署 Smart Tomcat Servlet常见的问题 Tomcat Tomcat就是一个HTTP服务器 HTTP协议是前
  • 语音识别-信号处理篇

    我的书 淘宝购买链接 当当购买链接 京东购买链接 连接前端和后端的语音识别 ASR 的关键是给到后端 根据特征判定词 句 系统的特征类型和特征质量 对于传统的语音识别系统常采用MFCC mel frequency ceptral coeff
  • flutter图片点击跳转_Flutter系列之Platform Channel使用详解

    PS 逐渐体会到关键少数原则的重要性 接下来就是付诸实践了 另外科创50ETF明天开始限额销售 可以适当关注或入手一点 前面几篇文章介绍了 Navigator 组件 Flex 布局 图片加载 Widget 生命周期 混合开发等 Flutte
  • Linux基础教程之/dev/null和/dev/zero的区别及其用法

    在Linux操作系统中 dev null和 dev zero是两个相似却又很特殊的文件 特别是在shell脚本开发和系统运维过程中会经常用这两个文件 因此作为Linux系统工程师 必须了解这两个文件的区别和用法 一 dev null的用法
  • 如何设计一个自动化测试框架?一文从4个点带你梳理一个正确的思路

    在进行自动化框架设计之前我们先来看两个问题 什么是自动化框架 设计的时候应该注意什么原则 然后该怎么做 本文会以一个web端的UI自动化测试框架设计为例 什么是自动化测试框架 什么是框架 特指为解决一个开放性问题而设计的具有一定约束性的支撑
  • QDIALOG 窗口级别模态

    这篇文章内容主要来自 QtQuarterly30 里面的 New Ways of Using QDialog 介绍的是使用QDialog open 这个函数是Qt 4 5 引入的 而不是传统的exec 来实现一个窗口级别的模态对话框 所谓模
  • 一键部署容器化版本,助力开发者快速试用WeDataSphere开源大数据平台套件

    一 部署WeDataSphere开源大数据平台的难点 您是否为搭建包含Hadoop Hive Spark等基础计算存储引擎的WeDataSphere 以下简称WDS 开源大数据平台套件而烦恼 是否希望能有一种简单快捷的方式来完成所有组件的部
  • 王道408计算机网络手写笔记 - 第六章 -应用层

    概览 6 1 网络应用模型 C S模型与P2P模型 1 6 2 域名系统DNS 层次域名 2 域名解析 3 6 3 文件传输协议FTP 4 6 34 电子邮件 MIME 5 SMTP POP3 IMAP 6 6 5 万维网WWW HTTP
  • jmeter对百度首页进行压力测试

    第一次测试 准备工作 在测试计划下添加jp gc Stepping Thread Group 阶梯线程组配置如下 该测试一共启动500个线程 每30秒增加10个 全部线程启动后 保持2分钟 然后每1秒停止5个线程 添加HTTP请求 添加查看
  • matlab:快速傅里叶(反)变换 FFT&IFFT

    文章目录 前言 一 傅里叶变换的离散性与周期性 二 MATLAB 实现快速傅里叶变换 FFT DFT 的计算 三 FFT 频谱的对称性 四 FFT 频谱的频率刻度 五 频谱图的绘制 半谱图 全谱图 六 练习 绘制cos信号的频谱图 半谱图