MATLAB 长度和像素_Matlab中短时傅里叶变换 spectrogram和stft的用法

574ce288095540a66ce39d157245cfb9.png

在Matlab中,做短时傅里叶变换需要使用函数spectrogram,而在Matlab2019中,引入了一个新的函数stft,下面我们就来看下这两个函数都如何使用。

短时傅里叶变换的基本原理就是将数据分段加窗,做fft,在分段时会有overlap,因此一个向量的短时傅里叶变换结果是一个矩阵。了解了这点,下面的函数及参数就更加容易理解了。

spectrogram

参数列表

先来看spectrogram函数,在更早期的版本中,这个函数的名字是specgram,几种常用的用法如下:

spectrogram(x)
s = spectrogram(x)
s = spectrogram(x, window)
s = spectrogram(x, window, noverlap)
s = spectrogram(x, window, noverlap, nfft)
s = spectrogram(x, window, noverlap, nfft, fs)
[s, f, t] = spectrogram(x, window, noverlap, nfft, fs)
[s, f, t] = spectrogram(x, window, noverlap, f, fs)
[s, f, t, p] = spectrogram(x, window, noverlap, f, fs)

其中,

  • x表示输入信号;
  • window表示窗函数,如果window的值是一个整数,那么被分段的x的每一段的长度都等于window,并采用默认的Hamming窗;如果window是一个向量,那么被分段后每一段的长度都等于length(window),且输入的向量即为所要加的窗函数;
  • overlap表示两段之间的重合点数,overlap的值必须要小于窗长,如果没有指定overlap,默认是窗长的一半,即50%的overlap;
  • nfft表示fft的点数,fft的点数跟窗长可以是不同的,当没有指定该参数时,Matlab会取max(256, 2^(ceil(log2(length(window))))),即当窗长小于256时,fft的点数是256;当窗长大于256时,fft的点数取大于窗长的最小的2的整数次幂;
  • fs表示采样率,用来归一化显示使用;
  • f表示显示的频谱范围,f是一个向量,长度跟s的行数相同;
    • 当x是实信号且nfft为偶数时,s的行数为(nfft/2+1)
    • 当x是实信号且nfft为奇数时,s的行数为(nfft+1)/2
    • 当x是复信号时,s的行数为nfft
    • 当在输入的参数列表中指定f后,函数会在f指定的频率处计算频谱图,返回的f跟输入的f是相同的;
  • t表示显示的时间范围,是一个向量,长度跟s的列数相同;
  • p表示功率谱密度,对于实信号,p是各段PSD的单边周期估计;对于复信号,当指定F频率向量时,P为双边PSD;如何计算PSD

Examples

首先,生成信号如下,4个点频信号拼接起来:

clc;clear all;close all;
fs = 10e6;
n = 10000;
f1 = 10e3; f2 = 50e3; f3 = 80e3; f4 = 100e3;
t = (0:n-1)'/fs;
sig1 = cos(2*pi*f1*t);
sig2 = cos(2*pi*f2*t);
sig3 = cos(2*pi*f3*t);
sig4 = cos(2*pi*f4*t);

sig = [sig1; sig2; sig3; sig4];

信号的时域波形如下:

ddc3bc56403b4129db80092ed76553b8.png

直接调用spectrogram(sig),可得如下结果,图中默认横轴是频率,纵轴是时间

8842df4fb07d8383bfcd4f51b7056b78.png

为了绘图更灵活,我们不直接用spectrogram绘图,而且求出s后,再对s单独绘图,这次我们指定window的大小为256

s = spectrogram(sig, 256);
t = linspace(0, 4*n/fs, size(s,1));
f = linspace(0, fs/2, size(s,2));
figure;
imagesc(t, f, 20*log10((abs(s))));xlabel('Samples'); ylabel('Freqency');
colorbar;

e4eba2c792952d31bc112f8ff496fe2e.png

noverlap默认是50%,现在我们把它设为window的长度减1,即每次的步进为1

s = spectrogram(sig, 256, 255);
t = linspace(0, 4*n/fs, size(s,1));
f = linspace(0, fs/2, size(s,2));
figure;
imagesc(t, f, 20*log10((abs(s))));xlabel('Samples'); ylabel('Freqency');
colorbar;

6f3e21ff1fa056319109b562e1b93a67.png

再加上nfftfs参数,我们指定fft点数就是窗长

s = spectrogram(sig, 256, 128, 256, fs);

这个的图形跟之前一样,不再画了

如果在返回值中,增加ft,这样我们下面就不用再重新定义ft

[s, f, t] = spectrogram(sig, 256, 128, 256, fs);
figure;
imagesc(t, f, 20*log10((abs(s))));xlabel('Samples'); ylabel('Freqency');
colorbar;

从上面的图中我们可以看出,我们的4个信号的频率都比较小,而画出来的图显示的频谱范围比较大,导致下面很大一部分信息我们其实都不需要。这时,我们就可以通过指定f的区间来计算频谱。为了显示效果更好,我们把其他参数也调一下

window = 2048;
noverlap = window/2;
f_len = window/2 + 1;
f = linspace(0, 150e3, f_len);
[s, f, t] = spectrogram(sig, window, noverlap , f, fs);
figure;
imagesc(t, f, 20*log10((abs(s))));xlabel('Samples'); ylabel('Freqency');
colorbar;

5cb2098022503237d9246b7e132b5a18.png

最后再把功率谱密度的返回值加上

[s, f, t, p] = spectrogram(sig, window, nfft, f, fs);
figure;
imagesc(t, f, p);xlabel('Samples'); ylabel('Freqency');
colorbar;

caaf91f96f4c2376b58b4b8545c94a44.png

stft

这个函数在Matlab的解释并不是很多,example也只写了两个,但用法比较简单:

window = 2048;
noverlap = window/2;
nfft = window;
[s, f, t, p] = spectrogram(sig, window, noverlap, nfft, fs);
figure;
imagesc(t, f, 20*log10((abs(s))));xlabel('Samples'); ylabel('Freqency');
title('使用spectrogram画出的短时傅里叶变换图形');
colorbar;

ss = stft(sig,fs,'Window',hamming(window),'OverlapLength',window/2,'FFTLength',nfft);
figure;
imagesc(t, f, 20*log10((abs(ss(1024:end,:)))));xlabel('Samples'); ylabel('Freqency');
title('使用stft画出的短时傅里叶变换图形');
colorbar;

2101a149dff7e25cd0b666caead6f0a6.png

欢迎关注微信公众号:Quant_Times

http://weixin.qq.com/r/Mi7t9T3EpWDarXmW93sg (二维码自动识别)

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MATLAB短时傅里叶变换STFT)和逆短时傅里叶变换(ISTFT)是用于时频分析的常用工具。以下是它们的示例代码: 短时傅里叶变换STFT): ```matlab % 定义信号参数 fs = 1000; % 采样频率 t = 0:1/fs:1-1/fs; % 时间向量 f1 = 50; % 信号频率 f2 = 120; % 信号频率 x = cos(2*pi*f1*t) + cos(2*pi*f2*t); % 信号 % 短时傅里叶变换 window = hamming(256); % 窗函数 noverlap = 128; % 重叠长度 nfft = 1024; % FFT长度 [S,F,T] = spectrogram(x,window,noverlap,nfft,fs); % 短时傅里叶变换 % 绘制谱图 figure; surf(T,F,10*log10(abs(S)),'edgecolor','none'); axis tight; view(0,90); xlabel('Time (Seconds)'); ylabel('Hz'); ``` 逆短时傅里叶变换(ISTFT): ```matlab % 设置STFT参数 win = 256; % 窗口大小 hop = 128; % 帧移 nfft = 1024; % FFT大小 % 执行逆变换 x_reconstructed = istft(S, win, hop, nfft); % 绘制原始信号与重构信号的对比 t_reconstructed = (0:length(x_reconstructed)-1) / fs; figure; plot(t, x, 'b', t_reconstructed, x_reconstructed, 'r--'); xlabel('Time (Seconds)'); ylabel('Amplitude'); legend('Original Signal', 'Reconstructed Signal'); ``` 这段代码首先定义了一个包含两个频率分量的信号,并使用`hamming`函数定义了一个长度为256的窗函数。接着,使用`spectrogram`函数进行短时傅里叶变换,并将结果存储在`S`、`F`和`T`。然后,使用`istft`函数执行逆短时傅里叶变换,将频域表示还原为时域信号`x_reconstructed`。最后,绘制原始信号和重构信号的对比图。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值