如何对频谱进行重新采样/重采样?

9
在Matlab中,我经常使用Welch方法(pwelch)计算功率谱,然后在对数-对数图上显示。 pwelch估计的频率是等间距的,但对数间距的点更适合于对数-对数图。特别是,在将图保存为PDF文件时,由于高频处的多余点数,会导致文件大小巨大。
有效的方案是什么,可以将线性间距的频谱重新采样(重新分组)为对数间距的频率?或者说,有什么方法可以在PDF文件中包含高分辨率的频谱而不会生成过大的文件大小?
显然,最简单的方法是直接使用interp1
  rate = 16384; %# sample rate (samples/sec)  
  nfft = 16384; %# number of points in the fft

  [Pxx, f] =  pwelch(detrend(data), hanning(nfft), nfft/2, nfft, rate);

  f2 = logspace(log10(f(2)), log10(f(end)), 300);
  Pxx2 = interp1(f, Pxx, f2);

  loglog(f2, sqrt(Pxx2)); 

然而,这种方法并不理想,因为它不能在频谱中保持功率的一致性。例如,如果在两个新频率间存在一个大的频谱线,它将被简单地从结果对数采样频谱中排除。
为了解决这个问题,我们可以插值功率谱的积分部分。
  df = f(2) - f(1);
  intPxx = cumsum(Pxx) * df;                     % integrate
  intPxx2 = interp1(f, intPxx, f2);              % interpolate
  Pxx2 = diff([0 intPxx2]) ./ diff([0 F]);       % difference

这很可爱,而且大部分都起作用,但是频率中心不太正确,并且它不能智能地处理低频区域,在那里频率网格可能变得更加细致。
其他想法:
- 编写一个确定新频率分箱的函数,然后使用accumarray进行重新分箱。 - 在插值之前对谱进行平滑过滤。问题:平滑核大小必须适应所需的对数平滑。 - pwelch函数接受一个频率向量参数f,在这种情况下,它使用Goetzel算法计算所需频率的PSD。也许一开始就使用对数间隔的频率向量调用pwelch就足够了。(这更有效还是更高效?) - 对于PDF文件大小问题:包括光谱的位图图像(看起来有点难搞,我想要漂亮的矢量图形!); - 或者显示一个区域(多边形/置信区间),而不仅仅是分段线来指示光谱。
3个回答

2
我会让它为我工作,并从一开始就提供频率。文档规定,您指定的频率将四舍五入到最近的DFT bin。这不应该是问题,因为您使用结果进行绘图。如果您担心运行时间,建议尝试并计时。
如果您想自己重新分组,我认为最好编写自己的函数以对每个新bin进行积分。如果您想让生活变得更轻松,可以像他们一样确保您的对数bin与线性bin共享边界。

这种方法的问题在于平均数的数量是由最低频率(最高分辨率)的bin设置的。我们在高频率处得到较少的点(如所需),但我们没有获得在较高频率下更多平均数的优势。 - nibot

1

找到解决方案:https://dsp.stackexchange.com/a/2098/64

简而言之,解决此问题的一种方法是使用频率相关的变换长度执行Welch方法。上面的链接是指向一个包含论文引用和示例实现的dsp.SE答案。这种技术的缺点是不能使用FFT,但由于计算的DFT点数大大减少,因此这不是一个严重的问题。


0
如果你想在可变速率 (对数) 下重新取样 FFT,那么平滑或低通滤波器核的宽度也需要是可变的,以避免混叠现象(采样点的丢失)。只需为每个绘图点使用不同宽度的 Sync 插值核(Sync 宽度大约是本地采样率的倒数就行了)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接