东方耀AI技术分享

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 3613|回复: 0
打印 上一主题 下一主题

[通信原理] python时域信号处理Demo:fft psd 自相关分析

[复制链接]

1365

主题

1856

帖子

1万

积分

管理员

Rank: 10Rank: 10Rank: 10

积分
14439
QQ
跳转到指定楼层
楼主
发表于 2021-1-27 08:51:25 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式



python时域信号处理Demo:fft psd 自相关分析


  1. import numpy as np
  2. import matplotlib.pyplot as plt

  3. # python时域信号处理Demo:fft psd 自相关分析
  4. N = 200     # 采样个数
  5. f_s = 50    # 采样频率
  6. t = np.linspace(0.0, N/f_s, N)
  7. print("4秒内多少个采样点:", len(t))
  8. signal1 = 2 * np.sin(2 * 1 * np.pi * t)   # f=1
  9. signal2 = np.sin(2 * 5 * np.pi * t)       # f=5
  10. # 时域信号合成
  11. signal = signal1 + signal2


  12. def get_values(y_values, N, f_s):
  13.     f_values = np.linspace(0.0, N/f_s, N)
  14.     return f_values, y_values



  15. plt.figure(figsize=(16, 12))

  16. plt.subplot(231)
  17. f_values, signal_values = get_values(signal1, N, f_s)
  18. plt.plot(f_values, signal_values, linestyle='-', color='blue')
  19. plt.xlabel('Time [sec]', fontsize=16)
  20. # Amplitude 振幅
  21. plt.ylabel('Amplitude', fontsize=16)
  22. plt.title("Time domain of the signal1(f=1)", fontsize=16)
  23. # plt.show()

  24. plt.subplot(232)
  25. f_values, signal_values = get_values(signal2, N, f_s)
  26. plt.plot(f_values, signal_values, linestyle='-', color='blue')
  27. plt.xlabel('Time [sec]', fontsize=16)
  28. plt.ylabel('Amplitude', fontsize=16)
  29. plt.title("Time domain of the signal2(f=5)", fontsize=16)
  30. # plt.show()

  31. plt.subplot(233)
  32. f_values, signal_values = get_values(signal, N, f_s)
  33. plt.plot(f_values, signal_values, linestyle='-', color='blue')
  34. plt.xlabel('Time [sec]', fontsize=16)
  35. plt.ylabel('Amplitude', fontsize=16)
  36. plt.title("Time domain of the signal", fontsize=16)
  37. # plt.show()


  38. from scipy.fftpack import fft

  39. def get_fft_values(y_values, N, f_s):
  40.     # 信号频率不会大于采样频率的一半
  41.     f_values = np.linspace(0.0, f_s / 2.0, N // 2)
  42.     fft_values_ = fft(y_values)
  43.     print("原始信号数据经过fft后:", len(fft_values_))
  44.     # 对称性 求模(振幅谱) 归一化(为什么乘以2.0)
  45.     fft_values = 2.0 / N * np.abs(fft_values_[0:N // 2])
  46.     print("单边振幅谱(归一化) 为什么乘以2.0???")
  47.     print("绝对值就是求模,归一化后的fft值:", len(fft_values), fft_values[:5])
  48.     return f_values, fft_values


  49. plt.subplot(234)
  50. f_values, fft_values = get_fft_values(signal, N, f_s)
  51. plt.plot(f_values, fft_values, linestyle='-', color='blue')
  52. plt.xlabel('Frequency [Hz]', fontsize=16)
  53. plt.ylabel('Amplitude', fontsize=16)
  54. plt.title("The FFT of our composite signal", fontsize=16)
  55. # plt.show()


  56. from scipy.signal import welch


  57. def get_psd_values(y_values, N, f_s):
  58.     # 用韦尔奇方法估计功率谱密度
  59.     f_values, psd_values = welch(y_values, fs=f_s)
  60.     return f_values, psd_values


  61. plt.subplot(235)
  62. # PSD英文全称Power Spectral Density,即功率谱密度,它和FFT一样,反映的是信号在频域上的信息。
  63. # 其中PSD频谱图脉冲下方的面积表示信号在该频率上的能量分布。
  64. f_values, psd_values = get_psd_values(signal, N, f_s)
  65. plt.plot(f_values, psd_values, linestyle='-', color='blue')
  66. plt.xlabel('Frequency [Hz]', fontsize=16)
  67. plt.ylabel('PSD [V**2 / Hz]', fontsize=16)
  68. plt.title("The PSD of our composite signal", fontsize=16)


  69. def autocorr(x):
  70.     # numpy互相关函数np.correlate
  71.     # 《Python 数字信号处理应用》这本书上刚好看到过,题主想要用的应该是np.corrcoef这个方法,np.corrlated,是信号处理领域的自相关算法,
  72.     # 【使用的非相关的标准化版定义,随着时滞变大,两个信号之间重叠点数减少,所以相关幅度降低了】,这是书上原话,
  73.     # 我的理解是由于np.corrlated在有限范围内计算信号自相关,也就是错位相乘,随着时延增加重叠的点就会减少,计算的自相关也会变小,
  74.     # 相比np.corrcoef,自相关函数的幅值明显有下降,需要除以N/2的长度这样可以获得与np.corrcoef几乎相同的结果
  75.     result = np.correlate(x, x, mode='full')
  76.     return result[len(result) // 2:]


  77. def get_autocorr_values(y_values, N, f_s):
  78.     autocorr_values = autocorr(y_values)
  79.     # 细节信息
  80.     x_values = np.array([1.0 * jj / f_s for jj in range(0, N)])
  81.     return x_values, autocorr_values


  82. plt.subplot(236)
  83. # Autocorrelation是自相关的意思,它可以求出信号的自相关性,即信号经过一个时延后与自身的相似性
  84. # 有趣的是Autocorrelation与PSD是一组FFT变换对,对Autocorrelation作FFT变换可得到PSD,对PSD作IFFT(快速傅里叶逆变换)可得到Autocorrelation
  85. t_values, autocorr_values = get_autocorr_values(signal, N, f_s)
  86. plt.plot(t_values, autocorr_values, linestyle='-', color='blue')
  87. plt.xlabel('time delay [s]', fontsize=16)
  88. plt.ylabel('Autocorrelation amplitude', fontsize=16)
  89. plt.title("The autocorrelation of signal.", fontsize=16)

  90. # plt.savefig('fft_psd_corr.png', dpi=200)
  91. plt.show()
复制代码


fft_psd_corr.png (389.28 KB, 下载次数: 121)

fft_psd_corr.png
让天下人人学会人工智能!人工智能的前景一片大好!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|人工智能工程师的摇篮 ( 湘ICP备2020019608号-1 )

GMT+8, 2024-5-19 11:50 , Processed in 0.195969 second(s), 21 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表