短时傅里叶变换函数编写

文章目录

      • 傅里叶变换与短时傅里叶变换
      • 什么是窗?
      • 自己对手实现短时傅里叶变换

傅里叶变换与短时傅里叶变换

在了解短时傅里叶变换之前,首先要知道是什么是傅里叶变换( fourier transformation,FT),傅里叶变换就是将一个信号分解为不同频率的复指数信号的和,例如我们要对一段钢琴曲进行傅里叶变换,它的结果能够告诉我们这一段时间内按下了那些琴键(简单假设为不同琴键对应不同频率的声音),注意我们处理的时长是整个时间段。傅里叶变换的公式可由下面给出:
F ( ω ) = F [ s ( t ) ] = ∫ − ∞ + ∞ s ( t ) e − j ω t d t F(\omega)=\mathcal{F}[s(t)]=\int_{-\infty}^{+\infty} s(t)e^{-j\omega t}dt F(ω)=F[s(t)]=+s(t)etdt
可以看出来,傅里叶变换得到的是一个谱,它是不同频率下对应的幅度谱和相位谱,幅度谱我们用的比较多。利用傅里叶变换能够对信号
进行分析。根据信号是否为周期信号,以及时域上是否连续,又可以分为傅里叶级数展开、离散时间傅里叶变换、离散傅里叶变换等等,在此不再赘述,《信号与系统》和《数字信号处理》的相关书籍介绍很多。
下面是短时傅里叶变换,(short-time fourier transformation,STFT),有时候也叫加窗傅里叶变换,时间窗口使得信号只在某一小区间内有效,这就避免了传统的傅里叶变换在时频局部表达能力上的不足,使得傅里叶变化有了局部定位能力。公式如下:
Ω ( t , f ) = Γ [ s ( t ) ] = ∫ − ∞ + ∞ s ( τ ) ω ( τ − t ) e − j 2 π f τ d τ \Omega(t,f)=\Gamma[s(t)]=\int_{-\infty}^{+\infty} s(\tau)\omega (\tau-t)e^{-j2\pi f \tau }d\tau Ω(t,f)=Γ[s(t)]=+s(τ)ω(τt)ej2πfτdτ
还是以钢琴音乐的信号分析,虽然傅里叶变换能够告诉我们这段音乐中包含那些琴键的声音,但是我们无法知道是在哪些时间点按下这些琴键的。傅里叶变换是一种频域分析共工具,而短时傅里叶变换就是为了解决以上问题而提出的一种时频域方法,后面还有人提出了小波变换。
mailab中可以采用stft函数和spectrogram函数来实现,当然也可以自己动手实现。

什么是窗?

在信号处理中,我们经常听到海明窗(hamming window)、汉宁窗(hanning window)之类的名字,这是什么意思呢?简单来说,窗就是一个函数,它的形状像窗,所以类似的函数都叫窗。
例如我们处理的语音信号一般在10ms到30ms之间,我们可以把它看成是平稳的。为了处理语音信号,我们要对语音信号进行加窗,也就是一次仅处理窗中的数据。因为实际的语音信号是很长的,我们不能也不必对非常长的数据进行一次性处理。明智的解决办法就是每次取一段数据,进行分析,然后再取下一段数据,再进行分析。
怎么仅取一段数据呢,一种方式就是构造一个函数。这个函数在某一区间有非零值,而在其余区间皆为0。汉明窗就是这样的一种函数。它主要部分的形状像 s i n ( x ) sin(x) sin(x)在0到 π \pi π区间的形状,而其余部分都是0,这样的函数乘上其他任何一个函数 f ( x ) f(x) f(x) f ( x ) f(x) f(x)只有一部分有非零值。
为什么海明窗这样取呢,因为之后我们会对海明窗中的数据进行FFT,它假设一个窗内的信号是代表一个周期的信号。(也就是说窗的左端和右端应该大致能连在一起)而通常一小段音频数据没有明显的周期性,加上汉明窗后,数据形状就有点周期的感觉了。
因为加上海明窗,只有中间的数据体现出来了,两边的数据信息丢失了,所以等会移窗的时候,只会移1/3或1/2窗,这样被前一帧或二帧丢失的数据又重新得到了体现。
在matlab中可以借助函数很轻松的生成窗,例如我们要创建一个长度为64点的汉宁窗

L = 64;
wvtool(hann(L))

在这里插入图片描述

自己对手实现短时傅里叶变换

这里参考了知乎笔记matlab短时傅里叶变换
自定义函数如下:

function [STFT, f, t] = mystft(x, win, hop, fs)
% 该函数用于短时傅里叶变换
%  Author:huasir 2023.11.22 @Beijing
% Input : 
%   * x: 输入信号
%   * win:窗,可以采用汉宁窗
%   * hop:窗口滑动的步长,可以为1
%   * fs:采样频率,由输入信号的采样率决定
% Output : 
%    * STFT:短时傅里叶变换的结果,每一列代表某一个窗口下的fft结果,只保留了幅度谱
%    * f: 频率坐标
%    * t: 时间坐标
x = reshape(x,length(x),1); %将向量转为列向量,与后续的点乘相对应
xlen = length(x);%信号长度
wlen = length(win);%窗长度
L = 1+fix((xlen-wlen)/hop);%窗口数目
STFT = zeros(wlen,L);%返回空矩阵
%循环进行傅里叶变换
for k = 0:L-1
    xw = x(1+k*hop : wlen+k*hop).*win; %滑动窗口
    X = fft(xw,wlen); %离散傅里叶变换
    X = fftshift(X);  %将频率按顺序排列:负频率→直流→正频率
    X=abs(X)/wlen*2;  %将fft之后的幅度乘以N/2
    STFT(:,1+k) = X;  %存储
end
%频率坐标
f=linspace(-fs/2,fs/2,wlen);
%时间坐标
t = (wlen/2:hop:wlen/2+(L-1)*hop)/fs;%秒
end

以线性调频信号为例,下面是采用这个自定义函数进行短时傅里叶变换并绘制时频图的代码:

%% 对LFM信号进行短时傅里叶变换
% 主要内容:线性调频信号的生成、雷达回波的模拟、对雷达回波进行短时傅里叶变换
% 短时傅里叶变换采用的是自定义函数
% Author: zhenhualiu 2023.11.22
%=========================================================================%
%                        雷达参数设置                                     %
%=========================================================================%
clear all;close all;clc;
BandWidth = 2.0e6;  %雷达发射信号带宽,带宽=B=1/tau,tau是脉冲宽度
TimeWidth = 40.0e-6; %雷达发射信号的脉冲时宽
PRT = 100e-6;       %雷达发射脉冲重复周期(s),100us对应1/2*100*300=15000米最大无模糊距离
Fs = 4.0e6;         %采样频率
NoisePower = -12;   %噪声功率
SigPower = 1;           %目标功率,无量纲
TargetDistance = 2000;  %目标距离,单位:m,相对于的距离门DelayNumber = fix(Fs*2*TargetDistance/C); %把目标距离换算成采样点(距离门)
plotEnableHigh = 1; %绘图控制符
%=========================================================================%
%             调用函数产生线性调频信号、雷达回波和脉压系数                %
%=========================================================================%
[LFMPulse,targetEchoPRT,matchedFilterCoeff,pulseNumber,PRTNumber] = GenerateLFMSignal(BandWidth,TimeWidth,PRT,Fs,SigPower,TargetDistance,plotEnableHigh);%调用函数
%=========================================================================%
%=========================================================================%
%                  设置窗、步长并进行短时傅里叶变换                       %
%=========================================================================%
wlen=32;%设置窗口长度。窗口越长时间分辨率越差,频率分辨率越好。
hop = 1; %每次平移的步长,最小为1。越小图像时间精度越好,但计算量大。
win = hanning(wlen, 'periodic');%窗函数
figure; %绘制汉宁窗
plot(win);title('汉宁窗');
[S2, f1, t1] = mystft(targetEchoPRT, win, hop, Fs); %采用自定义函数进行短时傅里叶变换
%=========================================================================%
%                     绘制短时傅里叶变换的伪彩色图                        %
%=========================================================================%
figure;
Figure=pcolor(t1,f1,S2); %绘制伪彩色图
colormap('jet'); %指定色系:parula、turbo、jet等等
shading flat;%将每个网格片用同一个颜色进行着色,且网格线也用相应的颜色,从而使得图形表面显得更加光滑。
shading interp;%在网格片内采用颜色插值处理,得出的表面图显得最光滑。
colorbar; %显示图像的颜色条,提供对图像彩色的可视化表示,使得用户能够更直观的理解图像数据的分布和范围

其中生成线性调频信号的函数如下:

function [LFMPulse,targetEchoPRT,matchedFilterCoeff,pulseNumber,PRTNumber] = GenerateLFMSignal(bandWidth,pulseDuration,PRTDuration,samplingFrequency,signalPower,targetDistece,plotEnableHigh)
% 该函数用于产生线性调频信号,以及雷达的目标反射回波,仅产生单个回波
%  Author:huasir 2023.9.21 @Beijing
% Input : 
%   * bandWidth: 信号带宽 ,参考值:2.0e6 表示2MHz
%   * pulseDuration:脉冲持续时间,参考值:40.0e-6 表示40ms
%   * PRTDuration:脉冲重复周期,参考值:240ms
%   * samplingFrequency:采样频率,参考值:2倍的信号带宽
%   * signalPower:信号能量,参考值:1
%   * targetDistece:目标距离,最大无模糊距离由脉冲重复周期决定。计算公式:1/2*PRTDuration*光速
%   * plotEnableHigh: 绘图控制符,1:打开绘图,0:关闭绘图
% Output : 
%    * LFMPulse:线性调频信号
%    * targetEchoPRT: 目标反射回波
%    * matchedFilterCoeff: 匹配滤波器系数
%    * pulseNumber:当前采样率下线性调频信号的采样点数
%    * PRTNumber:1个PRT对应的采样点数
C = 3.0e8;      %光速(m/s)
BandWidth = bandWidth;  %雷达发射信号带宽,带宽=B=1/tau,tau是脉冲宽度
TimeWidth = pulseDuration; %雷达发射信号的脉冲时宽

PRT = PRTDuration;       %雷达发射脉冲重复周期(s),240us对应1/2*240*300=360000米最大无模糊距离
Fs = samplingFrequency;         %采样频率
SampleNumber = fix(Fs*PRT);
%=========================================================================%
%                        目标参数设置                                     %
%=========================================================================%
SigPower = signalPower;           %目标功率,无量纲
TargetDistance = targetDistece; %目标距离,单位:m
DelayNumber = fix(Fs*2*TargetDistance/C); %把目标距离换算成采样点(距离门)
%=========================================================================%
%                        产生线性调频信号、匹配滤波器                     %
%=========================================================================%
number = fix(Fs*TimeWidth); %回波采样点数=脉压系数长度=暂态点数目+1
if rem(number,2)~=0
    nember = nember + 1;
end
Chirp = zeros(1,number);
for i = -fix(number/2):fix(number/2)-1
    Chirp(i+fix(number/2)+1)=exp(1j*(pi*(BandWidth/TimeWidth)*(i/Fs)^2));%产生复ChIrp信号
end
coeff = conj(fliplr(Chirp)); %把Chirp信号翻转并把复数共轭,产生脉压系数
%=========================================================================%
%                      绘制线性调频信号                                   %
%=========================================================================%
if plotEnableHigh == 1
    figure;
    plot(real(Chirp)); %绘制线性调频信号
    xlabel('Sampling points'); ylabel('Amplitude');title('线性调频信号实部');
end
SignalTemp = zeros(1,SampleNumber); %1个PRT
SignalTemp(DelayNumber+1:DelayNumber+number) = sqrt(SigPower)*Chirp;%将线性调频信号按照距离进行延时
if plotEnableHigh == 1
    figure;
    plot(real(SignalTemp)); %绘制1个完整的PRT的雷达回波信号
    xlabel('Range bin'); ylabel('Amplitude');title('雷达回波的实部');
end
%=========================================================================%
%                          进行脉冲压缩                                   %
%=========================================================================%
Echo = SignalTemp; % 目标回波
pc_time0 = conv(Echo,coeff); % 回波和滤波器卷积的结果
pc_time1 = pc_time0(number:number+SampleNumber-1); %去掉暂态点
realTargetRange = find(abs(pc_time1)==max(abs(pc_time1)))-1; %由脉压结果目标距离
fprintf('The target range bin is  %d',realTargetRange);
if plotEnableHigh == 1
    figure; %时域脉压结果
    subplot(2,1,1);plot(abs(pc_time0),'r-');
    xlabel('Range bin'); ylabel('Amplitude');title('时域脉压结果');
    subplot(2,1,2);plot(abs(pc_time1),'r-');
    xlabel('Range bin'); ylabel('Amplitude');title('去掉暂态点的时域脉压结果');
end
%=========================================================================%
%                              返回参数                                   %
%=========================================================================%
LFMPulse = Chirp; %线性调频信号
targetEchoPRT = SignalTemp; %目标反射回波
matchedFilterCoeff = coeff; %匹配滤波器系数
pulseNumber = number; %线性调频信号(仅脉内)的采样点数
PRTNumber = SampleNumber; %目标反射回波(整个PRT)的采样点数
end

绘制的线性调频信号的时域图和时频图如下:
在这里插入图片描述

图1. 线性调频信号时域图

在这里插入图片描述

图2. 线性调频信号时频域图

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/177105.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

吴恩达《机器学习》9-7-9-8:综合起来、自主驾驶

在神经网络的使用过程中,需要经历一系列步骤,从网络结构的选择到训练过程的实施。以下是使用神经网络时的主要步骤的小结: 一、网络结构的选择 输入层: 第一步是选择网络结构,即确定神经网络的层数以及每层的单元数。…

得物前端开发一面面经(等待结果中)

基本情况 上周有幸约到了得物的前端一面,问题都不是很难,但是比较底层,不是八股,而是js的很很细致的东西;且面试官会根据简历去问技术。本篇博客就记录一下这次一面面到的一些技术问题,以及我回答的情况。…

C++ DAY08 异常

概念 异常事件(如:除 0 溢出,数组下标越界,所要读取的文件不存在 , 空指针,内存不足 等等) 在 C 语言对错误的处理是两种方法: 一是使用整型的返回值标识错误; 二是使用 errn…

数字化转型:传统门店突破困境,实现可持续发展的必由之路

自2023年疫情管控基本解除以来,人民群众体验线下消费的意愿充分释放,夜经济、文娱文旅消费、暑期经济等线下消费场景持续走热。据统计,今年1-7月份,我国实体店零售额同比增长4.2%。虽然实体经济出现了消费复苏,发展向好…

【AT模式连接ONENET】ONENET可视化平台的使用

02 ONENET可视化平台的使用 ATCWMODE1 设置模式 ATCWDHCP1,1 启动DHCP功能 ①ATCWJAP"ssid","password" ATCWJAP“123456789”,“wang020118” ②ATMQTTUSERCFG0,1,"设备名字","设备ID","你的鉴权信息""…

气膜体育馆:低碳环保体育新潮流

在追求健康生活的今天,体育运动的重要性无法忽视。为了满足人民日益增长的体育需求,气膜体育馆应运而生,成为体育场馆领域的一次革命性创新。这种新型体育馆解决了传统体育场馆建设中面临的审批难、周期长、门槛高等问题,为我们的…

vue history路径编码

记录今天遇到的一个问题: 问题现状 有一个需要前端伪造302进行重定向的需求,我们需要将这样的一个路径:http://xxx.com/system-name/#/index,拼接在跳转地址的后面,进行重定向。拼接的方式是这样的: htt…

【JavaSE】-4-单层循环结构

回顾 运算符: 算术 --、逻辑 && & || |、比较 、三元 、赋值 int i 1; i; j i; //j2 i3 syso(--j"-----"i) //1 3 选择结构 if(){} if(){}else{} if(){}else if(){}else if(){}else{}//支持byte、short、int //支持char //支持枚举…

2018-2022年富时罗素 ESG评分数据

2018-2022年富时罗素 ESG评分数据 1、时间:2018-2022年 2、指标:证券代码、证券简称、富时罗素ESG评分、 3、说明: 富时罗素ESG评级体系评估了中国大陆、香港、欧洲以及美国等市场上1800家中国上市企业股票,评估了7200多种证券…

每日一练:质因数分解

1. 题目 从键盘输入一个整数,开始整数的质因数分解,最后打印出该整数的所有质因数。 2.解题思路 1)初始化: 从最小的质数开始,将输入的整数不断除以质数,直到无法整除为止。   2)循环&#x…

智能合约安全漏洞与解决方案

// SPDX-License-Identifier: MIT pragma solidity ^0.7.0;import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v3.3/contracts/math/SafeMath.sol";/*智能合约安全在智能合约中安全问题是一个头等大事,因为智能合约不像其他语…

Youtube运营如何打破0播放?你需要的技巧、策略与工具

对于有跨境意向的内容创作者或者品牌企业来说,YouTube是因其巨大的潜在受众群和商业价值成为最值得投入变现与营销计划的平台。 据统计,98% 的美国人每月访问 YouTube,近三分之二的人每天访问。但是,YouTube还远未达到过度饱和的…

好题分享(2023.11.12——2023.11.18)

目录 ​ 前情回顾: 前言: 题目一:《有效括号》 思路: 总结: 题目二:《用队列实现栈》 思路: 总结: 题目三:《用栈实现队列》 思路: 总结 &#x…

CodeWhisperer 一款好玩的 AI 插件

忙里抽闲,今天试了试 CodeWhisperer 这款插件,我是在 IDEA 中做的测试,下面是我的一些使用感想: 安装 CodeWhisperer 插件:在 IntelliJ IDEA 中,可以通过插件管理器安装 CodeWhisperer 插件,然…

ChatGPT 也并非万能,品牌如何搭上 AIGC「快班车」

内容即产品的时代,所见即所得,所得甚至超越所见。 无论是在公域的电商平台、社交媒体,还是品牌私域的官网、社群、小程序,品牌如果想与用户发生连接,内容永远是最前置的第一要素。 01 当内容被消费过,就…

GD32替换STM32使用HAL库开发问题

GD32HAL库开发问题 1can初始化进入error handle2发送邮箱不能按照填写顺序发送3 GD32修改代码被stm32cudemx覆盖问题 1can初始化进入error handle HAL库的HAL_CAN_Init中,hcan->Instance->MSR寄存器无法清零,STM32先清零,再退出睡眠模…

LL(1)语法分析程序设计与实现

制作一个简单的C语言词法分析程序_用c语言编写词法分析程序-CSDN博客文章浏览阅读322次。C语言的程序中,有很单词多符号和保留字。一些单词符号还有对应的左线性文法。所以我们需要先做出一个单词字符表,给出对应的识别码,然后跟据对应的表格…

AMEYA360:村田首款1608M尺寸/100V静电容量1µF的MLCC实现商品化

株式会社村田制作所成功开发了用于基站、服务器和数据中心48V线路的多层陶瓷电容器“GRM188D72A105KE01”并已量产。该产品在1608M(1.60.8mm)尺寸、100V的额定电压下可实现1μF的超大静电容量(村田调查数据,截至2023年11月20日)。目前可向村田申请免费样品。 随着5G…

Python入门教学——输入任意长度的int整型一维数组

使用python输入一个任意长度的整型一维数组: nums input("请输入整数数组,用空格分隔: ") nums [int(i) for i in nums.split( )] # 将每个数转换为整型后输出 运行结果: 【注】如果不强制转换类型,数字…

2023 极客巅峰线上

linkmap 考点: 栈溢出ret2csu栈迁移 保护: 开了 Full RELRO 和 NX, 所以这里不能打 ret2dl 题目给了一些有用的函数: 在这个函数中, 我们可以把一个地址的数据存放到 BSS 段上. 漏洞利用 可以把一个 libc 地址比如 readgot 读取到 bss 上, 然后在修改其为 syscall. 后面就是…