【问题标题】:how to improve the resolution of the PSD using Matlab如何使用 Matlab 提高 PSD 的分辨率
【发布时间】:2014-03-26 12:57:47
【问题描述】:

我有音频信号,我用 Matlab 读取,并使用 pwelch 获取它的 PSD,这是我正在使用的代码

[x,Fs] = audioread('audioFile.wav');
x= x(:,1) %  mono
[xPSD,f] = pwelch(x,hamming(512),16,1024,Fs);
plot(f,xPSD);

由于FS=96000 和我只对 5khz 以下的频率感兴趣,我想只计算该区域的 PSD,并且还能够调整 PSD 的分辨率!任何想法如何做到这一点!

【问题讨论】:

    标签: matlab signal-processing fft


    【解决方案1】:

    使用pwelch 计算 PSD 时,总是需要在光谱分辨率、平均数和所需数据量之间进行权衡。我首选的使用方式是:

    [psd_x, freq] = pwelch(x, hann(nfft), nfft/2, nfft, fsample);
    

    与您的代码的一些差异:

    1. 我更喜欢使用hann 窗口,因为我对汉明窗口有不好的体验,如果您的信号包含例如大的直流分量,它们就不是很好。请参阅this comparison,这表明hann 的滚降要好得多,唯一的代价是第一旁瓣稍高。

    2. 我使用重叠 50% 的窗口(通过使用 noverlap = nfft/2),这样您就可以“充分利用数据”。在您的情况下,窗口之间只有 16/512 = 3% 的重叠,并且由于窗口函数在其边缘处接近于零,因此边缘处的数据点的贡献不如窗口中间的点那么多。对于半重叠窗口,这种效果要小得多。使重叠大于 50% 是没有用的,你会得到更多的平均值,但由于你会多次使用相同的点,这不会添加任何额外的信息。只要坚持 50%。

    3. 我通常使 fft(pwelch 的第四个参数)的长度与窗口长度相同。唯一需要这种不同的情况是使用 zero-padding,它的用途有限。

    有一些简单的公式,在使用pwelch 和类似函数时应该记住:

    • 光谱分辨率仅由窗口长度给出:df = 1 / t_window

    • 单个窗口的长度为t_window = nfft / f_sample

    • 半重叠窗口,需要的数据总量为t_total = t_window * (n_average + 1) / 2

    • 对于单面光谱,PSD 的光谱箱数为nfft / 2

    • Nyquist:f_max = f_sample / 2

    为了获得相当平滑的频谱,我通常会使用大约 20 个平均值。结合上面的方程并填写所需的光谱分辨率,您就可以得到所需的总数据长度。或者反过来说,如果你只有有限数量的可用数据,你可以计算你可以获得的频率分辨率。

    【讨论】:

    • 感谢您的回答,但是零填充有什么问题?
    • 查看链接的问题,它只会给你“假”的解决方案。它会给你更多的点,但这些在没有零填充的情况下或多或少地形成了你将获得的点之间的平滑插值。您不会神奇地获得额外的光谱分辨率。将其视为信息守恒,如果您使用 1000 个数据点,添加 9000 个零不会给您提供具有 10000 个独立 bin 的频谱。我知道零填充的唯一用例是,如果您想准确确定频谱中单个锐线的频率。
    • 即使在运行零填充后,我仍然得到相同长度的 PSD
    • 你确定吗?要将零填充因子 4,您可能必须执行 pwelch(x, hann(nfft), nfft/2, nfft*4, fsample)。但正如我所说,这可能没用。
    • 零填充并非没有用,即使它只是插值,因为它为高密度或放大绘图产生了非常高质量和平滑的插值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-09
    • 1970-01-01
    • 1970-01-01
    • 2010-10-19
    • 1970-01-01
    • 1970-01-01
    • 2018-09-04
    相关资源
    最近更新 更多