当前位置:   article > 正文

时间序列信号处理系列-基于Python的同步压缩变换_python对信号进行时频分析

python对信号进行时频分析

时频分析方法使用时-频域联合分布描述时间序列信号的瞬态特征,并通过瞬时频率估计来表征信号的特征频率随时间变化的趋势,在时间序列信号处理中得到了广泛的应用。STFT 和WT等常用的时频分析方法时频分辨率较低,而且对于多分量时变信号的匹配效果不佳;WVD对噪声的鲁棒性不足且对于多分量时变信号存在交叉干扰项;EMD及其改进方法缺乏数学理论支撑,并存在端点效应和模态混叠等问题。以上时频分析方法存在一些共性问题,例如它们在时频平面的变换系数分布比较离散,瞬时频率曲线幅值能量不够集中,因此时频谱会出现模糊的现象。为了实现理想的时频表示,在原始时频谱的基础上进行能量重排是当前的研究热点。基于同步压缩变换SST的时频分析方法实现了对时频系数的压缩和重排,能够对复杂多分量信号实现高分辨率表达。同步压缩变换的前身,即重排算法,具有坚实的理论基础。重排算法作为一种后处理的时频分析方法,主要用于提升时频表达的效果,但是它最大的缺陷是不支持信号重构。在此基础上,小波的创始人之一Daubechies等在2011年提出了同步压缩小波变换SST,SST通过同步压缩算子对时频系数进行重排,将信号在时频平面任一点处的时频分布移到能量的重心位置,增强瞬时频率的能量集中,较好地解决传统时频分析方法存在的时频模糊问题。

前置知识可参考如下文章

调制信号的连续小波变换 - 哥廷根数学学派的文章 - 知乎 调制信号的连续小波变换 - 知乎

再看连续小波变换 - 哥廷根数学学派的文章 - 知乎 再看连续小波变换 - 知乎

同步压缩变换初探 - 哥廷根数学学派的文章 - 知乎 同步压缩变换初探 - 知乎

同步压缩变换在机械振动信号处理领域[1],在微震信号处理领域[2],辐射源个体识别领域[3],雷达辐射源分选识别领域[4],储层识别领域[5],通信信号调制识别领域[6],生理信号处理领域[7]等方面都有广泛应用。

[1]基于迭代广义同步压缩变换的时变工况行星齿轮箱故障诊断

[2]基于多重同步压缩变换的微震信号去噪方法研究

[3]基于同步压缩小波变换的主信号抑制技术

[4]基于多重同步压缩变换的雷达辐射源分选识别

[5]时间域和频率域二阶同步压缩变换及其在储层识别中的应用

[6]基于同步压缩小波变换的通信信号调制识别

[7]基于物联网和云平台的老人家庭远程监护系统研究

由于很多研究者在工作中使用python语言,因为这篇文章介绍在python环境下如何更好地使用SST方法。首先安装ssqueezepy模块:pip install ssqueezepy

ssqueezepy模块里是这么介绍SST的:Synchrosqueezing is a powerful reassignment method that focuses time-frequency representations, and allows extraction of instantaneous amplitudes and frequencies.

主要包括如下内容

  • Continuous Wavelet Transform (CWT), forward & inverse, and its Synchrosqueezing(连续小波变换,逆变换,及相应的同步压缩变换)
  • Short-Time Fourier Transform (STFT), forward & inverse, and its Synchrosqueezing(短时傅里叶变换,逆变换,及相应的同步压缩变换)
  • Wavelet visualizations and testing suite(小波可视化)
  • Generalized Morse Wavelets(广义Morse小波)
  • Ridge extraction(脊线提取)

1.首先,看一下基础模块Benchmarks

导入相关模块

  1. import os
  2. import numpy as np
  3. import gc
  4. import pandas as pd
  5. import scipy.signal as sig
  6. #pip install librosa
  7. import librosa
  8. from pywt import cwt as pcwt
  9. from timeit import timeit as _timeit
  10. from ssqueezepy import cwt, stft, ssq_cwt, ssq_stft, Wavelet
  11. from ssqueezepy.utils import process_scales, padsignal
  12. from ssqueezepy.ssqueezing import _compute_associated_frequencies
  13. def timeit(fn, number=10):
  14. return _timeit(fn, number=number) / number

定义一些基础函数,以后都会用到

  1. #输出名称
  2. def print_report(header, times):
  3. print(("{}\n"
  4. "CWT: {:.3f} sec\n"
  5. "STFT: {:.3f} sec\n"
  6. "SSQ_CWT: {:.3f} sec\n"
  7. "SSQ_STFT: {:.3f} sec\n"
  8. ).format(header, *list(times.values())[-4:]))
  9. #CWT同步压缩变换
  10. def time_ssq_cwt(x, dtype, scales, cache_wavelet, ssq_freqs):
  11. wavelet = Wavelet(dtype=dtype)
  12. kw = dict(wavelet=wavelet, scales=scales, ssq_freqs=ssq_freqs)
  13. if cache_wavelet:
  14. for _ in range(3): # warmup run
  15. _ = ssq_cwt(x, cache_wavelet=True, **kw)
  16. del _; gc.collect()
  17. return timeit(lambda: ssq_cwt(x, cache_wavelet=cache_wavelet, **kw))
  18. #STFT同步压缩变换
  19. def time_ssq_stft(x, dtype, n_fft):
  20. for _ in range(3):
  21. _ = ssq_stft(x, dtype=dtype, n_fft=n_fft)
  22. del _; gc.collect()
  23. return timeit(lambda: ssq_stft(x, dtype=dtype, n_fft=n_fft))
  24. #CWT变换
  25. def time_cwt(x, dtype, scales, cache_wavelet):
  26. wavelet = Wavelet(dtype=dtype)
  27. if cache_wavelet:
  28. for _ in range(3): # warmup run
  29. _ = cwt(x, wavelet, scales=scales, cache_wavelet=True)
  30. del _; gc.collect()
  31. return timeit(lambda: cwt(x, wavelet, scales=scales,
  32. cache_wavelet=cache_wavelet))
  33. #STFT变换
  34. def time_stft(x, dtype, n_fft):
  35. for _ in range(3):
  36. _ = stft(x, dtype=dtype, n_fft=n_fft)
  37. del _; gc.collect()
  38. return timeit(lambda: stft(x, dtype=dtype, n_fft=n_fft))
  39. def time_all(x, dtype, scales, cache_wavelet, ssq_freqs, n_fft):
  40. num = str(len(x))[:-3] + 'k'
  41. return {num: '',
  42. f'{num}-cwt': time_cwt(x, dtype, scales, cache_wavelet),
  43. f'{num}-stft': time_stft(x, dtype, n_fft),
  44. f'{num}-ssq_cwt': time_ssq_cwt(x, dtype, scales, cache_wavelet,
  45. ssq_freqs),
  46. f'{num}-ssq_stft': time_ssq_stft(x, dtype, n_fft)
  47. }
  48. x = np.random.randn(1000)
  49. for dtype in ('float32', 'float64'):
  50. wavelet = Wavelet(dtype=dtype)
  51. _ = ssq_cwt(x, wavelet, cache_wavelet=False)
  52. _ = ssq_stft(x, dtype=dtype)
  53. del _, wavelet

设置STFT 和 CWT的 输出参数

  1. N0, N1 = 10000, 160000 # selected such that CWT pad length ratios are same
  2. n_rows = 300
  3. n_fft = n_rows * 2 - 2
  4. wavelet = Wavelet()
  5. scales = process_scales('log-piecewise', N1, wavelet=wavelet)[:n_rows]
  6. ssq_freqs = _compute_associated_frequencies(
  7. scales, N1, wavelet, 'log-piecewise', maprange='peak',
  8. was_padded=True, dt=1, transform='cwt')
  9. kw = dict(scales=scales, ssq_freqs=ssq_freqs, n_fft=n_fft)
  10. t_all = {}

使用一个很简单的数据x = np.random.randn(N)测试用时

  1. #基础用时
  2. print("// BASELINE (dtype=float32, cache_wavelet=True)")
  3. os.environ['SSQ_PARALLEL'] = '0'
  4. os.environ['SSQ_GPU'] = '0'
  5. t_all['base'] = {}
  6. dtype = 'float32'
  7. for N in (N0, N1):
  8. x = np.random.randn(N)
  9. t_all['base'].update(time_all(x, dtype=dtype, cache_wavelet=True, **kw))
  10. print_report(f"/ N={N}", t_all['base'])
  11. #并行+小波Parallel + wavelet cache用时
  12. print("// PARALLEL + CACHE (dtype=float32, cache_wavelet=True)")
  13. os.environ['SSQ_PARALLEL'] = '1'
  14. os.environ['SSQ_GPU'] = '0'
  15. t_all['parallel'] = {}
  16. for N in (N0, N1):
  17. x = np.random.randn(N)
  18. t_all['parallel'].update(time_all(x, dtype='float32', cache_wavelet=True,
  19. **kw))
  20. print_report(f"/ N={N}", t_all['parallel'])
  21. #GPU+小波GPU + wavelet cache用时
  22. print("// GPU + CACHE (dtype=float32, cache_wavelet=True)")
  23. os.environ['SSQ_GPU'] = '1'
  24. t_all['gpu'] = {}
  25. for N in (N0, N1):
  26. x = np.random.randn(N)
  27. t_all['gpu'].update(time_all(x, dtype='float32', cache_wavelet=True, **kw))
  28. print_report(f"/ N={N}", t_all['gpu'])

然后测试一下python的其他模块执行小波变换的耗时

  1. #PyWavelets模块,小波变换常用的一个python模块
  2. for N in (N0, N1):
  3. x = np.random.randn(N)
  4. xp = padsignal(x)
  5. t = timeit(lambda: pcwt(xp, wavelet='cmor1.5-1.0', scales=scales,
  6. method='fft'))
  7. print("pywt_cwt-%s:" % N, t)
  8. #Scipy模块
  9. for N in (N0, N1):
  10. x = np.random.randn(N)
  11. xp = padsignal(x)
  12. t = timeit(lambda: sig.cwt(xp, wavelet=sig.morlet,
  13. widths=np.arange(4, 4 + len(scales))))
  14. print("scipy_cwt-%s:" % N, t)
  15. #%%
  16. for N in (N0, N1):
  17. x = np.random.randn(N)
  18. t = timeit(lambda: sig.stft(x, nperseg=n_fft, nfft=n_fft, noverlap=n_fft-1))
  19. print("scipy_stft-%s:" % N, t)
  20. #Librosa模块,语音信号分析中常用的模块
  21. # NOTE: we bench here with float64 since float32 is slower for librosa as of 0.8.0
  22. for N in (N0, N1):
  23. x = np.random.randn(N)
  24. t = timeit(lambda: librosa.stft(x, n_fft=n_fft, hop_length=1, dtype='float64'))
  25. print("librosa_stft-%s:" % N, t)

最后看一下执行结果

2.讲完了benchmarks,接下来看一下test_transforms相关内容

导入相关模块

  1. import numpy as np
  2. import scipy.signal as sig
  3. from ssqueezepy import Wavelet, TestSignals
  4. from ssqueezepy.utils import window_resolution

生成测试信号

  1. tsigs = TestSignals(N=2048)
  2. # 设置 `dft` 模式
  3. dft = (None, 'rows', 'cols')[0]
  4. tsigs.demo(dft=dft)

看一下配备了多少测试信号

还有很多很多,就不一一列举了。

还可以指定测试信号类,例如

  1. signals = [
  2. 'am-cosine',
  3. ('hchirp', dict(fmin=.2)),
  4. ('sine:am-cosine', (dict(f=32, phi0=1), dict(amin=.3))),
  5. ]
  6. tsigs.demo(signals, N=2048)

加上`dft` 参数,就展示了相应的频谱

  1. tsigs.demo(signals, dft='rows')
  2. #tsigs.demo(signals, dft='cols')

下面开始进行CWT变换和SST变换,使用广义morse小波,但参数不同,只列出几个图片

  1. tsigs = TestSignals(N=2048)
  2. wavelets = [
  3. Wavelet(('gmw', {'beta': 60})),
  4. Wavelet(('gmw', {'beta': 5})),
  5. ]
  6. tsigs.wavcomp(wavelets, signals='all')

再看一个chirp信号的例子

tsigs.wavcomp(wavelets, signals=[('#echirp', dict(fmin=.1))], N=2048)

再对比一下CWT和STFT以及相应的同步压缩变换的例子

再看一下含噪声信号的例子

再简要看一下时频谱图的脊线提取的例子,以后会慢慢讲

今天就讲到这吧,精华就是这些,其他的关于小波的知识以后再讲。

时间序列信号处理系列-基于Python的同步压缩变换 - 哥廷根数学学派的文章 - 知乎 https://zhuanlan.zhihu.com/p/554189692

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/134378
推荐阅读
相关标签
  

闽ICP备14008679号