【问题标题】:FFT in python not giving the expected result [closed]python中的FFT没有给出预期的结果[关闭]
【发布时间】:2021-08-31 19:18:30
【问题描述】:

最近我一直在尝试通过 python 计算信号的 FFT。 问题是,我只在 fft 图中得到基频。如下:

如果我们查看“Sinal”图,那么谐波比我在 FFT 中得到的要多得多。我将波形与示波器进行了比较,似乎相等,但 FFT 与示波器计算的波形有很大不同。另外,我不知道为什么 FFT 看起来那么干净。

我正在使用此代码。

import numpy
from matplotlib import pyplot as plt
from scipy import fft, signal
import csv

with open('output.csv') as csv_file:
    csv_reader = csv.reader(csv_file, delimiter=',')
    line_count = 0
    data=[]
    time=[]

    count = 0
    for row in csv_reader:
        data.append(row)
        count += 1
    i = 0
    rec_data = []
    data = numpy.array(data)
    while i < count:
        rec_data.append(float(data[i]))
        i+=1
    
    recv_data = rec_data - numpy.mean(rec_data)

    time_step = 1/9835
    fft_transform_complex = fft.fft(recv_data)
    print(fft_transform_complex)
    fourrier_transform = 2/50000 * numpy.abs(fft_transform_complex) #Tira o módulo e normaliza o valor
    sample_frequencies = fft.fftfreq(50000, time_step)
    fig, axs = plt.subplots(2, 1, constrained_layout=True)
    fig.suptitle('Sinal e FFT')
    axs[0].plot(recv_data)
    # O filtro atrasa o sinal, por isso não pode pegar o sinal no começo
    axs[0].set_xlim([0,450])
    axs[0].set_title('Sinal')
    axs[0].set_ylabel('Corrente [A]')
    axs[0].set_xlabel('Amostra [n]')
    axs[1].plot(sample_frequencies, fourrier_transform)
    axs[1].set_xlim([0,300])
    axs[1].set_title('FFT')
    axs[1].set_ylabel('Amplitude')
    axs[1].set_xlabel('Frequência [Hz]')
    plt.show()

【问题讨论】:

  • 请提供预期的minimal, reproducible example (MRE)。我们应该能够复制和粘贴您的代码的连续块,执行该文件,并重现您的问题以及跟踪问题点的输出。这让我们可以根据您的测试数据和所需的输出来测试我们的建议。
  • 您的大部分代码都与您未提供的数据的摄取有关。对该数据进行硬编码,并提供您要与之比较的备用 FFT 结果。
  • 抱歉,此链接包含输出此数据的 csv 文件。 [链接] (drive.google.com/file/d/1TVMp-pr4WGxX72J_DM5X8ha6i5FDiirE/…)。示波器数据可在此处获得 [链接] (drive.google.com/file/d/1TVMp-pr4WGxX72J_DM5X8ha6i5FDiirE/…)。我还不能在我的程序中使用示波器数据,因为采样率不同。
  • 不接受站外链接和文字图片;您的帖子必须是独立的,符合本网站的目的。

标签: python numpy scipy signal-processing fft


【解决方案1】:

首先,matplotlib 有一个用于生成幅度谱图的内置方法,让您不必再猜测哪里可能存在错误。 您所有的 FFT 代码都可以替换为:

Fs = 9835
axs[1].magnitude_spectrum(recv_data, Fs, sides='onesided')
axs[1].set_xlim([0,500])
axs[1].set_title('FFT')
axs[1].set_ylabel('Amplitude')
axs[1].set_xlabel('Frequência [Hz]')

magnitude_spectrum 也会执行 FFT。

与您的示波器相比,Y 轴刻度很可能会关闭。 您正在使用线性刻度绘制 FFT,但工具更常见的是使用对数 dB 刻度。

尝试: axs[1].magnitude_spectrum(recv_data, Fs, sides='onesided', scale='dB') 你会得到类似的东西

如果不是很接近,您的示波器不太可能同时对整个 50k 个样本进行 FFT。尝试将幅度谱调用更改为:

axs[1].magnitude_spectrum(recv_data[0:1024], Fs, sides='onesided', scale='dB')

它可能与您在示波器中看到的更接近。

【讨论】:

  • 非常感谢,我真的忘记了日志部分。而且,这个内置的方法省了很多工作,真的很不错!再次,非常感谢。
猜你喜欢
  • 2018-12-08
  • 2021-01-06
  • 1970-01-01
  • 1970-01-01
  • 2020-05-29
  • 1970-01-01
  • 2019-06-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多