从fft()中删除最高频率的系数

时间:2014-03-30 19:27:24

标签: matlab for-loop fft frequency

我有一个带有心电图噪音的文件,我需要删除fft中最高频率的系数。 然后我可以使用IFFT,并确保该函数只包含实数。结果应该是具有过滤ECG的文件。 到目前为止我的代码:

function [Z] = cutout (X, m)  %X= the noise file, m the frequency
Y = fft(X);

% transforms X via an FFt and save it in Y
[rows cols] =size(Y);%get size of Y

Y=abs(Y);


for i=1:cols
    if Y(i)> m; % if freq Y(i) is higher than m make it 0 
        Y(i)=0;
    end
end
Z=abs(ifft(Y));
%Calculates the ifft of the modified Y and sets all
%complex numbers to real numbers
end

我不明白我哪里出错了,有没有人有想法或建议? 提前谢谢!

2 个答案:

答案 0 :(得分:3)

第一件事是第一件事。通过去除最高频率的系数,您可以对数据应用FIR(有限脉冲响应)低通滤波器。使用更复杂的滤波器比使用最高频率分量的简单归零可以获得更好的结果。有关MATLAB中滤波器选择,设计和应用的大量信息,您可以在线轻松找到。

现在,问你的问题。您提供的代码有几个问题:

  • 你不应该abs(Y)。即使对于实际输入数据,FFT也很复杂。
  • Y的值是频率幅度,而不是频率数字。您要删除幅度最大而不是最高频率的频率。
  • 如果您有真实数据,则应使用Z=ifft(Y,'symmetric')来确保实际结果而不是获取答案的绝对值。这将保留结果中的负数,如果您使用abs,则会变为正数。
  • 由于您Y的大小为[rows, cols],因此Y似乎可能是2D数组。您应该非常小心地使用fft多维数组来确保您按照自己的意思行事。 fft在第一个非单身维度上运作。

您实际需要做的是确定Y的哪些值对应于最高频率并将这些值归零。对于大小为N的向量,频率向量由

给出
k = ifftshift(-floor(N/2):floor(N/2-1));

您可以通过获取您知道预期结果的函数的FFT来验证这一点。例如,[1 1 1 1]的FFT应仅在0频率处非零,[-1 1 -1 1]的FFT在最高频率处应为非零。您可以使用[0,2 * pi]中的特定x值以及各种正弦或余弦函数y=sin(k*x)来测试更多案例

假设X是1d向量,您可以通过

获得结果
N = length(X);
k = ifftshift(-floor(N/2):floor((N-1)/2)); %//compute the frequency vector
Y = fft(X); %//perform fft
Y = Y.*(abs(k)<=m); %// zero out all frequencies larger than 'm'
Z = ifft(Y,'symmetric');

答案 1 :(得分:-1)

FFT很复杂。如果取绝对值,就会丢失信息。

function [Z] = cutout (X, m) 
  % X the noise file, m the frequency 

  % FFT
  Y = fft(X);

  % Transform
  Y(abs(Y)>m) = 0;

  % IFFT
  Z = abs(ifft(Y));

end