东方耀AI技术分享

 找回密码
 立即注册

QQ登录

只需一步,快速开始

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

[Python] 时域信号加窗与窗函数的作用

[复制链接]

1365

主题

1856

帖子

1万

积分

管理员

Rank: 10Rank: 10Rank: 10

积分
14429
QQ
跳转到指定楼层
楼主
发表于 2021-9-1 15:00:46 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
# 时域信号加窗与窗函数的作用  通过加窗,可以减少频谱的泄露
# 时域加窗:主瓣变宽(距离分辨率下降?),幅值变小(信噪比降低)


  1. # -*- coding: utf-8 -*-
  2. __author__ = u'东方耀 微信:dfy_88888'
  3. __date__ = '2021/9/1 上午9:57'
  4. __product__ = 'PyCharm'
  5. __filename__ = '21_信号处理demo'

  6. from scipy.fftpack import fft, ifft, fftshift
  7. from scipy.signal import findfreqs, find_peaks
  8. import numpy as np
  9. import scipy
  10. from scipy.signal import get_window
  11. import matplotlib.pyplot as plt
  12. import matplotlib.ticker as mticker
  13. from matplotlib.font_manager import FontProperties

  14. font_fname = "/usr/share/fonts/wps-office/simfang.ttf"
  15. font = FontProperties(fname=font_fname)
  16. # plt.rcParams['font.sans-serif']=['simfang']#设置作图中文显示


  17. # 时域信号加窗与窗函数的作用  通过加窗,可以减少频谱的泄露
  18. # 时域加窗:主瓣变宽(距离分辨率下降?),幅值变小(信噪比降低)

  19. continue_time_per_freq = 1e-6   # 每个频点的持续时间1微妙
  20. fs = 100e6    # 时间维 采样率  100M
  21. f = 10e6      # 信号频率 10M

  22. sample_num_per_freq = int(np.ceil(continue_time_per_freq * fs))
  23. print("每个子脉冲的采样点数(采样速率和脉宽有关)=", sample_num_per_freq)
  24. # 发信号
  25. x_time = np.linspace(0, continue_time_per_freq, sample_num_per_freq, endpoint=True)
  26. print("每个频段的时间采样点数=", len(x_time), x_time[:2], x_time[-2:])
  27. # 离散后就没有时间的概念了  发送复信号
  28. Tx_signal = 1 * np.cos(2*np.pi*f*x_time)

  29. print("发送cos实信号:", len(Tx_signal), type(Tx_signal[0]))

  30. # 发送信号fft  将零频分量移动到数组中心
  31. Tx_y_fft = fftshift(fft(Tx_signal))
  32. print("发射信号作fft之后:", len(Tx_y_fft))
  33. # 频域的X轴 参考gnuradio的 一般为(-fs/2,fs/2)
  34. # 取一半  因为 振幅谱 是偶函数 相位谱 是奇函数
  35. # 复序列没有负频率,采样率只要大于带宽即可
  36. x_f = np.linspace(0, int(fs), len(Tx_signal), endpoint=True) - int(fs/2)
  37. Tx_abs_y = np.abs(Tx_y_fft)  # 取复数的绝对值,即复数的模(双边频谱)


  38. # 矩形窗boxcar  hamming hann blackmanharris  blackman gaussian
  39. window_name = "hamming"
  40. window = get_window(window_name, sample_num_per_freq)
  41. print("生成窗%s函数的序列:" % window_name, len(window), window[:3], window[-3:])
  42. # assert 0 == 1, "stop"
  43. # 这里的 len(window) == 300 != 2048也是可以的
  44. window_y_fft = np.abs(fftshift(fft(window, 2048)))
  45. print("看看改变了频点的fft变换后:", len(window_y_fft))
  46. x_f_window = np.linspace(-0.5, 0.5, len(window_y_fft))
  47. # 注意 x_f_window的取值范围 和 fftshift的使用 导致0频分量已经放到坐标原点了
  48. window_y_fft_db = 20 * np.log10(window_y_fft / np.max(window_y_fft))

  49. # 进行加窗操作
  50. windowed_signal = Tx_signal * window
  51. windowed_y_fft = np.abs(fftshift(fft(windowed_signal)))


  52. # 画图展示
  53. plt.figure(figsize=(14, 12))
  54. # seen_point_num = 600   # 刚好是2个子脉冲的 600=2*300  sample_num_per_freq
  55. plt.figure(1)
  56. plt.subplot(2, 2, 1)
  57. plt.plot(np.arange(sample_num_per_freq), Tx_signal, marker='o', markersize=6, markerfacecolor='r')
  58. plt.title('发射信号_时域(实信号)', fontproperties=font, fontsize=16)
  59. # plt.axis([0, 500, -3, 3])
  60. plt.xlabel('time/sample_num')

  61. # plt.subplot(2, 3, 2)
  62. # plt.plot(Tx_signal.imag[:seen_point_num], marker='o', markersize=8, markerfacecolor='r')
  63. # plt.title('发射信号(虚部)', fontproperties=font, fontsize=16)
  64. # # plt.axis([0, 500, -3, 3])
  65. # plt.xlabel('time')

  66. plt.subplot(2, 2, 2)
  67. plt.plot(x_f, Tx_abs_y, 'blue')
  68. plt.title('发射信号的幅度谱(未归一化)', fontproperties=font, fontsize=16)
  69. plt.xlabel('freq')

  70. plt.subplot(2, 2, 3)
  71. plt.plot(np.arange(sample_num_per_freq), window, marker='o', markersize=6, markerfacecolor='r')
  72. plt.title('%s窗' % window_name, fontproperties=font, fontsize=16)
  73. plt.xlabel('time/sample_num')

  74. plt.subplot(2, 2, 4)
  75. # plt.plot(x_f, window_y_fft, 'blue')
  76. plt.plot(x_f_window, window_y_fft_db, 'blue')
  77. plt.title('窗的幅度谱(db)', fontproperties=font, fontsize=16)
  78. plt.xlabel('freq')


  79. plt.figure(2)
  80. plt.subplot(2, 1, 1)
  81. plt.plot(np.arange(sample_num_per_freq), windowed_signal, marker='o', markersize=6, markerfacecolor='r')
  82. plt.title('加窗%s信号_时域(实信号)' % window_name, fontproperties=font, fontsize=16)
  83. # plt.axis([0, 500, -3, 3])
  84. plt.xlabel('time/sample_num')

  85. plt.subplot(2, 1, 2)
  86. plt.plot(x_f, windowed_y_fft, 'blue')
  87. plt.title('加窗%s信号的幅度谱(未归一化)' % window_name, fontproperties=font, fontsize=16)
  88. plt.xlabel('freq')

  89. plt.show()
复制代码


加窗01.png (131.29 KB, 下载次数: 100)

加窗01.png

加窗02.png (88.61 KB, 下载次数: 106)

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-20 17:38 , Processed in 0.185307 second(s), 21 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

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