matlab中的FFT,出乎意料的结果
Posted
技术标签:
【中文标题】matlab中的FFT,出乎意料的结果【英文标题】:FFT in matlab, unexpected results 【发布时间】:2014-02-06 10:03:21 【问题描述】:我正在玩 FFT,但似乎无法获得预期的结果。我有一个声音片段,是从放置在模拟时钟上的麦克风录制的。所以它每秒都有声音。
[wave,fs]=wavread('clock.wav');
t=0:1/fs:(length(wave)-1)/fs;
plot(t,wave);
n=length(wave)-1;
f=0:fs/n:fs;
wavefft=abs(fft(wave));
plot(f,wavefft);
这是我正在使用的代码。以下是结果。
我应该在 1hz 看到一个巨大的尖峰,但我没有。
FFT 之后是声波。
【问题讨论】:
您应该意识到,在您的第一张图像中,“x”轴并不代表实际频率。当您执行 FFT 时,结果在 0Hz 是对称的,您可以清楚地看到您的 FFT 在 4000 左右是对称的。所以结果可能是正确的,但你没有正确绘制它。 @AnderBiguri 没关系,因为频谱在 4000 左右是周期性的,在这种情况下是 fs/2。此格式是fft
函数的默认格式。要显示零附近的频谱,您应该使用fftshift
。
@Adiel 你说的很对,我只是快速浏览了一下问题,我错了。
@adiel 谢谢!我会试试这个,让你知道它是否有效!。
我使用了 fft shift,得到了更好的结果。我在彼此相等的距离处得到多个峰。这是因为峰很尖,所以使用了正弦/余弦的倍数来制作峰?
【参考方案1】:
您看到的就是您的麦克风录制的内容。标准麦克风过滤非常低的频率,即低于 20 Hz,声卡也可能过滤低频。
每秒有一个滴答声并不意味着您会在 FFT 上看到 1Hz 的巨大峰值。如果您想在 1hz 看到那个巨大的峰值,请记录一个由 1Hz 的正弦波组成的信号。但是,正如我上面所说,要小心低频。音响系统测试的常用频率为 1000 Hz。
以下是您的信号clock.wav 的时间视图,带有缩放功能。我们可以看到它是由许多谐波组成的,我们可以清楚地看到它远不是1Hz的正弦波。
然后我用低通二阶型巴特沃斯过滤信号,截止频率为 100Hz。
请看过滤前的黄色光谱,过滤后的蓝色光谱。
所以,我相信你的matlab代码没有什么大问题。
【讨论】:
如果你看上面的图片(第二张)你会看到麦克风确实把它捡起来了。 仍然很难相信您的输入信号真的有您的声卡记录的 1Hz 谐波。您能否将文件clock.wav 放到某个地方,我将尝试使用我的python 脚本(使用scipy.signal)?除此之外,如果您想确定有 1Hz 谐波,请对您的信号进行低通滤波。使用截止频率为 1Hz 的 Butterworth 或 Tchebychev,您会看到。 它们不是 1hz 谐波。它们是相隔 1 秒的声音爆发。 好的,让我真正开始讨论主要问题。我正在制作一个测量心跳的应用程序。我正在用时钟做一些测试,但基本上我想知道心跳什么时候开始,什么时候结束。 我考虑的解决方案是我将对小样本(2-4 秒样本)进行 FFT,然后查看我在 1hz 标记附近开始获得峰值的位置。如果这是不可能的,你能告诉我我能做什么吗?心跳听起来很相似,并且与时钟的频率相似,所以我用它来测试。你能给我一些建议,我应该研究什么样的技术来解决这个问题?【参考方案2】:请注意,在时域中,峰值之间存在大量噪声。它在时间上似乎很少,但在频域中却非常重要。可能噪声的主频约为 1000+ Hz。
尝试再次录制,没有时钟滴答声(只有“沉默”),然后从原始信号中减去它......我怀疑它是否会起作用,但你可以尝试......
您也可以通过一个简单的阈值从信号中挑选峰值,然后您将保持时钟滴答声。
编辑:另一个建议是通过低通滤波器中的信号,以滤除高频噪声。
【讨论】:
【参考方案3】:由于您要在声音片段的幅度包络中寻找低频周期性,而不是音调波形或音高,您可以尝试在应用 fft 之前对信号进行平方或取绝对值,然后忽略更高的结果中的频率分档。
【讨论】:
以上是关于matlab中的FFT,出乎意料的结果的主要内容,如果未能解决你的问题,请参考以下文章
Matlab fft 和 Scipy fft 的 FFT 结果略有不同
fft2 (matlab) 和 fftw (C) 的不同结果
为啥我的 NAudio FFT 结果与 MATLAB 相差 4 倍?