给定一个正弦信号,我们如何有效地确定它的频率?
估计白噪声中单个正弦信号频率的简单有效方法
我假设模型是:
其中是与信号本身不相关的白噪声。
这里明显的方法是使用 DFT 作为这种情况的最大似然估计量。它可能能够在低 SNR 下产生最佳结果。
在高信噪比中,我将使用Steven Kay - A Fast and Accurate Single Frequency Estimator ( Alternative Source ) 中的方法。
那里给出了2种方法。
最简单的一个(论文中的方程式 17)基本上是:
estFreq = 0;
for ii = 1:(numSamples - 1)
estFreq = estFreq + angle(vX(ii)' * vX(ii + 1));
end
estFreq = estFreq / (2 * pi * (numSamples - 1));
estFreq = samplingFreq * estFreq; %<! Moving from normalized frequency to absolute frequency
直觉很简单,基本上是估计瞬时相位的斜率。
从论文中可以看出,它们在许多实际案例中取得了非常好的效果:
深入分析
上面的算法(论文中的公式 17)基本上变成了实信号的过零计数。它集成了许多交叉口(假设有很多交叉口),因此比一个更好。问题是假设相位已知并且为 0。
这是一个与估计正弦信号频率的 CRLB 相比的性能示例,无需了解其幅度(即使已知也不会产生影响)或相位:
Kay 估计器类型 1是来自方程式的估计器。17. Kay 估计量类型 2是等式。16(更好的称量)。
正如预期的那样,当相位未知时,性能与 CRLB 不匹配。但是现实世界的表现非常好(SNR 的标准偏差~0.03 [Hz]
,5 [dB]
因为它是归一化的频率,所以可以达到约 3%)。
以上是针对 3 个不同的相对频率完成的,是的,对于每个实现的随机相位。
我们需要特定的频率,因此在 2000 年实现时曲线将足够平滑(对于随机频率,我们可能需要在 2 个数量级的范围内实现更多的东西)。
我们能做得更好吗?
是的!
如果我们有一个真实的信号(正弦/余弦),只需要应用希尔伯特变换(实际上就像在 MATLAB 中那样构建解析信号hilbert()
)。
然后,我们得到:
嗯,就是这样。我们有一些与 CRLB 匹配的 SNR9 [dB]
及以上的东西,甚至在它以下也能很好地工作。
总之:
- 如果您希望通过非常简单的算法获得良好的结果(但不是最好的),请采用上面的算法并将其直接应用于真实数据。它很简单,而且工作得很好。它假设您的数据周期很少。
~9 [dB]
如果您希望在调用算法之前应用希尔伯特变换的 SNR 得到类似 CRLB 的结果(尽可能好) 。它会增加复杂性,但结果将与没有 DFT 分析的结果一样好。
备注:请注意,这两种算法都不适用于其他模型。即不止一个音调或类似的东西。
一种常见的方法是对输入信号进行 FFT。由于频率在 FFT bin 处可能不正确,因此通常在选择初始峰值后进行第二步插值。通常这样做的几个原因是,它是 AWGN 案例的最大似然解决方案,无论您在什么平台上实现,都可能有一个优化的 FFT 代码供您使用。在效率方面,你会看到操作,其中繁重的计算步骤是采用 FFT。
如果您有一个低噪声且采样良好的信号,一种快速估计它的方法是找到。对于信号,二阶导数是,它是乘以原始值。如果您想要快速响应并且只有循环的一部分,那么这很有用,因此没有过零。但显然,这取决于能否在数值上获得准确的二阶导数。
这取决于所需的精度。
如果它是无噪声的纯正弦波,您可以通过测量两个零交叉点之间的差异来快速估算。
棘手的部分是大多数正弦波频率不是采样率的整数分频器,因此实际的过零落在两个样本之间,并且这种方法存在一些固有的测量误差。
处理这个问题的最简单方法就是随着时间的推移不断测量和平均结果。
一种更有效、更快捷的方法是通过线性插值估计过零的确切位置。这很有效,因为正弦波可以近似为围绕它的零交叉的一条线,即。这将在单次测量中为您提供非常好的估计,但前提是噪声非常少或没有。
如果事情变得嘈杂,如果有谐波,或者如果有漂移,更好的选择是使用相位或延迟锁定环来跟踪频率。
另一件需要注意的是,您只能测量与采样时钟相关的频率。大多数现实世界的采样时钟也在漂移(尽管只是很小的量)。
如果你想超级快,你可以使用关系
您可以仅使用三个连续的正弦波样本来求解
然而,这种方法在数值上是“脆弱的”,即使是极少量的噪音也会导致大的错误