【问题标题】:Properly finding peaks in MATLAB in 3D spectrogram在 MATLAB 中正确查找 3D 频谱图中的峰值
【发布时间】:2016-04-26 05:02:56
【问题描述】:

我正在尝试对一首歌曲进行频谱图分析。目前,我有大约 10 秒的歌曲片段,并且正在尝试找到当地的峰值。

我真正想要的是有一个散点图显示一些 NxN 邻域的振幅值内的局部最大值

[y,fs] = audioread('audio_file.wav');
window = hamming(512);
num_overlap = 256;
nfft = 1024;
[S,F,T,P] = spectrogram(y(:,1), window, num_overlap, nfft, fs, 'yaxis');
surf(T,F,10*log10(P), 'edgecolor', 'none'); axis tight; view(0, 90); colormap hot;

结果如下图:

x 轴当然是时间 [0,~10],y 轴是频率 [0,22.5 KHz],z 轴是幅度

现在我想做的是在这个冲浪上创建一个 3D 散点图来显示峰值的位置。 S、F、T、P的尺寸分别为
S: 513 x 1770 complex double
F: 513 x 1 double
T: 1 x 1770 double
P: 513 x 1770 double

现在我很确定我做错了什么或者完全不理解 MATLAB。

msk = true(3,3,3);
msk(2,2,2) = false;
dil = imdilate(10*log10(P), msk);
M = 10*log10(P) > dil;

我的理解是,无论我的本地高峰在哪里,我都会得到一个1

现在让我们说 amp = 10*log10(P),我希望能够像调用 surf 一样调用 scatter3,如下所示:

scatter3(T, F, amp(M))

但我当然会得到X, Y and Z must be vectors of the same length.,我想这对我来说很有意义,所以我决定根据需要重复这些值以使坐标轴相等。

Tr = repelem(T, 513)';
Fr = repelem(F, 1770);
Zr = reshape(amp, [908010, 1]);
[pks, locs] = findpeaks(Zr);
scatter3(Tr(locs), Fr(locs), Zr(locs));

这会产生一个像这样的 3D 散点图:

这绝对是不对的,因为在显示的幅度中应该有许多局部峰值。我不确定我做错了什么,但我也几乎肯定有一种更简单的方法可以实现我想要的。我真正想要的是有一个散点图显示一些 NxN 邻域的振幅值内的局部最大值

【问题讨论】:

  • 是否可以访问该音频剪辑?我希望能够重现您的图表并帮助您实际绘制您想要的内容。此外,您没有正确指定掩码。您实际上希望中心元素是true 而不是false。这种技术称为非最大值抑制,它确保窗口的中心元素是最大值,如果不是,则抑制该点。当您想在 N x N x N 3D 元素邻域中找到局部峰值时,这正是您所追求的。

标签: matlab signal-processing spectrogram


【解决方案1】:

如果我知道你想要的话,你有一个矩阵 M 带有局部峰值,并且你想在峰值的位置绘制散点图。您可以使用find 获取每个峰的行\列,使用sub2ind 获取线性索引:

[Fi,Ti] = find(10*log10(P) > dil);
Pi = sub2ind(size(P),Fi,Ti);

scatter3(T(Ti),F(Fi),amp(Pi));

【讨论】:

  • 完美运行,谢谢!我的 3x3x3 邻域过于紧凑,所以我将其更改为 15x15x15
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-09
  • 1970-01-01
  • 2017-12-19
  • 2014-04-24
  • 2014-08-30
  • 1970-01-01
相关资源
最近更新 更多