改变FFT内容

时间:2011-12-16 00:30:59

标签: algorithm matlab fft

假设您有一些音调加上噪音。

t=0:0.01:10;
y=sin(t) + rand(1,length(t));

我试图击倒fft中的音调峰值,这样只需要噪音数据即可获得ifft。我的算法将是一个for循环,循环遍历abs(fft)的每个索引以寻找峰值。如果存在峰值,我会用嘈杂的数据点替换该峰值。

问题是,在fft完成后,为了可视化数据,通常我会使用plot(abs(fft))。但是,要做ifft,还需要虚数据。因此,我不确定我将如何“敲击高峰”或摆脱它以便我可以使用ifft功能。我想我必须使用想象中的数字。

有什么建议吗? :X

感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

你将不得不使用虚数,但我不明白为什么这是一个问题。您仍然可以使用幅度(abs)表示来查找峰值,但是当您“击倒它们”时,您将放置另一个复杂值。由您决定如何确定该值应该是什么 - 您可以将其设置为零,插入本地频率,插入随机数...

编辑:您的评论:

不要让想象中的数字让你感到困惑。反正他们不是真的“虚构”!只是为了表示给定频率的正弦波,您需要两个值:幅度和相位。大小是你习惯看到的,它决定了我们拥有的给定频率的多少。相位确定 shift 相对于某个点(例如t = 0),这也是非常重要的。举一个例子,将FFT用于相同频率的信号(比如正弦和余弦波) - 幅度看起来相同,但相位会有所不同!如果我们没有阶段,IFFT就不知道是给我们一个正弦波还是一个余弦波,或两者之间的东西。

当然,幅度和相位与真实和虚构不同,但有一个简单的公式可以转换它们。无论哪种方式,我们都使用两个数字来表示每个频率。

答案 1 :(得分:1)

您可以在abs(fft(y))信号中查找“峰值”,并通过查看fft本身的方差替换随机复数值,例如

h = fft(y);

peaks = your_peak_finding_algorithm(abs(fft(y)));

real_noise = std(real(h));
imag_noise = std(imag(h));

h(peaks) = real_noise*randn(size(peaks)) + i*imag_noise*randn(size(peaks))

y_new = ifft(h);

然而,我强烈质疑这是否真的是你想要做的。如果这是一个学术练习,那么很好,但如果它适用于任何类型的实际应用,那么我建议做一些研究。有关于降噪以及检测和滤除信号中音调的文献 ton

同样注意 fft中有更多信息,而不仅仅是与您的正弦曲线相关的单个峰值点。见Window function。它取决于信号的采样与其带宽的比较,以及噪声的属性。