时变频率下Spectrogram与Scaleogram对比:CWT精度及读取问题
关于CWT尺度图的频率/振幅读取及精度问题解答
嘿,我来帮你梳理下你在对比FFT(谱图)和CWT(尺度图)时遇到的问题~
一、为什么CWT看起来“精度低”?
你觉得CWT精度不如STFT(谱图),主要是两个核心原因:
- Heisenberg不确定性原理的自适应表现:STFT用固定长度的滑动窗,时间和频率分辨率是固定的权衡;但CWT的分辨率是自适应的——高频信号对应高时间分辨率、低频率分辨率,低频信号则相反。你的信号里有固定8Hz的高频成分,CWT对这类高频的频率分辨率天生不如固定窗的STFT,这是它的特性而非缺陷,换其他小波也改变不了这个基本规律。
- 参数设置的偏差:你用了
np.arange(1,512)的宽尺度范围,pywt返回的freqs是基于小波中心频率的近似估算,当尺度跨度太大时,这个估算和实际频率的对应关系会出现偏差,看起来就更不准了。
二、如何从CWT尺度图读取频率和振幅?
1. 频率读取:手动对应尺度与频率
CWT的尺度和频率并非线性直接对应,必须结合小波的中心频率来计算。以你用的gaus1为例,它的中心频率约为0.46(不同小波的中心频率可以查pywt文档或通过小波的傅里叶变换计算),频率与尺度的转换公式是:
f = (中心频率 * 采样率) / 尺度
你可以手动计算这个对应关系,代替pywt返回的freqs,这样能得到更准确的频率值:
fc = 0.46 # gaus1的中心频率 scales = np.arange(1, 200) # 缩小尺度范围,聚焦到你关注的0-10Hz freqs_cwt = (fc * f_s) / scales # 只保留0-10Hz的有效尺度和频率 valid_idx = freqs_cwt <= 10 scales_valid = scales[valid_idx] freqs_valid = freqs_cwt[valid_idx]
2. 振幅读取:归一化CWT系数
CWT系数的幅值和信号振幅不是直接线性对应的,因为小波变换是内积运算,系数大小会受尺度、小波能量的影响。要得到近似的信号振幅,需要对系数做归一化处理:
- 首先,尺度变换会导致小波能量变化,所以要给每个尺度的系数除以
sqrt(scale); - 其次,不同小波的L2范数不同,还可以结合小波的能量进行进一步归一化(比如gaus1的L2范数可以通过计算小波的积分平方得到)。
示例代码:
# 计算CWT系数 cwtmatr, _ = pywt.cwt(x, scales_valid, "gaus1", sampling_period=1/f_s) # 归一化系数,得到近似振幅 cwt_amplitude = np.abs(cwtmatr) / np.sqrt(scales_valid[:, np.newaxis])
三、CWT是不是不适合你的问题?
不一定,这取决于你的核心需求:
- 如果你的目标是精确估计高频固定频率,那STFT(谱图)确实更合适,因为它的固定窗能提供稳定的高频频率分辨率;
- 如果你的需求是捕捉低频慢变信号的时间细节,或者检测瞬态高频事件,CWT的自适应分辨率会更有优势——比如你信号中的
f1(t)是随时间变化的低频,CWT对它的时间分辨率会比大窗的STFT好很多。
另外,你可以试试更适合频率分析的小波,比如morl(Morlet小波),它的形状更接近正弦波,和你的正弦信号成分匹配度更高,频率分辨率会比gaus1更好。
代码修改示例(优化后的CWT部分)
# 替换原CWT代码部分 fc = 0.46 # gaus1中心频率 scales = np.arange(1, 200) freqs_cwt = (fc * f_s) / scales valid_idx = freqs_cwt <= 10 scales_valid = scales[valid_idx] freqs_valid = freqs_cwt[valid_idx] cwtmatr, _ = pywt.cwt(x, scales_valid, "gaus1", sampling_period=1/f_s) cwt_amplitude = np.abs(cwtmatr) / np.sqrt(scales_valid[:, np.newaxis]) im2 = ax4.pcolormesh(t, freqs_valid, cwt_amplitude, vmin=0, cmap="inferno" ) ax4.set_ylim(0,10) ax4.set_ylabel("Frequency in [Hz]") ax4.set_xlabel("Time in [s]") ax4.set_title("Normalized Scaleogram using GAUS1")
内容的提问来源于stack exchange,提问作者varantir
相关产品推荐
相关产品推荐

