在 MATLAB 中根据信号数据确定频率

Posted

技术标签:

【中文标题】在 MATLAB 中根据信号数据确定频率【英文标题】:Determine frequency from signal data in MATLAB 【发布时间】:2013-02-22 01:22:10 【问题描述】:

我有来自传感器的数据,我需要找到它的频率。看起来fft() 似乎是要走的路,但 MATLAB 文档只显示了如何获取频率图,我不知道从那里做什么。

我的数据如下所示:

【问题讨论】:

【参考方案1】:

一种方法确实是使用 fft。由于 fft 为您提供了信号的频率表示,因此您想要寻找最大值,并且由于 fft 是一个复杂的信号,您需要首先获取绝对值。该指数将对应于具有最大能量的归一化频率。最后,如果您的信号有偏移,就像您展示的那样,您希望在获取 fft 之前消除该偏移,这样您就不会在代表 DC 分量的原点处获得最大值。

我在一行中描述的所有内容都是:

[maxValue,indexMax] = max(abs(fft(signal-mean(signal))));

其中 indexMax 是可以找到最大 fft 值的索引。

注意:要从 indexMax 到实际感兴趣的频率,您需要知道 fft 的长度 L(与您的信号长度相同)和采样频率 Fs。信号频率将为:

frequency = indexMax * Fs / L;

或者,根据您拥有的信号,更快且工作得相当好,对您的信号进行自相关:

autocorrelation = xcorr(signal);

并找到出现在自相关中心点之后的第一个最大值。 (自相关将以其最大值在中间对称。)通过找到该最大值,您可以找到移位信号看起来或多或少与自身相似的第一个位置。 IE。你找到你的信号的周期。由于偏移其周期倍数的信号总是看起来像它自己,因此您需要确保找到的最大值确实对应于信号的周期,而不是其倍数之一。

由于信号中的噪声,绝对最大值很可能出现在周期的倍数处,而不是周期本身。因此,要考虑该噪声,您将获取自相关的绝对最大值(自相关(长度(自相关)/2+1),然后找到自相关大于第一个最大值的 95% 的位置信号后半部分的时间。95%、99% 或其他数字将取决于有多少噪声会破坏您的信号。

更新:我意识到我假设您所说的信号的“频率”是指具有最多能量的音高或基本谐波或频率,但是您想查看它。如果频率是指信号的频率表示,那么对于第一个近似值,您只想绘制 FFT 的绝对值以了解能量在哪里:

plot(abs(fft));

如果您想了解为什么会有绝对值,或者由于不表示 fft 的相位而丢失了哪些相关信息,您可能需要阅读更多有关 DFT 变换的信息,以准确了解您得到的信息。

【讨论】:

我得到的信号来自使用应变仪测量的一些振荡。我想找到这些振荡的频率。使用您发布的fft 方法,我得到 0.0357 的频率,但是通过查看绘图,每秒大约有 10 个周期,所以我不应该得到大约 10 个频率吗? 如果你每秒有 10 次振荡,那确实是 0.1 秒的周期或 10 赫兹的频率。 indexMax、L 和 Fs 的值是多少?还运行 plot(abs(fft)) 以确认您有一个大峰值,并且 indexMax 是该峰值发生位置的正确索引。我注意到在图表中,您的信号中有一个负偏移,这意味着您的 fft 也会有一个接近零的尖峰,代表直流分量。它可能是你正在测量的。如果是这种情况,请使用 (signal-mean(signal)) 的 fft 来移除该直流分量。 我得到的峰值为零(indexMax = 1)。我做了你所说的减去平均值(信号),现在我得到了大约 9.8 Hz 的频率,这似乎是正确的!非常感谢您的帮助! 很高兴它成功了。我将更新我的帖子以反映这一调整。 自相关和 FFT 直接相关,FFT 可以用来计算前者,实际上可能会获得更快的结果,因为硬件有助于 FFT:***.com/questions/3949324/…【参考方案2】:

我觉得应该是

 (indexMax-1) * Fs / L 

abs(fft(x)) 的第一个元素是直流电 (DC),或偏置,或信号的平均值,或 X0。我们从第二个元素 (X1) 开始计数。 如果我错了,请告诉我。谢谢。

clear all
clc
close all
Fs = 1;
T = 11 % Note this T is deliberately chosen , so that we have about 1.7 cycle of cosine singal
t = 0:Fs:T; % T seconds
L = length(t); % L is the length of sample sequence
bias = 4
signal = sin(t) + bias;

[maxValue,indexMax] = max(abs(fft(signal-mean(signal))));

frequency_method1 = (indexMax-1) * Fs / (L-1);
frequency_method2 = (indexMax-1) * Fs / L;


number_of_cycles_method1 = frequency_method1*T

number_of_cycles_method2 = frequency_method2*T


subplot(2,1,1)
plot(t,signal,'-or') ; grid on;
legend('about 1.7 cycles of cosine signal')
subplot(2,1,2)
plot(abs(fft(signal-mean(signal))),'-xb'); grid on
legend('abs of fft')

number_of_cycles_method1 =

     2


number_of_cycles_method2 =

    1.8333

【讨论】:

以上是关于在 MATLAB 中根据信号数据确定频率的主要内容,如果未能解决你的问题,请参考以下文章

MATLAB中的FFT的采样频率和采样点怎样确定

数字信号去噪基于matlab粒子滤波器与FBSMAP平滑方法数字信号去噪含Matlab源码 2179期

在matlab中提取具有多个频率分量的信号

matlab设计复合信号不同频率的初相位

在matlab中提取具有多个频率分量的信号

matlab的音乐信号的分析与处理设计的实验咋做?