从数据获取FFT峰值
我正在开发一个使用八度从头开始的语音识别系统。 我试图通过检测频率的差异来检测音素。 目前我已经阅读了一个wav文件,将这些值组织成块并将fft
应用于整体数据。 之后,我绘制新的数据与plot(abs(real(fft(q))))
创build此图:
我怎样才能得到频率值(图表的峰值)?
如果你没有findfindpeaks
,它背后的基本前提是你的信号中的每一个点都search一个以此为中心的三元窗口,并检查这个窗口的中心是否更大比这个窗口的左边和右边的元素。 您希望能够find正峰值和负峰值,所以您需要检查绝对值。
因此,你可以做的是做两个额外的信号,将信号左移1,右1。当我们这样做时,我们实际上将检查从信号的第二个元素开始的峰值,为了腾出空间向左看。 我们继续检查,直到倒数第二个元素 ,以便腾出空间向右看。 因此,我们实际上将检查N - 2
版本信号的峰值,其中N
是信号的长度。 因此,当我们创build左移信号时,我们提取信号的第一个元素直到第三个元素 。 当我们创build右移信号时,我们从第三个元素提取直到最后一个元素。 原始信号将只删除其第一个和最后一个元素。
因此,通过这种方式检查峰值,我们将会丢失数据的第一个和最后一个点,但这应该是合适的,因为在开始和结束时最有可能不会出现峰值。 之后,创build所有这些信号,只需使用逻辑索引来查看原始信号(没有第一个和最后一个元素)中的对应值是否大于其对应位置中的另外两个信号。
因此,假设您的信号存储在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
将包含峰值出现位置的索引位置。 请记住,我们开始在第二个位置search峰值,所以你需要加1来适应这个转变。 如果你想find实际的时间(或你的情况下的频率)值,你可以使用idx
索引到用来产生信号的时间(或频率)数组中,并find它们。 因此,让我们使用一个仿真案例,我从0到3秒,频率为1 Hz,产生一个正弦曲线。 因此:
t = 0 : 0.01 : 3; f = sin(2*pi*t);
现在,如果我们用这个信号运行上面的代码,我们会find我们峰值的位置。 然后,我们可以使用这些位置索引到t
和f
并绘制信号以及我们检测到峰值的位置。 因此:
plot(t, f, t(idx), f(idx), 'r.')
这是我得到的:
请记住,这是检测峰值的一种非常简单的方法,但这是findpeaks
基本上完成的。 如果你使用上面的代码,它基本上会find所有的峰值 。 因此,代码会在上图中find几十个峰值,因为在您的频谱中存在局部最大值。 你可能想要确定强峰位置。 人们通常用一个阈值来表示峰值的大小应该在多大之后才能决定是否是有效峰值。 因此,你可以执行一个门槛,做这样的事情:
thresh = ... ; %// Define threshold here idx = find(f1 > f2 & f1 > f3 & f1 > thresh) + 1; %// Get the locations of where we find our peaks
在你的情况下,你可能想要设置这个,以便find任何峰值大于10的峰值。
还有很多其他的东西,比如过滤掉嘈杂的峰值和一些其他强有力的措施。 如果你想使用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。 我build议你做简单的事情就是安装Homebrew或者MacPorts,并以这种方式获得Octave。 一旦你安装它,那么你应该能够得到mkoctfile
工作。 但是,如果仍不能,则可能需要安装兼容的编译器。 简单的方法是从Xcode安装命令行开发工具。 转到此链接,然后转到其他工具。
祝你好运!
您可以使用倍频程信号包中的findpeaksfunction:
http://octave.sourceforge.net/signal/function/findpeaks.html