我正在尝试对一首歌进行频谱图分析。目前我从一首歌中得到大约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轴是幅度
现在我想做的是在这个海浪上创建一个三维散点图,以显示峰值的位置。 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)
,我希望能够以我称之为冲浪的方式呼叫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邻域内的局部最大值
答案 0 :(得分:1)
如果我理解你想要的,你有一个带有局部峰的矩阵M
,你想要在峰的位置绘制散射。您可以使用find
获取每个峰的行\ col,使用sub2ind
获取线性索引:
[Fi,Ti] = find(10*log10(P) > dil);
Pi = sub2ind(size(P),Fi,Ti);
scatter3(T(Ti),F(Fi),amp(Pi));