从数据获取FFT峰 [英] Getting FFT peaks from data

查看:97
本文介绍了从数据获取FFT峰的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am developing a speech recognition system from scratch using Octave. I am trying to detect phonemes by detecting differences in frequency. Currently I have read in a wav file, organized the values into blocks and applied fft to the overall data. After, I plot the new data with plot(abs(real(fft(q)))) which creates this graph:

如何获取频率值(图形的峰值)?

How could I get the frequency values (the peaks of the graph)?

推荐答案

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

If you don't have access to findpeaks, the basic premise behind how it works is that for each point in your signal, it searches a three element window that is centred at this point and checks to see whether the centre of this window is larger than the left and right element of this window. You want to be able to find both positive and negative peaks, so you'd need to check the absolute value.

这样,您可以做的是制作两个附加信号,这些信号将信号向左移动1,向右移动1.当我们这样做时,我们实际上将检查从 second开始的峰值信号,以便为向左看留空间.我们会一直进行检查,直到倒数第二个元素,以便为向右看提供空间.因此,我们实际上将检查信号的N - 2版本中的峰值,其中N是信号的长度.因此,当我们创建左移信号时,我们提取信号的第一个元素,直到最后一个元素.当我们创建右移信号时,我们从第三个元素提取直到最后一个元素.原始信号只会删除其第一个和最后一个元素.

As such, what you can do is make two additional signals that shift the signal to the left by 1 and to the right by 1. When we do this, we will actually be checking for peaks starting at the second element in your signal, in order to make room for looking to the left. We keep checking up until the second last element, in order to make room for looking to the right. Therefore, we will actually be checking for peaks on a N - 2 version of the signal where N is the length of your signal. Therefore, when we create the left shifted signal, we extract the first element of the signal up until the third last element. When we create the right shifted signal, we extract from the third element up until the last element. The original signal will simply have its first and last elements removed.

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

Therefore, by checking for peaks this way, we will lose out on the first and last point of your data, but that should be suitable as there most likely won't be any peaks at the beginning and at the end. After, creating all of these signals, simply use logical indexing to see whether the corresponding values in the original signal (without the first and last elements) are larger than the other two signals in their corresponding positions.

这样,假设您的信号存储在f中,您将执行以下操作:

As such, supposing your signal was stored in f, you would do the following:

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将包含出现峰的索引位置.请记住,我们开始在 second 位置搜索峰,因此您需要加1 来适应这种变化.如果要查找实际时间(或您的情况下的频率)值,只需使用idx索引到用于生成信号并找到它们的时间(或频率)数组即可.因此,让我们使用一个人工情况,其中我会以0 Hz的频率生成0到3秒的正弦曲线.因此:

idx will contain the index locations of where the peaks occur. Bear in mind that we started searching for peaks at the second position, and so you need to add 1 to accommodate for this shift. If you wanted to find the actual time (or frequency in your case) values, you would just use idx to index into the time (or frequency) array that was used to generate your signal and find them. As such, let's use an artificial case where I generate a sinusoid from 0 to 3 seconds with a frequency of 1 Hz. Therefore:

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

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

Now, if we ran the above code with this signal, we'd find the location of our peaks. We can then use these locations to index into t and f and plot the signal as well as where we have detected our peaks. Therefore:

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

这就是我得到的:

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

Bear in mind that this is a very simple way of detecting peaks, but that is what is essentially done in findpeaks. If you used the above code, it would basically find all peaks. As such, the code would find dozens of peaks in that above graph, because there are local maxima all over your spectrum. You probably want to determine where the strong peaks are located. What people usually do is use a threshold to signify how large the peak should be before deciding whether that is a valid peak. As such, you can enforce a threshold, and do something like this:

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

就您的图形而言,您可能需要进行设置,以便找到幅度大于10的任何峰.

In your case for your graph, you may want to set this so that you find any peaks whose magnitude is larger than 10 perhaps.

findpeaks还有很多其他功能,例如滤除噪声峰值和一些其他可靠的措施.如果要使用findpeaks,则需要确保安装信号包.您可以简单地使用Octave命令提示符中的pkg install并安装signal软件包.具体来说,请尝试以下操作:

There are a lot of other things that findpeaks does, such as filtering out noisy peaks and some other robust measures. If you want to use findpeaks, you need to make sure that you install signal package. You can simply use pkg install from the Octave Command Prompt and install the signal package. Specifically, try this:

pkg install -forge signal

一旦安装了signal软件包,您可以通过以下操作将其加载到Octave环境中:

Once you install the signal package, you can load it into the Octave environment by doing:

pkg load signal

如果必须安装依赖项,它将在尝试安装signal软件包时告诉您.请查看此链接以获取更多详细信息: https://www.gnu. org/software/octave/doc/interpreter/Installing-and-Removing-Packages.html

If you have to install dependencies, it'll tell you when you try to install the signal package. Check out this link for more details: https://www.gnu.org/software/octave/doc/interpreter/Installing-and-Removing-Packages.html

mkoctfile代表制作/编译八度音阶文件.如果没有mkoctfile,请确保已安装最新版本的Octave.为了简化操作,我建议您安装 Homebrew MacPorts 并以这种方式获取Octave.安装后,您应该就能使mkoctfile工作.但是,如果仍然不能,则可能需要安装兼容的编译器.一种简单的方法是从Xcode安装Command Line Developer工具.转到此链接,然后转到其他工具".

mkoctfile stands for making / compiling an Octave file. If you don't have mkoctfile, make sure you have the most recent version of Octave installed. What I recommend you do to make things simple is to install either Homebrew or MacPorts and get Octave in that fashion. Once you install it, then you should be able to get mkoctfile working. However, if you still can't, you may need to have a compatible compiler installed. The easy approach is to install the Command Line Developer tools from Xcode. Go to this link then go to Additional Tools.

祝你好运!

这篇关于从数据获取FFT峰的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆