假设您有一些音调加上噪音。
t=0:0.01:10;
y=sin(t) + rand(1,length(t));
我试图击倒fft中的音调峰值,这样只需要噪音数据即可获得ifft。我的算法将是一个for循环,循环遍历abs(fft)的每个索引以寻找峰值。如果存在峰值,我会用嘈杂的数据点替换该峰值。
问题是,在fft完成后,为了可视化数据,通常我会使用plot(abs(fft))。但是,要做ifft,还需要虚数据。因此,我不确定我将如何“敲击高峰”或摆脱它以便我可以使用ifft功能。我想我必须使用想象中的数字。
有什么建议吗? :X
感谢您的帮助。
答案 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。它取决于信号的采样与其带宽的比较,以及噪声的属性。