【问题标题】:Using fft to extract frequency使用 fft 提取频率
【发布时间】:2019-11-08 13:13:08
【问题描述】:

我有一个信号是两个频率的线性组合,我正在尝试使用 MATLAB 来确定(主)信号的频率。作为输入,我有采样率rate 和带有信号数据的行向量segment

现在我有以下代码:

N=length(segment);

freq = rate*(0:N/2)/N;
X = fft(segment);
X=X(1:N/2+1);

plot(freq*2, abs(X))

这确实返回了一个具有两个峰值的图形,一个在信号所包含的每个频率上。现在我想提取这些频率。所以我想返回一个变量signal,它是两个频率的向量。

因此,如果我的信号是由30 Hz60 Hz 之一的信号的线性组合创建的,那么我想要signal = [30,60]。我可以创建一个图表然后识别它,但我想去掉那个中间人,只返回找到的频率,而不使用任何工具箱。

我怎样才能找到我想要的频率?

【问题讨论】:

    标签: matlab signal-processing fft continuous-fourier


    【解决方案1】:

    没有工具箱:选择一些您认为可以接受的阈值,然后简单地执行abs(x)>threshold,这将为您提供一个逻辑数组以索引到freq,给出高于阈值的频率。为了提高准确性,您可以在结果数组上执行diff() 之类的操作,并找到相邻的索引,然后选择该序列上那些连续索引的最大值作为那里的“峰值”。

    或者,您可以sort() 值,保留最大n(在您的情况下为 2)值的索引并将其索引到频率数组中。同样不是一个非常健壮的方法,但又快又脏。

    结合上述两种技术,您可以根据排序后的数组迭代地降低阈值,然后检查峰值的接近度、突出度等。

    如果您不想自己实现这一切,请参阅下面的一站式功能来执行此操作。


    如果您愿意使用信号处理工具箱,您可以使用findpeaks()。这为您提供了索引,然后您可以使用它来索引您的频率阵列以获得所需的频率。或者使用peaks = findpeaks(data,x) 语法直接提取x 位置(在您的情况下为频率)。

    【讨论】:

    • 但是如果较高的峰值在其频带中的某些频率高于第二个峰值,它会返回非常接近的两个频率并且它会失去第二个频率,对吗?
    • @Mathbeginner 这就是为什么我说它不是很健壮。唯一简短的解决方案是求助于内置的峰值查找算法,如 findpeaks(),任何比这更长的时间都需要自己实现一个峰值查找算法,我认为这对于 Stack Overflow 的答案来说是广泛的。
    【解决方案2】:

    我最终做的是使用max() 函数。这将返回峰值,然后相应的 x-index 将与正确的频率相对应。检索到这个频率后,我选择了峰值周围的某个括号并将这些索引设置为零。然后我会再次运行max() 来查找第二个峰值及其对应的频率。

    【讨论】:

      【解决方案3】:

      2 种简单的方法:

      1. 获取返回的 fft 数组,并用每个峰值(一次 1 个)替换部分并用零替换(这样你最终只有 1 个峰值。然后对数组执行逆 fft 以检索没有归零频率的信号。

      2. 如果您知道原始信号的相位 - 一次取一个并创建一个仅具有该频率的新信号并将其反转(即 0 信号 - 它上升的地方现在下降了!)。并将它添加到原始信号中。该频率将从音频信号中消失,需要 fft(验证结果除外。

      【讨论】:

        猜你喜欢
        • 2013-01-13
        • 1970-01-01
        • 2013-04-01
        • 2012-05-18
        • 1970-01-01
        • 1970-01-01
        • 2013-06-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多