我试图在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);
答案 0 :(得分:2)
我不确定你的问题究竟是什么,但我想问题是,使用提供的代码,你没有得到类似于你所获得的情节,例如surf
此外,我也不太清楚你为什么要使用plot3
,也许是为了获得时间和频率上的标签?您可以使用surf
surf(T, F, sp_frame_array,'EdgeColor','none');
事实上,plot3
没有给出相同数字的原因是因为plot3
的参数必须是相同大小的三个矩阵(在{{1}上检查它) })。根据我的测试,你的代码实际上应该在Matlab上被破坏,而不是它。好吧,再一次Matlab允许人们在没有警告的情况下乱七八糟(去Python!:D)......无论如何,尝试设置矩阵更像下面这样:
help plot3
虽然这通常会产生更符合我在绘制光谱图时的预期,但我仍会发表一些评论:
您的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
,因为您填充Fs
的方式。更具体地说,它应该从0Hz变为sp_frame_dft
:
Fs - Fs/rows
您可能希望以dB为单位绘制幅度:
F = linspace(0,Fs*(1-1/rows)/1000,rows); % in kHz
plot3(Tmat,Fmat,db(sp_frame_array));
每列提供的矩阵绘制一行。这意味着有很多线条可供绘制!正如@ atul-ingle所问,你确定这是你想要的吗?也许plot3
能以更低的成本提供更好的渲染效果吗?
waterfall
好吧,你会获得行而不是列的行,所以你可能需要转置,如果后者是你想要的。
希望有所帮助!