python实现FFT+滤波

# 日期:2020.08.02
# 功能:
# 产生4个正弦波的原始信号采用FFT将其提取出来并图形化展示,
# 滤波得到原来的分项数据,并图形化展示

import matplotlib.pyplot as plt
import numpy as np
from scipy.fftpack import fft, ifft
import copy

plt.rcParams['font.sans-serif'] = ['SimHei']  # 显示中文
plt.rcParams['axes.unicode_minus'] = False  # 显示负号

# 根据采样定理知采样频率要>信号频率的2倍
# 设置的信号频率分量最高为400赫兹,因此采样点选择1000个
x = np.linspace(0, 1, 1000, endpoint = False)
# 产生原始信号——一个直流信号和四个正弦波的叠加
y = 2 + 4 * np.sin(2 * np.pi * 100 * x) + 6 * np.sin(2 * np.pi * 200 * x) + 8 * np.sin(
    2 * np.pi * 300 * x) + 10 * np.sin(2 * np.pi * 400 * x)
fft_y = fft(y)  # 对y进行傅里叶变换
fd = abs(fft(y))  # 幅度谱
normalization_fd = fd / (len(x) / 2)  # 归一化
normalization_fd[0] = normalization_fd[0] / 2  # 第一个点为直流分量,它的模值就是直流分量的N倍
half_normalization_fd = normalization_fd[range(int(len(x) / 2))]  # 由于对称性,只取一半区间
x = np.arange(len(y))
half_x = x[range(int(len(x) / 2))]  # 取一半区间

plt.subplot(331)
plt.plot(x[0:50], y[0:50])  # 由于采样点太过密集,看起来不好看,我们只显示前面的50组数据
plt.title('原始信号')

plt.subplot(332)
plt.plot(x, fd, 'r')
plt.title('未归一化的幅度谱')

plt.subplot(333)
plt.plot(x, normalization_fd, 'g')
plt.title('归一化后的幅度谱')

plt.subplot(334)
plt.plot(half_x, half_normalization_fd, 'b')
plt.title('归一化后的幅度谱(一半)')

# =============================滤波=============================
filter_y1 = copy.deepcopy(half_normalization_fd)
for i in range(len(half_x)):
    if i > 0:
        filter_y1[i] = 0
filter_y1 = np.fft.ifft(filter_y1)  # =============逆变换========
filter_y1 = filter_y1 * len(x) / 2  # 归一化的逆运算
plt.subplot(335)
plt.plot(half_x[:50], filter_y1[:50], 'g')
plt.title('第一个信号滤波结果')

filter_y2 = copy.deepcopy(half_normalization_fd)
for i in range(len(half_x)):
    if i < 50 or i > 150:
        filter_y2[i] = 0
filter_y2 = np.fft.ifft(filter_y2)
filter_y2 = filter_y2 * len(x) / 2
plt.subplot(336)
plt.plot(half_x[:50], filter_y2[:50], 'g')
plt.title('第二个信号滤波结果')

filter_y3 = copy.deepcopy(half_normalization_fd)
for i in range(len(half_x)):
    if i < 150 or i > 250:
        filter_y3[i] = 0
filter_y3 = np.fft.ifft(filter_y3)
filter_y3 = filter_y3 * len(x) / 2
plt.subplot(337)
plt.plot(half_x[:50], filter_y3[:50], 'g')
plt.title('第三个信号滤波结果')

filter_y4 = copy.deepcopy(half_normalization_fd)
for i in range(len(half_x)):
    if i < 250 or i > 350:
        filter_y4[i] = 0
filter_y4 = np.fft.ifft(filter_y4)
filter_y4 = filter_y4 * len(x) / 2
plt.subplot(338)
plt.plot(half_x[:50], filter_y4[:50], 'g')
plt.title('第四个信号滤波结果')

filter_y5 = copy.deepcopy(half_normalization_fd)
for i in range(len(half_x)):
    if i < 350:
        filter_y5[i] = 0
filter_y5 = np.fft.ifft(filter_y5)
filter_y5 = filter_y5 * len(x) / 2
plt.subplot(339)
plt.plot(half_x[:50], filter_y5[:50], 'g')
plt.title('第五个信号滤波结果')
plt.show()

你可能感兴趣的:(python,傅立叶分析,信号处理,可视化)