2016-04-26 54 views
0

我想對歌曲做譜圖分析。目前,我從一首歌中獲得大約10秒的剪輯,並試圖找到當地的山峯。在3D譜圖中正確找到MATLAB峯值

我真正想要的是有顯示一些N×N的鄰居值得幅度

[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; 

這導致下面的圖像中的內局部最大值的散點圖:

enter image description here

其中x軸當然是時間[0,〜10],y軸是頻率[0,22.5 KHz],z軸是振幅

現在我發誓d喜歡做的是在這個衝浪上創建一個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),我想只能夠調用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散點圖像這樣:

enter image description here

這是絕對不正確的,因爲應該有整個所示幅度許多局部峯值。我不確定我做錯了什麼,但我也幾乎肯定有一個更簡單的方法來實現我想要的。我真正想要的是有一個散點圖,顯示某個NxN鄰域值振幅的局部最大值

+0

纔有可能獲得訪問該音頻剪輯?我希望能夠重現您的圖表,並幫助您真正繪製您想要的圖表。另外,您沒有正確指定掩碼。你實際上希望中心元素是「真」而不是「假」。這種技術稱爲**非最大值抑制**,它確保窗口的中心元素是最大值,如果不是,則抑制此點。這正是你想要在「N×N×N」3D元素鄰域中找到局部峯值時的情況。 – rayryeng

回答

1

如果我明白你想要的,你有一個矩陣M與本地峯值,你想繪製分散的位置峯。你可以使用sub2ind線性指標使用find和各峯的行\西:

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

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

完美工作,謝謝!我的3x3x3鄰域太緊湊了,所以我把它改成了15x15x15 – ZWiki