繁体   English   中英

我在Python中计算的傅里叶变换是否显示在时域中? 如果是这样,我如何在频域中显示它?

[英]Is the Fourier transform I am computing in Python displayed in the time domain? If so, how can I display this in the Frequency domain?

我的目标是检测录音中是否存在特定频率和 output 二进制响应。 为此,我计划对音频文件执行傅里叶变换,并查询频点中包含的值。 如果我发现与我要查找的频率相关联的 bin 具有很高的值,这应该意味着它存在(如果我的想法是正确的)。 但是,我无法正确生成转换。 我的代码如下:

from scipy.io import wavfile
from scipy.fft import fft, fftfreq
from matplotlib import pyplot as plt
import numpy as np
import pandas as pd

user_in = input("Please enter the relative path to your wav file --> ")
sampling_rate, data = wavfile.read(user_in)
print("sampling rate:", sampling_rate)

duration = len(data) / float(sampling_rate)
print("duration:", duration)

number_samples_in_seg = int(sampling_rate * duration)
fft_of_data = fft(data)
fft_bins_from_data = fftfreq(number_samples_in_seg, 1 / sampling_rate)

print(fft_bins_from_data.size)

plt.plot(fft_bins_from_data, fft_of_data, label="Real part")
plt.show()

使用几个不同的 wav 文件尝试这段代码让我想知道我是否在时域而不是我需要的频域中显示我的变换:

输入:200hz.wav

Output:

sampling rate: 48000
duration: 60.000375
2880018

绘图输出 200hz

输入:8000hz.wav

Output:

sampling rate: 48000
duration: 60.000375
2880018

绘图输出 8000hz

对于这些应该包含纯信号的文件,我希望在我的 plot 上只看到一个尖峰,其中 x = 200 或 x = 800。最后一个文件让我担心我没有查看频域:

输入:beep.wav

Output:

sampling rate: 48000
duration: 5.061958333333333
24297

绘图输出蜂鸣声

这似乎显示了明显的哔哔声,因为它在时间的 x 轴上进行。

我试图通过仅绘制正值的大小来清理绘图。 不幸的是,我仍然没有看到频谱上孤立的频率:

plt.plot(fft_bins_from_data[0:number_samples_in_seg//2], abs(fft_of_data[0:number_samples_in_seg//2])
plt.show()

哔声 output 已更新

我在发帖前参考了这些资源:

如何获取wav文件中的频率列表

Python频率检测

傅立叶变换 scipy.fft: Python 信号处理

计算python中特定频率信号的幅度和相位

numpy.fft.fft 和 numpy.fft.fftfreq 有什么区别

我的问题摘要:

  1. 我的图表显示的是信号的时域还是频域?
  2. 为什么样本数等于 bin 数,频域应该是这种情况吗?
  3. 如果这些图确实是频域,我该如何解释它们并查询 bin 中的值?

尝试这个:

import scipy as sp
import scipy.signal as sig
import numpy as np
from numpy import fft
import matplotlib.pyplot as plt

number_samples_in_seg = len(data)
time_axis = np.arange(0, number_samples_in_seg)/sampling_rate
win = sig.windows.hann(number_samples_in_seg)
windowed_data = win*data
plt.plot(time_axis, windowed_data)

plot 如果不是很明显的话,这将是时域中的信号。 我对信号应用了 Hann window,如果信号的开始和结束不匹配(因为 FFT 假定信号片段是周期性的),这将减少伪影。

对于 FFT 的绘图:

fft_data = fft.fft(windowed_data)[0:int(np.floor(number_samples_in_seg/2))]
freq_axis = sp.fft.fftfreq(number_samples_in_seg, 1.0/sample_rate)[0:int(np.floor(number_samples_in_seg/2))]
plt.plot(freq_axis, 20.0*np.log10(np.abs(fft_data)))

fft_datafreq_axis上的方括号索引是为了消除 FFT 的负频率部分。 我在 Audacity 中生成了一个 200Hz 的正弦波,长度为 4096 个样本(只是为了使其适合二次方以进行良好的 FFT-ing)并且在我的 plot 中有一个 200Hz 的峰值。还要注意20*log10(abs(fft_data))以 dB 为单位绘制的东西。

以上应该回答你的问题#3。 至于问题 #2,FFT 始终具有相同数量的时间点和频率点。 不确定问题 #1,但同样,上面的代码应该解决这个问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM