python - 计算 FFT 峰的强度
问题描述
对于物理实验室,我们的教授给了我们一项任务,即分析弹拨弦的频谱。在声音采集之后,我们得到了一个执行 FFT 的脚本。
然后他告诉我们,我们必须分别计算每个峰的强度。我是这个主题的新手,所以我请求你帮助如何改变给定的代码以获得输出峰值强度,比如说从 760 到 765 Hz。
代码在这里:
from scipy.fftpack import fft,ifft
import matplotlib.pyplot as plt
from scipy.signal import blackman
data = np.loadtxt("mic.txt")
x = data[:,0]
y = data[:,1]
fy = fft(y)
print np.sum(y),"==",fy[0]
n = len(x)
t = x[-1]
fx = np.linspace(0,n/t,n)
plt.plot(fx[0:n/2],np.abs(fy[0:n/2]))
plt.xlabel("frequency (Hz)")
plt.show()
我会很感激你的帮助,马修
解决方案
通过峰值强度,我假设您的意思是每个峰值的大小(当然它可以归一化)。我曾经scipy.signal.find_peaks
得到光谱中的峰值。因为 FFT 返回复数值,所以我将它用于 y 的绝对值。这是一个通用示例,因此在大多数情况下找到最大值并不是那么简单。还有其他峰值检测工具,例如scipy.signal.find_peaks_cwt
,或peakutils
包。从scipy 教程这里是一个最小的工作示例:
import numpy as np
from scipy.fft import fft
import matplotlib.pyplot as plt
from scipy.signal import find_peaks
N = 600
T = 1.0 / 800.0
x = np.linspace(0.0, N*T, N)
y = np.sin(50.0 * 2.0 * np.pi * x) + 0.5 * np.sin(80.0 * 2.0 * np.pi * x)
yf = fft(y)
xf = np.linspace(0.0, 1.0 / (2.0 * T), N//2)
# finding the peaks in the absolute value of y
y_abs = 2.0 / N * np.abs(yf[0:N//2])
peakind, _ = find_peaks(y_abs)
plt.plot(xf, y_abs)
# plotting the peaks
plt.plot(xf[peakind], y_abs[peakind], 'k.')
plt.grid()
plt.show()
山峰的大小只是
>>> y_abs[peakind]
[0.70947072 0.4914645 ]
推荐阅读
- visual-studio-code - Visual Studio 代码 DPI 或渲染设置问题
- java - 容器上的 JVM 调优 (Java 8)
- c++ - 将 Htslib 用于提取替代等位基因信息的 VCF 文件
- r - 删除单个重复列并将它们放置在 R 中
- python - 熊猫数据框,如果条件匹配和索引彼此相邻:添加值并删除使用的行
- python - matplotlib.show() 似乎什么也没做
- node.js - 如何在猫鼬中填充对象数组中的每个元素?
- azure-devops - Azure Pipeline Cron Scheduler:不要同时轮询所有分支
- r - 在 r 中使用 dplyr 有效地重塑数据帧
- matomo - Matomo 中的目标创建问题