1

MATLABでplot3を使用してSTFTをプロットしようとしましたが、失敗しました。誰かが私にそれを行う方法を教えてもらえますか?私のMWEは以下のとおりです。

%% STFT Computataion
clear; clc; clf;

%% Get input and calculate frame size and overlap/shift
[Y,Fs]=wavread('D_NEHU_F0001_MN_10001');
frame_size=round(20*Fs/1000);         % calculate frame size for 20ms
frame_shift=round(10*Fs/1000);        % calculate frame shift for 10ms

%% Plot the input signal in time domain
t=1/Fs:1/Fs:(length(Y)/Fs);
subplot(2,1,1)
    plot(t,Y);
    title('Speech signal in time domain');
    ylabel('Magnitude of samples');
    xlabel('time in seconds');

%% Calculation of STFT
%NoOfFrames=floor((length(Y)/frame_shift)-1);
NoOfFrames=length(Y)-frame_size;
j=1;
%for i=1:frame_shift:(length(Y)-frame_size)
for i=1:frame_shift:((length(Y)-frame_size))%+frame_shift)
    sp_frame=Y(i:(i+frame_size)).*hamming(frame_size+1);
    sp_frame_dft=abs(fft(sp_frame)); % Compute STFT
    sp_frame_array(:,j)=sp_frame_dft;
    j=j+1;
end

%% Plot the STFT in 3D
[rows,cols]=size(sp_frame_array);
F=linspace(1/Fs,Fs/2000,cols);
T=1/Fs:(frame_shift*Fs/1000):(cols*(frame_shift*Fs/1000));
Z=1:frame_size+1;
subplot(2,1,2)
    %mesh(sp_frame_array);
    %surf(sp_frame_array,'EdgeColor','none');
   plot3(T,F,sp_frame_array);
4

1 に答える 1

2

あなたの質問が正確に何であるかはわかりませんが、問題は、提供されたコードでは、たとえば、で得られるものと同様のプロットが得られないことだと思いますsurf

さらに、plot3時間と頻度のラベルを正しく取得するために、なぜ使用するのかよくわかりません。あなたはそれをすべて同じように行うことができますsurf

surf(T, F, sp_frame_array,'EdgeColor','none');

実際のところ、あなたplot3が同じ数字を与えない理由は、の引数がplot3同じサイズの3つの行列でなければならないからです(でそれをチェックしてくださいhelp plot3)。私のテストによると、コードは実際にはMatlabで壊れているはずですが、そうではありません。さて、もう一度、Matlabを使用すると、警告なしに混乱することができます(Pythonに移動してください!:D)...とにかく、行列を次のように設定してみてください。

F=linspace(1/Fs,Fs/2000, rows); % note: has to be rows, not cols here!
Fmat = F(:) * ones(1,cols); % or use repmat
T=1/Fs:(frame_shift*Fs/1000):(cols*(frame_shift*Fs/1000));
Tmat = ones(rows,1) * T(:)';

plot3(Tmat,Fmat,sp_frame_array);

これは通常、スペクトログラムを描くときに期待するものとより一致するものを生成しますが、それでもいくつかの意見を述べます。

  • あなたが記入した方法のために、あなたのFベクトルはまで上がるはずです。より具体的には、それは0Hzから:まで行くべきです。Fssp_frame_dftFs - Fs/rows

    F = linspace(0,Fs*(1-1/rows)/1000,rows); % in kHz
    
  • おそらく、振幅をdB単位で描画したいと思うでしょう。

    plot3(Tmat,Fmat,db(sp_frame_array));
    

plot3の結果

  • plot3提供された行列の列ごとに1本の線を描画します。つまり、描画する線がたくさんある可能性があります。@ atul-ingleが尋ねたように、これがあなたが望むものであると確信していますか?たぶんwaterfall、より低いコストでより良いレンダリングを提供するでしょうか?

    waterfall(T,F,db(sp_frame_array));
    

滝の結果

ええと、列の代わりに行の行を取得するので、後者が必要な場合は転置する必要があるかもしれません。

  • また、マトリックスの前半のみを視覚化することもできます(Fs / 2より高い周波数は、マトリックスの残りの半分のミラーにすぎないため)。

お役に立てば幸いです。

于 2013-01-27T21:07:35.147 に答える