【问题标题】:Getting FFT peaks from data从数据中获取 FFT 峰值
【发布时间】:2015-01-20 19:31:52
【问题描述】:

我正在使用 Octave 从头开始​​开发语音识别系统。我试图通过检测频率差异来检测音素。目前我已读入一个 wav 文件,将值组织成块并将fft 应用于整体数据。之后,我使用plot(abs(real(fft(q)))) 绘制新数据,从而创建此图:

如何获得频率值(图表的峰值)?

【问题讨论】:

    标签: matlab fft speech-recognition octave


    【解决方案1】:

    您可以使用 octave 信号包中的 findpeaks 函数:

    http://octave.sourceforge.net/signal/function/findpeaks.html

    【讨论】:

    • 我没有 osx 的“mkoctfile”程序。你知道我在哪里可以买到吗?
    【解决方案2】:

    如果您无法访问findpeaks,其工作原理的基本前提是,对于信号中的每个点,它会搜索以该点为中心的三元素窗口,并检查中心是否这个窗口的元素大于这个窗口的左右元素。您希望能够同时找到正峰值和负峰值,因此您需要检查绝对值。

    因此,您可以做两个额外的信号,将信号向左移动 1,向右移动 1。当我们这样做时,我们实际上将检查从 秒开始的峰值元素,以便为向左看腾出空间。我们一直检查到倒数第二个元素,以便为向右查找腾出空间。因此,我们实际上将检查信号的N - 2 版本的峰值,其中N 是您的信号长度。因此,当我们创建左移信号时,我们会提取信号的第一个元素直到倒数第三个元素。当我们创建右移信号时,我们从第三个元素中提取直到最后一个元素。原始信号将简单地删除其第一个和最后一个元素。

    因此,通过这种方式检查峰值,我们将丢失数据的第一个和最后一个点,但这应该是合适的,因为在开始和结束时很可能不会有任何峰值。在创建所有这些信号之后,只需使用逻辑索引来查看原始信号中的对应值(不包括第一个和最后一个元素)是否大于其对应位置的其他两个信号。

    因此,假设您的信号存储在f,您将执行以下操作:

    f1 = abs(f(2:end-1)); %// Original signal
    f2 = abs(f(1:end-2)); %// Left shift
    f3 = abs(f(3:end)); %// Right shift
    
    idx = find(f1 > f2 & f1 > f3) + 1; %// Get the locations of where we find our peaks
    

    idx 将包含出现峰值的索引位置。请记住,我们开始在 第二 位置搜索峰值,因此您需要添加 1 以适应这种转变。如果您想找到实际的时间(或频率)值,您只需使用idx 来索引用于生成信号并找到它们的时间(或频率)数组。因此,让我们使用一个人工案例,我生成一个 0 到 3 秒、频率为 1 Hz 的正弦曲线。因此:

    t = 0 : 0.01 : 3;
    f = sin(2*pi*t);
    

    现在,如果我们使用此信号运行上述代码,我们将找到峰值的位置。然后我们可以使用这些位置来索引tf 并绘制信号以及我们检测到峰值的位置。因此:

    plot(t, f, t(idx), f(idx), 'r.')
    

    这是我得到的:

    请记住,这是一种非常简单的检测峰值的方法,但这实际上是在 findpeaks 中完成的。如果您使用上面的代码,它基本上会找到所有峰值。因此,代码会在上图中找到数十个峰值,因为在整个频谱中都有局部最大值。您可能想要确定 strong 峰的位置。人们通常做的是使用阈值来表示峰值应该有多大,然后再决定它是否是有效的峰值。因此,您可以强制执行阈值,并执行以下操作:

    thresh = ... ; %// Define threshold here
    idx = find(f1 > f2 & f1 > f3 & f1 > thresh) + 1; %// Get the locations of where we find our peaks
    

    就您的图表而言,您可能需要设置此项,以便找到幅度可能大于 10 的任何峰值。


    findpeaks 还可以做很多其他事情,例如过滤掉噪声峰值和其他一些稳健的措施。如果你想使用findpeaks,你需要确保你安装了信号包。您可以简单地使用 Octave 命令提示符中的 pkg install 并安装 signal 包。具体来说,试试这个:

    pkg install -forge signal
    

    安装signal 包后,您可以通过以下方式将其加载到 Octave 环境中:

    pkg load signal
    

    如果您必须安装依赖项,它会在您尝试安装 signal 包时告诉您。查看此链接了解更多详情:https://www.gnu.org/software/octave/doc/interpreter/Installing-and-Removing-Packages.html

    mkoctfile 代表制作/编译 Octave 文件。如果您没有mkoctfile,请确保您安装了最新版本的 Octave。为了简单起见,我建议您安装HomebrewMacPorts 并以这种方式获取Octave。一旦你安装它,那么你应该能够让mkoctfile 工作。但是,如果仍然不能,则可能需要安装兼容的编译器。简单的方法是从 Xcode 安装命令行开发工具。转到to this link,然后转到其他工具。

    祝你好运!

    【讨论】:

    • 这太棒了!太感谢了!这对我有用!最后一件事,有什么方法可以将这些点放入矩阵中?
    • 图表上所有的峰值点(红点)。
    • @user2809184 是的。就做f(idx)
    • @user2809184 如果我帮助了你。请考虑接受我的回答!
    猜你喜欢
    • 2019-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-11
    • 1970-01-01
    相关资源
    最近更新 更多