主要内容

spectrogram

使用短时傅里叶变换的谱图

说明

信号的频谱图是其短时傅里叶变换 (STFT) 的幅值平方。STFT 描述信号的频率成分随时间的变化情况。

s = spectrogram(x) 返回信号 x 的 STFT。s 的每一列都包含 x 的短期时间局部化频率成分的估计值。

示例

[s,f,t] = spectrogram(x,win,nOverlap,freqSpec) 返回信号 x 的 STFT 以及频率 f(弧度/采样点)和采样索引 t,其中 spectrogram 函数:

  • 使用 win 将信号分段并对其加窗。

  • 使用 nOverlap 中指定的重叠长度来重叠相邻段之间的采样。

  • freqSpec 中指定的点数或频率处计算每个加窗段的离散傅里叶变换。

要对这些输入参量中的任一个使用默认值,请将它们指定为空,即 []

示例

[s,f,t] = spectrogram(x,win,nOverlap,freqSpec,Fs) 指定采样率 Fs 并返回周期性频率 f (Hz) 和时刻 t

示例

[___,ps] = spectrogram(___,freqRange,spectrumType) 还指定要在 ps 中返回的频率范围和频谱类型,该返回值与 x 的频谱图成正比。将 ps 以功率谱密度 (PSD) 估计值或功率谱估计值形式返回。您可以指定这两个输入参量中的任一个或同时指定两个。

示例

[___,fc,tc] = spectrogram(___,"reassigned") 将每个 PSD 估计值或功率谱估计值重新分配给其能量中心的位置。此语法还返回能量中心频率和时间,即 fctc

如果您的信号包含定位良好的时序分量或频谱分量,则 "reassigned" 参量会生成更清晰的谱图。

示例

[___] = spectrogram(___,"yaxis",Name=Value) 使用名称-值参量指定附加选项。您可以指定最小阈值、输出时间维度和用于绘制频谱图的目标父容器。

如果指定目标父容器,则 "yaxis" 选项在 ps 的图中将频率显示在 y 轴上,将时间显示在 x 轴上。

示例

不带输出参量的 spectrogram(___) 在当前图窗窗口或指定的目标父容器中绘制 ps(以分贝为单位)。

示例

示例

全部折叠

生成一个信号的 Nx=1024 个采样,该信号由正弦波之和组成。正弦波的归一化频率为 2π/5 弧度/采样和 4π/5 弧度/采样。较高频率正弦波的振幅是另一个正弦波的 10 倍。

N = 1024;
n = 0:N-1;

w0 = 2*pi/5;
x = sin(w0*n)+10*sin(2*w0*n);

使用函数默认值计算短时傅里叶变换。绘制谱图。

s = spectrogram(x);

spectrogram(x,"yaxis")

Figure contains an axes object. The axes object with title Spectrogram, xlabel Samples, ylabel Normalized Frequency ( times pi radians/sample) contains an object of type image.

重复该计算。

  • 将信号分成长度为 nsc=Nx/4.5 的若干段。

  • 使用汉明窗对这些段进行加窗处理。

  • 指定连续段之间的重叠率为 50%。

  • 为了计算 FFT,请使用 max(256,2p) 个点,其中 p=log2nsc

验证这两种方法是否给出相同的结果。

Nx = length(x);
nsc = floor(Nx/4.5);
nov = floor(nsc/2);
nff = max(256,2^nextpow2(nsc));

t = spectrogram(x,hamming(nsc),nov,nff);

maxerr = max(abs(abs(t(:))-abs(s(:))))
maxerr = 
0

将信号分成 8 个等长的段,段之间的重叠率为 50%。指定与上一步相同的 FFT 长度。计算短时傅里叶变换,并验证它是否与前两个过程的结果相同。

ns = 8;
ov = 0.5;
lsc = floor(Nx/(ns-(ns-1)*ov));

t = spectrogram(x,lsc,floor(ov*lsc),nff);

maxerr = max(abs(abs(t(:))-abs(s(:))))
maxerr = 
0

生成一个信号,该信号由在 600 Hz 下采样 2 秒的复数值凸二次啁啾组成。啁啾的初始频率为 250 Hz,最终频率为 50 Hz。

fs = 6e2;
ts = 0:1/fs:2;
x = chirp(ts,250,ts(end),50,"quadratic",0,"convex","complex");

spectrogram 函数

使用 spectrogram 函数计算信号的 STFT。

  • 将信号分成若干段,每段的长度为 M=49 个采样。

  • 指定相邻段之间有 L=11 个采样的重叠。

  • 丢弃最后的较短段。

  • 使用巴特利窗对每个段加窗。

  • NDFT=1024 个点的每个段计算离散傅里叶变换。默认情况下,spectrogram 计算复数值信号的双边变换。

M = 49;
L = 11;
g = bartlett(M);
Ndft = 1024;

[s,f,t] = spectrogram(x,g,L,Ndft,fs);

使用 waterplot 函数计算并显示谱图,定义为 STFT 的幅值平方。

waterplot(s,f,t)

Figure contains an axes object. The axes object with xlabel Frequency (Hz), ylabel Time (s) contains an object of type patch.

STFT 定义

使用定义计算长度为 Nx 个采样的信号的 STFT。将信号分成 Nx-LM-L 个重叠段。对每个段加窗并在 NDFT 个点处计算其离散傅里叶变换。

segs = framesig(1:length(x),M,OverlapLength=L);
X = fft(x(segs).*g,Ndft);

计算 STFT 的时间范围和频率范围。

  • 要找到时间值,请将时间向量分成若干重叠段。时间值是段的中点,每个段被视为下端开放的区间。

  • 要找到频率值,请指定在零频率处闭合、在下端开放的奈奎斯特区间。

framedT = ts(segs);
tint = mean(framedT(2:end,:));

fint = 0:fs/Ndft:fs-fs/Ndft;

spectrogram 的输出与定义进行比较。显示谱图。

maxdiff = max(max(abs(s-X)))
maxdiff = 
0
waterplot(X,fint,tint)

Figure contains an axes object. The axes object with xlabel Frequency (Hz), ylabel Time (s) contains an object of type patch.

function waterplot(s,f,t)
% Waterfall plot of spectrogram
    waterfall(f,t,abs(s)'.^2)
    set(gca,XDir="reverse",View=[30 50])
    xlabel("Frequency (Hz)")
    ylabel("Time (s)")
end

生成一个由在 1.4 kHz 下采样 2 秒的啁啾组成的信号。在测量时间内,啁啾的频率从 600 Hz 线性增加到 100 Hz。

fs = 1400;
x = chirp(0:1/fs:2,600,2,100);

stft 默认值

使用 spectrogramstft 函数计算信号的 STFT。使用 stft 函数的默认值:

  • 将信号分成若干长度为 128 个采样的段,并使用周期性汉宁窗对每个段加窗。

  • 指定相邻段之间有 96 个采样的重叠。此长度等效于窗长度的 75%。

  • 指定 128 个 DFT 点并将 STFT 中心设在零频率处,频率以赫兹为单位表示。

验证两个结果是否相等。

M = 128;
g = hann(M,"periodic");
L = 0.75*M;
Ndft = 128;

[sp,fp,tp] = spectrogram(x,g,L,Ndft,fs,"centered");

[s,f,t] = stft(x,fs);

dff = max(max(abs(sp-s)))
dff = 
0

使用 mesh 函数绘制两个输出。

nexttile
mesh(tp,fp,abs(sp).^2)
title("spectrogram")
view(2), axis tight

nexttile
mesh(t,f,abs(s).^2)
title("stft")
view(2), axis tight

Figure contains 2 axes objects. Axes object 1 with title spectrogram contains an object of type surface. Axes object 2 with title stft contains an object of type surface.

spectrogram 默认值

使用 spectrogram 函数的默认值重复计算:

  • 将信号分成长度为 M=Nx/4.5 的段,其中 Nx 是信号的长度。使用汉明窗对每个段加窗。

  • 指定段之间有 50% 的重叠。

  • 为了计算 FFT,请使用 max(256,2log2M) 个点。仅计算正归一化频率的频谱图。

M = floor(length(x)/4.5);
g = hamming(M);
L = floor(M/2);
Ndft = max(256,2^nextpow2(M));

[sx,fx,tx] = spectrogram(x);

[st,ft,tt] = stft(x,Window=g,OverlapLength=L, ...
    FFTLength=Ndft,FrequencyRange="onesided");

dff = max(max(sx-st))
dff = 
0

使用 waterplot 函数绘制两个输出。在这两种情况下都将频率轴除以 π。对于 stft 输出,将采样数除以有效采样率 2π

figure
nexttile
waterplot(sx,fx/pi,tx)
title("spectrogram")

nexttile
waterplot(st,ft/pi,tt/(2*pi))
title("stft")

Figure contains 2 axes objects. Axes object 1 with title spectrogram, xlabel Frequency/\pi, ylabel Samples contains an object of type patch. Axes object 2 with title stft, xlabel Frequency/\pi, ylabel Samples contains an object of type patch.

function waterplot(s,f,t)
% Waterfall plot of spectrogram
    waterfall(f,t,abs(s)'.^2)
    set(gca,XDir="reverse",View=[30 50])
    xlabel("Frequency/\pi")
    ylabel("Samples")
end

使用 spectrogram 函数测量和跟踪信号的瞬时频率。

生成以 1 kHz 采样的时长为两秒的二次啁啾。指定啁啾的最初频率为 100 Hz,一秒后增加到 200 Hz。

fs = 1000;
t = 0:1/fs:2-1/fs;
y = chirp(t,100,1,200,"quadratic");

使用通过 spectrogram 函数实现的短时傅里叶变换来估计啁啾的频谱。将信号分成长度为 100 的段,使用汉明窗加窗。指定相邻段之间有 80 个采样的重叠,并在 100/2+1=51 个频率处计算频谱。

spectrogram(y,100,80,100,fs,"yaxis")

Figure contains an axes object. The axes object with title Spectrogram, xlabel Time (s), ylabel Frequency (Hz) contains an object of type image.

通过找到在 (2000-80)/(100-80)=96 个时间点上具有最高能量的时频脊来跟踪啁啾频率。在谱图上叠加瞬时频率。

[~,f,t,p] = spectrogram(y,100,80,100,fs);

[fridge,~,lr] = tfridge(p,f);

hold on
plot3(t,fridge,abs(p(lr)),LineWidth=2)
hold off

Figure contains an axes object. The axes object with title Spectrogram, xlabel Time (s), ylabel Frequency (Hz) contains 2 objects of type image, line.

生成一个啁啾的 512 个采样,其频率成分呈正弦变化。

N = 512;
n = 0:N-1;

x = exp(1j*pi*sin(8*n/N)*32);

计算啁啾的居中双边短时傅里叶变换。将该信号分成若干长度为 32 个采样的段,段之间重叠 16 个采样。指定 64 个 DFT 点。绘制谱图。

[scalar,fs,ts] = spectrogram(x,32,16,64,"centered");

spectrogram(x,32,16,64,"centered","yaxis")

Figure contains an axes object. The axes object with title Spectrogram, xlabel Samples, ylabel Normalized Frequency ( times pi radians/sample) contains an object of type image.

通过在区间 (-π,π] 上计算 64 个等间距频率的谱图获得相同的结果。'centered' 选项不是必需的。

fintv = -pi+pi/32:pi/32:pi;

[vector,fv,tv] = spectrogram(x,32,16,fintv);

spectrogram(x,32,16,fintv,"yaxis")

Figure contains an axes object. The axes object with title Spectrogram, xlabel Samples, ylabel Normalized Frequency ( times pi radians/sample) contains an object of type image.

生成一个由压控振荡器和三个高斯原子组成的信号。信号在 fs=2 kHz 下采样 2 秒。

fs = 2000;
tx = 0:1/fs:2;
gaussFun = @(A,x,mu,f) exp(-(x-mu).^2/(2*0.03^2)).*sin(2*pi*f.*x)*A';
s = gaussFun([1 1 1],tx',[0.1 0.65 1],[2 6 2]*100)*1.5;
x = vco(chirp(tx+.1,0,tx(end),3).*exp(-2*(tx-1).^2),[0.1 0.4]*fs,fs);
x = s+x';

短时傅里叶变换

使用 pspectrum 函数计算 STFT。

  • Nx 采样信号分成长度为 M=80 个采样的段,对应的时间分辨率为 80/2000=40 毫秒。

  • 指定相邻段之间有 L=16 个采样或 20% 的重叠。

  • 使用凯塞窗对每个段加窗,并指定泄漏 =0.7

M = 80;
L = 16;
lk = 0.7;

[S,F,T] = pspectrum(x,fs,"spectrogram", ...
    TimeResolution=M/fs,OverlapPercent=L/M*100, ...
    Leakage=lk);

与使用 spectrogram 函数获得的结果进行比较。

  • 直接以采样为单位指定窗长度和重叠。

  • pspectrum 始终使用凯塞窗作为 g(n)。窗的泄漏 和形状因子 β 的关系是 β=40×(1-)

  • pspectrum 在计算离散傅里叶变换时始终使用 NDFT=1024 个点。如果您要计算在双边或居中频率范围内的变换,可以指定此数字。但是,对于单边变换(实信号的默认变换),spectrogram 使用 1024/2+1=513 个点。您也可以指定要在其上计算变换的频率向量,如此示例中所示。

  • 如果信号无法整除分成 k=Nx-LM-L 个段,spectrogram 会截断信号,而 pspectrum 会用零填充信号以创建一个额外的段。为了使输出等效,请删除最后一个段和时间向量的最后一个元素。

  • spectrogram 返回 STFT,其幅值平方是谱图。pspectrum 返回逐段功率谱,该功率谱已平方,但在平方之前除以因子 ng(n)

  • 对于单边变换,pspectrum 向谱图添加额外的因子 2。

g = kaiser(M,40*(1-lk));

k = (length(x)-L)/(M-L);
if k~=floor(k)
    S = S(:,1:floor(k));
    T = T(1:floor(k));
end

[s,f,t] = spectrogram(x/sum(g)*sqrt(2),g,L,F,fs);

使用 waterplot 函数显示由两个函数计算的谱图。

subplot(2,1,1)
waterplot(sqrt(S),F,T)
title("pspectrum")

subplot(2,1,2)
waterplot(s,f,t)
title("spectrogram")

Figure contains 2 axes objects. Axes object 1 with title pspectrum, xlabel Frequency (Hz), ylabel Time (s) contains an object of type patch. Axes object 2 with title spectrogram, xlabel Frequency (Hz), ylabel Time (s) contains an object of type patch.

maxd = max(max(abs(abs(s).^2-S)))
maxd = 
2.4419e-08

功率谱图和便捷图

spectrogram 函数有第四个参量,对应于逐段功率谱或功率谱密度。与 pspectrum 的输出类似,ps 参量已平方并包括归一化因子 ng(n)。对于实信号的单边谱图,您仍必须包括额外的因子 2。将函数的缩放参量设置为 "power"

[~,~,~,ps] = spectrogram(x*sqrt(2),g,L,F,fs,"power");

max(abs(S(:)-ps(:)))
ans = 
2.4419e-08

当以不带输出参量形式被调用时,pspectrumspectrogram 都以分贝为单位绘制信号的谱图。对于单边谱图,包括因子 2。将两个图的颜色图设置为相同。将 x 范围设置为相同的值,以使 pspectrum 图末尾的额外段可见。在 spectrogram 图中,在 y 轴上显示频率。

subplot(2,1,1)
pspectrum(x,fs,"spectrogram", ...
    TimeResolution=M/fs,OverlapPercent=L/M*100, ...
    Leakage=lk)
title("pspectrum")
cc = clim;
xl = xlim;

subplot(2,1,2)
spectrogram(x*sqrt(2),g,L,F,fs,"power","yaxis")
title("spectrogram")
clim(cc)
xlim(xl)

Figure contains 2 axes objects. Axes object 1 with title pspectrum, xlabel Time (s), ylabel Frequency (kHz) contains an object of type image. Axes object 2 with title spectrogram, xlabel Time (s), ylabel Frequency (kHz) contains an object of type image.

function waterplot(s,f,t)
% Waterfall plot of spectrogram
    waterfall(f,t,abs(s)'.^2)
    set(gca,XDir="reverse",View=[30 50])
    xlabel("Frequency (Hz)")
    ylabel("Time (s)")
end

生成在 1 kHz 下采样 2 秒的啁啾信号。指定啁啾的最初频率为 100 Hz,1 秒后增加到 200 Hz。

fs = 1000;
t = 0:1/fs:2;
y = chirp(t,100,1,200,"quadratic");

估计重排后的信号谱图。

  • 将信号分成长度为 128 的段,使用形状参数为 β=18 的凯塞窗加窗。

  • 指定相邻段之间有 120 个采样的重叠。

  • 128/2=65 个频率和 (length(x)-120)/(128-120)=235 个时间 bin 处计算频谱。

使用不带输出参量的 spectrogram 函数绘制重排后的谱图。在 y 轴上显示频率,在 x 轴上显示时间。

spectrogram(y,kaiser(128,18),120,128,fs,"reassigned","yaxis")

Figure contains an axes object. The axes object with title Spectrogram, xlabel Time (s), ylabel Frequency (Hz) contains an object of type image.

使用 imagesc 函数重新绘图。指定 y 轴方向,使频率值从下到上增大。向重排后的谱图添加 eps 以避免转换为分贝时可能出现的负无穷大。

[~,fr,tr,pxx] = spectrogram(y,kaiser(128,18),120,128,fs,"reassigned");

imagesc(tr,fr,pow2db(pxx+eps))
axis xy
xlabel("Time (s)")
ylabel("Frequency (Hz)")
colorbar

Figure contains an axes object. The axes object with xlabel Time (s), ylabel Frequency (Hz) contains an object of type image.

生成在 1 kHz 下采样 2 秒的啁啾信号。指定啁啾的最初频率为 100 Hz,1 秒后增加到 200 Hz。

Fs = 1000;
t = 0:1/Fs:2;
y = chirp(t,100,1,200,"quadratic");

估计信号的时间相关功率谱密度 (PSD)。

  • 将信号分成长度为 128 的段,使用形状参数为 β=18 的凯塞窗加窗。

  • 指定相邻段之间有 120 个采样的重叠。

  • 128/2=65 个频率和 (length(x)-120)/(128-120)=235 个时间 bin 处计算频谱。

输出每个 PSD 估计值的重心的频率和时间。将小于 -30 dB 的 PSD 元素设置为零。

[~,~,~,pxx,fc,tc] = spectrogram(y,kaiser(128,18),120,128,Fs, ...
    MinThreshold=-30);

将非零元素绘制为重心频率和时间的函数。

plot(tc(pxx>0),fc(pxx>0),".")

Figure contains an axes object. The axes contains a line object which displays its values using only markers.

生成一个信号,该信号由在 2 kHz 下采样 2 秒的实数值啁啾组成。

fs = 2000;
tx = 0:1/fs:2;
x = vco(-chirp(tx,0,tx(end),2).*exp(-3*(tx-1).^2), ...
    [0.1 0.4]*fs,fs).*hann(length(tx))';

双边谱图

计算并绘制信号的双边 STFT。

  • 将信号分成若干段,每段的长度为 M=73 个采样。

  • 指定相邻段之间有 L=24 个采样的重叠。

  • 丢弃最后的较短段。

  • 使用平顶窗对每个段加窗。

  • NDFT=895(注意这是奇数)个点的每个段处计算离散傅里叶变换。

M = 73;
L = 24;
g = flattopwin(M);
Ndft = 895;
neven = ~mod(Ndft,2);

[stwo,f,t] = spectrogram(x,g,L,Ndft,fs,"twosided");

使用不带输出参量的 spectrogram 函数绘制双边谱图。

spectrogram(x,g,L,Ndft,fs,"twosided","power","yaxis")

Figure contains an axes object. The axes object with title Spectrogram, xlabel Time (s), ylabel Frequency (kHz) contains an object of type image.

使用定义计算双边谱图。将信号分成长度为 M 个采样的段,相邻段之间有 L 个采样的重叠。对每个段加窗并在 NDFT 个点处计算其离散傅里叶变换。

y = framesig(x,M,Window=g,OverlapLength=L);
Xtwo = fft(y,Ndft);

计算时间和频率范围。

  • 要找到时间值,请将时间向量分成若干重叠段。时间值是段的中点,每个段被视为下端开放的区间。

  • 要找到频率值,请指定在零频率处闭合、在上端开放的奈奎斯特区间。

framedT = framesig(tx,M,OverlapLength=L);
ttwo = mean(framedT(2:end,:));

ftwo = 0:fs/Ndft:fs*(1-1/Ndft);

spectrogram 的输出与定义进行比较。使用 waterplot 函数显示谱图。

diffs = [max(max(abs(stwo-Xtwo)));
    max(abs(f-ftwo'));
    max(abs(t-ttwo))]
diffs = 3×1
10-12 ×

         0
    0.2274
    0.0002

figure
nexttile
waterplot(Xtwo,ftwo,ttwo)
title("Two-Sided, Definition")

nexttile
waterplot(stwo,f,t)
title("Two-Sided, spectrogram Function")

Figure contains 2 axes objects. Axes object 1 with title Two-Sided, Definition, xlabel Frequency (Hz), ylabel Time (s) contains an object of type patch. Axes object 2 with title Two-Sided, spectrogram Function, xlabel Frequency (Hz), ylabel Time (s) contains an object of type patch.

居中谱图

计算信号的居中谱图。

  • 使用与用于双边 STFT 相同的时间值。

  • 使用 fftshift 函数将 STFT 的零频率分量移至频谱中心。

  • 对于奇数值 NDFT,频率区间在两端开放。对于偶数值 NDFT,频率区间在下端开放、在上端闭合。

比较输出并显示谱图。

tcen = ttwo;

if ~neven
    Xcen = fftshift(Xtwo,1);
    fcen = -fs/2*(1-1/Ndft):fs/Ndft:fs/2;
else
    Xcen = fftshift(circshift(Xtwo,-1),1);
    fcen = (-fs/2*(1-1/Ndft):fs/Ndft:fs/2)+fs/Ndft/2;
end

[scen,f,t] = spectrogram(x,g,L,Ndft,fs,"centered");

diffs = [max(max(abs(scen-Xcen)));
    max(abs(f-fcen'));
    max(abs(t-tcen))]
diffs = 3×1
10-12 ×

         0
    0.2274
    0.0002

figure
nexttile
waterplot(Xcen,fcen,tcen)
title("Centered, Definition")

nexttile
waterplot(scen,f,t)
title("Centered, spectrogram Function")

Figure contains 2 axes objects. Axes object 1 with title Centered, Definition, xlabel Frequency (Hz), ylabel Time (s) contains an object of type patch. Axes object 2 with title Centered, spectrogram Function, xlabel Frequency (Hz), ylabel Time (s) contains an object of type patch.

单边谱图

计算信号的单边谱图。

  • 使用与用于双边 STFT 相同的时间值。

  • 对于奇数值 NDFT,单边 STFT 由双边 STFT 的前 (NDFT+1)/2 行组成。对于偶数值 NDFT,单边 STFT 由双边 STFT 的前 NDFT/2+1 行组成。

  • 对于奇数值 NDFT,频率区间在零频率处闭合,在奈奎斯特频率处开放。对于偶数值 NDFT,频率区间在两端闭合。

比较输出并显示谱图。对于实数值信号,"onesided" 参量是可选的。

tone = ttwo;

if ~neven
    Xone = Xtwo(1:(Ndft+1)/2,:);
else
    Xone = Xtwo(1:Ndft/2+1,:);
end

fone = 0:fs/Ndft:fs/2;

[sone,f,t] = spectrogram(x,g,L,Ndft,fs);

diffs = [max(max(abs(sone-Xone)));
    max(abs(f-fone'));
    max(abs(t-tone))]
diffs = 3×1
10-12 ×

         0
    0.1137
    0.0002

figure
nexttile
waterplot(Xone,fone,tone)
title("One-Sided, Definition")

nexttile
waterplot(sone,f,t)
title("One-Sided, spectrogram Function")

Figure contains 2 axes objects. Axes object 1 with title One-Sided, Definition, xlabel Frequency (Hz), ylabel Time (s) contains an object of type patch. Axes object 2 with title One-Sided, spectrogram Function, xlabel Frequency (Hz), ylabel Time (s) contains an object of type patch.

function waterplot(s,f,t)
% Waterfall plot of spectrogram
waterfall(f,t,abs(s)'.^2)
set(gca,XDir="reverse",View=[30 50])
xlabel("Frequency (Hz)")
ylabel("Time (s)")
end

spectrogram 函数有一个矩阵作为第四个输出参量,该矩阵包含每个段的功率谱密度 (PSD) 或功率谱。功率谱等于 PSD 乘以窗的等效噪声带宽 (ENBW)。

生成一个信号,该信号由在 1 kHz 下采样 1 秒的对数啁啾组成。啁啾的初始频率为 400 Hz,在测量结束时降至 10 Hz。

fs = 1000;
tt = 0:1/fs:1-1/fs;
y = chirp(tt,400,tt(end),10,"logarithmic");

具有采样率的段 PSD 和功率谱

将信号分成若干长度为 102 个采样的段,并使用汉宁窗对每个段加窗。指定相邻段之间有 12 个采样的重叠,并指定 1024 个 DFT 点。

M = 102;
g = hann(M);
L = 12;
Ndft = 1024;

使用默认 PSD 频谱类型计算信号的谱图。输出 STFT 和段功率谱密度数组。

[s,f,t,p] = spectrogram(y,g,L,Ndft,fs);

使用指定为 "power" 的频谱类型重复计算。输出 STFT 和段功率谱数组。

[r,~,~,q] = spectrogram(y,g,L,Ndft,fs,"power");

验证在两种情况下谱图相同。使用频率的对数刻度绘制谱图。

max(max(abs(s).^2-abs(r).^2))
ans = 
0
waterfall(f,t,abs(s)'.^2)
set(gca,XScale="log",...
    XDir="reverse",View=[30 50])

Figure contains an axes object. The axes object contains an object of type patch.

验证功率谱等于功率谱密度乘以窗的 ENBW。

max(max(abs(q-p*enbw(g,fs))))
ans = 
1.6653e-16

验证段功率谱矩阵与谱图成正比。比例因子是窗元素之和的平方。

max(max(abs(s).^2-q*sum(g)^2))
ans = 
1.3235e-23

在归一化频率下分段计算 PSD 和功率谱

重复计算,但现在使用归一化频率。当您将采样率指定为 2π 时,结果相同。

[~,~,~,pn] = spectrogram(y,g,L,Ndft);
[~,~,~,qn] = spectrogram(y,g,L,Ndft,"power");

max(max(abs(qn-pn*enbw(g,2*pi))))
ans = 
1.1102e-16

加载一个音频信号,其中包含两个递减啁啾和一个宽带飞溅声。计算短时傅里叶变换。将波形分成若干长度为 400 个采样的段,段之间重叠 300 个采样。绘制谱图。

load splat

% To hear, type soundsc(y,Fs)

sg = 400;
ov = 300;

spectrogram(y,sg,ov,[],Fs,"yaxis")
colormap bone

Figure contains an axes object. The axes object with title Spectrogram, xlabel Time (s), ylabel Frequency (kHz) contains an object of type image.

使用 spectrogram 函数输出信号的功率谱密度 (PSD)。

[s,f,t,p] = spectrogram(y,sg,ov,[],Fs);

使用 medfreq 函数跟踪两个啁啾。为了找到更强的低频啁啾,将搜索范围限制为 100 Hz 以上的频率和宽带声音开始之前的时间。

f1 = f > 100;
t1 = t < 0.75;

m1 = medfreq(p(f1,t1),f(f1));

为了找到微弱的高频啁啾,将搜索范围限制为 2500 Hz 以上的频率和 0.3 秒到 0.65 秒之间的时间。

f2 = f > 2500;
t2 = t > 0.3 & t < 0.65;

m2 = medfreq(p(f2,t2),f(f2));

在谱图上叠加结果。将频率值除以 1000 以便以 kHz 表示。

hold on
plot(t(t1),m1/1000,LineWidth=4)
plot(t(t2),m2/1000,LineWidth=4)
hold off

Figure contains an axes object. The axes object with title Spectrogram, xlabel Time (s), ylabel Frequency (kHz) contains 3 objects of type image, line.

生成以 10 kHz 采样、长度为两秒的信号。将信号的瞬时频率指定为时间的三角函数。

fs = 10e3;
t = 0:1/fs:2;
x1 = vco(sawtooth(2*pi*t,0.5),[0.1 0.4]*fs,fs);

计算并绘制信号的谱图。使用长度为 256、形状参数为 β=5 的凯塞窗。指定段与段之间有 220 个采样的重叠,并指定 512 个 DFT 点。在 y 轴上绘制频率。使用默认颜色图和视图。

spectrogram(x1,kaiser(256,5),220,512,fs,"yaxis")

Figure contains an axes object. The axes object with title Spectrogram, xlabel Time (s), ylabel Frequency (kHz) contains an object of type image.

将视图更改为将谱图显示为瀑布图。将颜色图设置为 bone

view(-45,65)
colormap bone

Figure contains an axes object. The axes object with title Spectrogram, xlabel Time (s), ylabel Frequency (kHz) contains an object of type surface.

自 R2025a 起

在指定的目标坐标区和面板容器中绘制四个信号的频谱图。

创建四个振荡信号,采样率为 10 kHz,持续三秒。

Fs = 10e3;
t = 0:1/Fs:3;
x1 = vco(sawtooth(2*pi*t,0.5),[0.1 0.4]*Fs,Fs);
x2 = vco(sin(2*pi*t).*exp(-t),[0.1 0.4]*Fs,Fs) ...
    + 0.01*sin(2*pi*0.25*Fs*t);
x3 = exp(1j*pi*sin(4*t)*Fs/10);
x4 = chirp(t,Fs/10,t(end),Fs/2.5,"quadratic");

在目标坐标区中绘制频谱图

在新图窗窗口的西南角和东北角创建两个坐标区。

fig = figure;
ax1 = axes(fig,Position=[0.09 0.1 0.52 0.45]);
ax2 = axes(fig,Position=[0.55 0.7 0.42 0.25]);

分别在图窗的西南和东北坐标区中绘制信号 x1x2 的功率谱。在 y 轴上显示频率。使用 512 个 DFT 点,长度为 256 个采样的凯塞窗,长度为 220 个采样的重叠。

g = kaiser(256,5);
ol = 220;
nfft = 512;

spectrogram(x1,g,ol,nfft,Fs,"power","yaxis",Parent=ax1);
spectrogram(x2,g,ol,nfft,Fs,"power","yaxis",Parent=ax2);

Figure contains 2 axes objects. Axes object 1 with title Spectrogram, xlabel Time (s), ylabel Frequency (kHz) contains an object of type image. Axes object 2 with title Spectrogram, xlabel Time (s), ylabel Frequency (kHz) contains an object of type image.

在目标 UI 坐标区中绘制频谱图

在新 UI 图窗窗口的西北角创建一个坐标区。

uif = uifigure(Position=[100 100 720 540]);
ax3 = uiaxes(uif,Position=[5 305 300 200]);

在图窗坐标区上绘制信号 x3 的 PSD 估计值。在 y 轴上显示频率,以 0 kHz 为中心。

spectrogram(x3,g,ol,nfft,Fs,"centered","yaxis",Parent=ax3);
title(ax3,"Spectrogram in UI Axes")

Figure contains an axes object. The axes object with title Spectrogram in UI Axes, xlabel Time (s), ylabel Frequency (kHz) contains an object of type image.

在目标面板容器中绘制频谱图

在 UI 图窗窗口的东南角添加一个面板容器。

p = uipanel(uif,Position=[300 5 400 325], ...
    Title="Spectrogram in UI Panel", ...
    BackgroundColor="white");

在该面板容器上绘制信号 x4 的 PSD 估计值。在 y 轴上显示频率。

spectrogram(x4,g,ol,nfft,Fs,"yaxis",Parent=p);

Figure contains 2 axes objects and another object of type uipanel. Axes object 1 with title Spectrogram, xlabel Time (s), ylabel Frequency (kHz) contains an object of type image. Axes object 2 with title Spectrogram in UI Axes, xlabel Time (s), ylabel Frequency (kHz) contains an object of type image.

输入参数

全部折叠

输入信号,指定为向量。

示例: x = chirp(0:0.001:1,0,0.5,100,"quadratic") 指定二次扫频信号。

数据类型: single | double
复数支持:

窗,指定为空数组 ([])、正整数或向量。

spectrogram 函数将输入信号 x 分段,并使用窗计算段采样与窗值的逐元素乘积。窗值取决于您如何指定此参量。

  • 空值 ([]) - spectrogram 使用汉明窗,其长度使得 x 分成八个段,段之间具有 nOverlap 个重叠采样。

  • 正整数 - spectrogramx 分成长度为 win 的段,并使用该长度的汉明窗。

  • 向量 - spectrogramx 分成与向量 win 长度相同的段,并使用在 win 中指定的窗。

如果 x 的长度无法整除分成具有 nOverlap 个重叠采样的整数段,则 spectrogram 会相应地截断 x

有关可用窗的列表,请参阅加窗法

示例: hann(N+1)(1-cos(2*pi*(0:N)'/N))/2 都指定长度为 N + 1 的汉宁窗。

重叠采样的数量,指定为空数组 ([]) 或非负整数。

  • 空数组 ([]) - spectrogram 使用生成段之间有 50% 重叠的数。

    如果未指定段长度,则函数将 nOverlap 设置为 Nx / 4.5⌋,其中 Nx 是输入信号的长度,⌊ ⌋ 符号表示向下取整函数。此操作等效于将信号分成尽可能长的段,以获得接近但不超出 8 个重叠率为 50% 的段。

  • 非负整数 - spectrogram 使用此参量中指定的采样数重叠相邻段。

    • 如果 win 是标量,则 nOverlap 必须小于 win

    • 如果 win 是向量,则 nOverlap 必须小于 win 的长度。

频率设定,指定为以下值之一:

  • 空值 [] - spectrogram 使用 256 或大于等于窗长度的下一个 2 的幂中的较大者作为 DFT 点数来计算频谱估计值。

  • 正整数 - spectrogram 使用在此参量中指定的 DFT 点数来计算频谱估计值。

  • 包含至少两个元素的向量 - spectrogramfreqSpec 中指定的频率处计算频谱估计值。

    • 如果指定采样率 Fs,则 spectrogram 假定 freqSpec 是与 Fs 单位相同的周期性频率。

    • 如果未指定 Fs,则 spectrogram 假定 freqSpec 是以弧度/采样点为单位的归一化频率。

示例: freqSpec = 512 指定 512 个 DFT 点。

示例: freqSpec = pi./[8 4 2] 指定一个包含三个归一化频率的向量。

数据类型: single | double

采样率,指定为正标量。采样率是单位时间内的采样数。如果时间单位是秒,则采样率的单位是赫兹。

  • 如果将 Fs 指定为空数组 [],则 spectrogram 假定输入信号 x 的采样率为 1 Hz。

  • 如果未指定 Fs,则 spectrogram 假定输入信号 x 的采样率为 2π 弧度/采样点。

PSD 估计值或功率谱的频率范围,指定为 "onesided""twosided""centered"

spectrogram 函数返回的 ps 的行数和频率区间取决于在 freqRange 中指定的值,无论 DFT 点数 freqSpec 是偶数还是奇数,以及是否指定 Fs

freqRangefreqSpecps 中的行数

ps 的频率区间

Fs 未指定

Fs 已指定

"onesided"
(如果 x 是实数值,则为默认值)
偶数freqSpec/2 + 1[0,π] 弧度/采样点[0,Fs/2] 周期/单位时间
奇数(freqSpec + 1)/2[0,π) 弧度/采样点[0,Fs/2) 周期/单位时间
"twosided"
(如果 x 是复数值,则为默认值)
偶数或奇数freqSpec[0,2π) 弧度/采样点[0,Fs) 周期/单位时间
"centered"偶数freqSpec(–π,π] 弧度/采样点(–Fs/2,Fs/2] 周期/单位时间
奇数(–π,π) 弧度/采样点(–Fs/2,Fs/2) 周期/单位时间

注意

  • 如果您将 freqSpec 指定为周期性频率或归一化频率的向量,则不支持此参量。

  • 如果 x 是复数值,则不支持 "onesided" 值。

数据类型: char | string

功率谱缩放,指定为下列值之一:

  • "psd" - spectrogram 返回功率谱密度。

  • "power" - spectrogram 对 PSD 的每个估计值进行缩放(缩放量为窗的等效噪声带宽),并返回每个频率处的功率估计值。如果您还指定 "reassigned",则 spectrogram 会在重排之前在每个频率 bin 的宽度上对 PSD 进行积分。

下表显示在给定输入信号 x、窗向量 win、重叠长度 nOverlap、频率设定 freqSpec 和采样率 Fs 的情况下,在 ps 中返回的 PSD 估计值和功率谱估计值之间的缩放关系。

采样率缩放关系
Fs 已指定

[~,~,~,psd] = spectrogram(x,win,nOverlap,freqSpec,Fs,"psd");
[~,~,~,pow] = spectrogram(x,win,nOverlap,freqSpec,Fs,"power");
那么 pow 等效于 psd*enbw(win,Fs)

Fs 未指定

[~,~,~,psd] = spectrogram(x,win,nOverlap,freqSpec,"psd");
[~,~,~,pow] = spectrogram(x,win,nOverlap,freqSpec,"power");
那么 pow 等效于 psd*enbw(win,2*pi)

数据类型: char | string

名称-值参数

全部折叠

将可选参量对组指定为 Name1=Value1,...,NameN=ValueN,其中 Name 是参量名称,Value 是对应的值。名称-值参量必须出现在其他参量之后,但对各个参量对组的顺序没有要求。

示例: spectrogram(x,100,OutputTimeDimension="downrows")x 分成长度为 100 的段,并使用该长度的汉明窗对每个段加窗。谱图的输出时间维度沿行排列。

阈值,指定为以分贝为单位的实数标量。

如果指定 MinThreshold=thspectrogram 会将满足条件 10 log10(s) ≤ th 的那些 s 元素设置为零。

输出时间维度,指定为以下值之一:

  • "acrosscolumns" - spectrogramspsfctc 的时间维度沿列排列,频率维度沿行排列。

  • "downrows" - spectrogramspsfctc 的时间维度沿行排列,频率维度沿列排列。

如果您将 spectrogram 与输出参量结合使用,则此参量将被忽略。

数据类型: char | string

自 R2025a 起

目标父容器,指定为 Axes 对象、UIAxes 对象或 Panel 对象。

如果指定 Parent,则无论是否带输出参量调用函数,spectrogram 函数都会在指定的目标父容器上绘制频谱图。

有关 MATLAB® 图形中目标容器和父子关系的详细信息,请参阅图形对象层次结构。有关在 UIAxesPanel 对象中使用 Parent 设计 App 的详细信息,请参阅Plot Spectral Representations of Signal in App Designer

输出参量

全部折叠

短时傅里叶变换 (STFT) 输出,以矩阵形式返回。时间按 s 的列从左到右递增排列,频率从 0 开始沿行递增排列。

  • 如果 x 是长度为 Nx 的信号,则 sk 列,其中

    • k = ⌊(NxnOverlap)/(winnOverlap)⌋(如果 win 为标量)。

    • k = ⌊(NxnOverlap)/(length(win)nOverlap)⌋(如果 win 为向量)。

  • 如果 x 是实数值且 freqSpec 是偶数,则 s 有 (freqSpec/2 + 1) 行。

  • 如果 x 是实数值且 freqSpec 是奇数,则 s 有 (freqSpec + 1)/2 行。

  • 如果 x 是复数值,则 sfreqSpec 行。

  • 如果您指定 "reassigned" 参量,s 将保持不变。

注意

freqRange 设置为 "onesided" 时,spectrogram 输出正奈奎斯特范围内的 s 值,并且不保持总功率。

与 STFT 输出相关联的频率,以向量形式返回。

  • 如果指定 Fs,则 f 包含以赫兹为单位的周期性频率。

  • 如果未指定 Fs,则 f 包含以弧度/采样点为单位的归一化频率。

与 STFT 输出相关联的时间,以向量形式返回。

  • 如果指定 Fs,则 t 包含以秒为单位的时刻。

  • 如果未指定 Fs,则 t 包含以 (采样数)/(2π) 为单位的采样索引。

t 中的值对应每个段的中点。

功率谱密度 (PSD) 或功率谱,以矩阵形式返回。

  • 如果 x 是实数值且您未指定 freqRange 或将其设置为 "onesided",则 ps 包含每个段的 PSD 或功率谱的单边修正周期图估计值。函数在所有频率(除了 0 和奈奎斯特频率)上将功率乘以 2 以保持总功率。

  • 如果 x 是复数值或您将 freqRange 设置为 "twosided""centered",则 ps 包含每个段的 PSD 或功率谱的双边修正周期图估计值。

  • 如果您指定归一化频率向量或在 freqSpec 中指定周期性频率,则 ps 包含在输入频率处计算的每个段的 PSD 或功率谱的修正周期图估计值。

能量中心频率和时间,以与短时傅里叶变换大小相同的矩阵形式返回。如果您未指定采样率,则 fc 的元素以归一化频率形式返回。

仅当您指定 "reassigned" 选项时,spectrogram 函数才返回 fctc。如果 fctc 中的每个重新分配的值超出范围,spectrogram 会分别将它们替换为 ft 中的对应值。

详细信息

全部折叠

提示

  • 如果 STFT 矩阵有零值,则将其转换为分贝会导致出现负无穷大而无法绘制。为避免此问题,当您以不带输出参量形式或通过指定 Parent 参量调用 spectrogram 时,该函数会向 STFT 矩阵添加 eps

  • 如果 STFT 矩阵的幅值非常接近于零,并且您指定了 "reassigned" 选项,则频谱图重排可能会对数值敏感。在这种情况下,请不要使用 "reassigned" 选项。

参考

[1] Boashash, Boualem, ed. Time Frequency Signal Analysis and Processing: A Comprehensive Reference. Second edition. EURASIP and Academic Press Series in Signal and Image Processing. Amsterdam and Boston: Academic Press, 2016.

[2] Chassande-Motin, Éric, François Auger, and Patrick Flandrin. "Reassignment." In Time-Frequency Analysis: Concepts and Methods. Edited by Franz Hlawatsch and François Auger. London: ISTE/John Wiley and Sons, 2008.

[3] Fulop, Sean A., and Kelly Fitz. "Algorithms for computing the time-corrected instantaneous frequency (reassigned) spectrogram, with applications." Journal of the Acoustical Society of America. Vol. 119, January 2006, pp. 360–371.

[4] Oppenheim, Alan V., and Ronald W. Schafer, with John R. Buck. Discrete-Time Signal Processing. Second edition. Upper Saddle River, NJ: Prentice Hall, 1999.

[5] Rabiner, Lawrence R., and Ronald W. Schafer. Digital Processing of Speech Signals. Englewood Cliffs, NJ: Prentice-Hall, 1978.

扩展功能

全部展开

版本历史记录

在 R2006a 之前推出

全部展开