【发布时间】: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 doubleF: 513 x 1 doubleT: 1 x 1770 doubleP: 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 N3D 元素邻域中找到局部峰值时,这正是您所追求的。
标签: matlab signal-processing spectrogram