Matlab Low Pass filter using fft

前端 未结 1 1551
攒了一身酷
攒了一身酷 2021-01-31 12:50

I implemented a simple low pass filter in matlab using a forward and backward fft. It works in principle, but the minimum and maximum values differ from the original.

         


        
相关标签:
1条回答
  • 2021-01-31 13:08

    Just to remind ourselves of how MATLAB stores frequency content for Y = fft(y,N):

    • Y(1) is the constant offset
    • Y(2:N/2 + 1) is the set of positive frequencies
    • Y(N/2 + 2:end) is the set of negative frequencies... (normally we would plot this left of the vertical axis)

    In order to make a true low pass filter, we must preserve both the low positive frequencies and the low negative frequencies.

    Here's an example of doing this with a multiplicative rectangle filter in the frequency domain, as you've done:

    % make our noisy function
    t = linspace(1,10,1024);
    x = -(t-5).^2  + 2;
    y = awgn(x,0.5); 
    Y = fft(y,1024);
    
    r = 20; % range of frequencies we want to preserve
    
    rectangle = zeros(size(Y));
    rectangle(1:r+1) = 1;               % preserve low +ve frequencies
    y_half = ifft(Y.*rectangle,1024);   % +ve low-pass filtered signal
    rectangle(end-r+1:end) = 1;         % preserve low -ve frequencies
    y_rect = ifft(Y.*rectangle,1024);   % full low-pass filtered signal
    
    hold on;
    plot(t,y,'g--'); plot(t,x,'k','LineWidth',2); plot(t,y_half,'b','LineWidth',2); plot(t,y_rect,'r','LineWidth',2);
    legend('noisy signal','true signal','+ve low-pass','full low-pass','Location','southwest')
    

    enter image description here

    The full low-pass fitler does a better job but you'll notice that the reconstruction is a bit "wavy". This is because multiplication with a rectangle function in the frequency domain is the same as a convolution with a sinc function in the time domain. Convolution with a sinc fucntion replaces every point with a very uneven weighted average of its neighbours, hence the "wave" effect.

    A gaussian filter has nicer low-pass filter properties because the fourier transform of a gaussian is a gaussian. A gaussian decays to zero nicely so it doesn't include far-off neighbours in the weighted average during convolution. Here is an example with a gaussian filter preserving the positive and negative frequencies:

    gauss = zeros(size(Y));
    sigma = 8;                           % just a guess for a range of ~20
    gauss(1:r+1) = exp(-(1:r+1).^ 2 / (2 * sigma ^ 2));  % +ve frequencies
    gauss(end-r+1:end) = fliplr(gauss(2:r+1));           % -ve frequencies
    y_gauss = ifft(Y.*gauss,1024);
    
    hold on;
    plot(t,x,'k','LineWidth',2); plot(t,y_rect,'r','LineWidth',2); plot(t,y_gauss,'c','LineWidth',2);
    legend('true signal','full low-pass','gaussian','Location','southwest')
    

    enter image description here

    As you can see, the reconstruction is much better this way.

    0 讨论(0)
提交回复
热议问题