www.gusucode.com > signal 案例源码程序 matlab代码 > signal/FilteringDataWithSignalProcessingToolboxSoftwareExample.m
%% Filtering Data With Signal Processing Toolbox Software %% Lowpass FIR Filter – Window Method % This example shows how to design and implement an FIR filter using two % command line functions, |fir1| and |designfilt|, and the interactive % *Filter Designer* app. %% % Create a signal to use in the examples. The signal is a 100 Hz sine wave % in additive $N(0,1/4)$ white Gaussian noise. Set the random number % generator to the default state for reproducible results. rng default Fs = 1000; t = linspace(0,1,Fs); x = cos(2*pi*100*t)+0.5*randn(size(t)); %% % The filter design is an FIR lowpass filter with order equal to 20 and a % cutoff frequency of 150 Hz. Use a Kaiser window with length one sample % greater than the filter order and $\beta = 3$. See |kaiser| for details % on the Kaiser window. % % Use |fir1| to design the filter. |fir1| requires normalized frequencies % in the interval [0,1], where 1 corresponds to $\pi$ rad/sample. To use % |fir1|, you must convert all frequency specifications to normalized % frequencies. % % Design the filter and view the filter's magnitude response. fc = 150; Wn = (2/Fs)*fc; b = fir1(20,Wn,'low',kaiser(21,3)); fvtool(b,1,'Fs',Fs) %% % Apply the filter to the signal and plot the result for the first ten % periods of the 100 Hz sinusoid. y = filter(b,1,x); plot(t,x,t,y) xlim([0 0.1]) xlabel('Time (s)') ylabel('Amplitude') legend('Original Signal','Filtered Data') %% % Design the same filter using |designfilt|. Set the filter response to % |'lowpassfir'| and input the specifications as |Name,Value| pairs. With % |designfilt|, you can specify your filter design in Hz. Fs = 1000; Hd = designfilt('lowpassfir','FilterOrder',20,'CutoffFrequency',150, ... 'DesignMethod','window','Window',{@kaiser,3},'SampleRate',Fs); %% % Filter the data and plot the result. y1 = filter(Hd,x); plot(t,x,t,y1) xlim([0 0.1]) xlabel('Time (s)') ylabel('Amplitude') legend('Original Signal','Filtered Data') %% Lowpass FIR Filter with Filter Designer % This example shows how to design and implement a lowpass FIR filter using % the window method with the interactive *Filter Designer* app. %% % * Start the app by entering |filterDesigner| at the command line. % * Set the *Response Type* to *Lowpass*. % * Set the *Design Method* to *FIR* and select the *Window* method. % * Under *Filter Order*, select *Specify order*. Set the order to 20. % * Under *Frequency Specifications*, set *Units* to *Hz*, *Fs* to 1000, % and *Fc* to 150. %% % <<../windowmethodfilterdesigner.png>> %% % * Click *Design Filter*. % * Select *File* > *Export...* to export your FIR filter to the % MATLAB(R) workspace as coefficients or a filter object. In this example, % export the filter as an object. Specify the variable name as |Hd|. %% % <<../windowobjectexport_hg2.png>> %% % * Click *Export*. % * Filter the input signal in the command window with the exported filter % object. Plot the result for the first ten periods of the 100 Hz sinusoid. y2 = filter(Hd,x); plot(t,x,t,y2) xlim([0 0.1]) xlabel('Time (s)') ylabel('Amplitude') legend('Original Signal','Filtered Data') %% % * Select *File* > *Generate MATLAB Code* to generate a MATLAB function to % create a filter object using your specifications. % % You can also use the interactive tool |filterBuilder| to design your % filter. %% Bandpass Filters – Minimum-Order FIR and IIR Systems % This example shows how to design a bandpass filter and filter data with % minimum-order FIR equiripple and IIR Butterworth filters. You can model % many real-world signals as a superposition of oscillating components, a % low-frequency trend, and additive noise. For example, economic data often % contain oscillations, which represent cycles superimposed on a slowly % varying upward or downward trend. In addition, there is an additive noise % component, which is a combination of measurement error and the inherent % random fluctuations in the process. %% % In these examples, assume you sample some process every day for one year. % Assume the process has oscillations on approximately one-week and % one-month scales. In addition, there is a low-frequency upward trend in % the data and additive $N(0,1/4)$ white Gaussian noise. % % Create the signal as a superposition of two sine waves with frequencies % of 1/7 and 1/30 cycles/day. Add a low-frequency increasing trend term and % $N(0,1/4)$ white Gaussian noise. Reset the random number generator for % reproducible results. The data is sampled at 1 sample/day. Plot the % resulting signal and the power spectral density (PSD) estimate. rng default Fs = 1; n = 1:365; x = cos(2*pi*(1/7)*n)+cos(2*pi*(1/30)*n-pi/4); trend = 3*sin(2*pi*(1/1480)*n); y = x+trend+0.5*randn(size(n)); [pxx,f] = periodogram(y,[],[],Fs); subplot(2,1,1) plot(n,y) xlim([1 365]) xlabel('Days') grid subplot(2,1,2) plot(f,10*log10(pxx)) xlabel('Cycles/day') ylabel('dB') grid %% % The low-frequency trend appears in the power spectral density estimate as % increased low-frequency power. The low-frequency power appears % approximately 10 dB above the oscillation at 1/30 cycles/day. Use this % information in the specifications for the filter stopbands. % % Design minimum-order FIR equiripple and IIR Butterworth filters with the % following specifications: passband from [1/40,1/4] cycles/day and % stopbands from [0,1/60] and [1/4,1/2] cycles/day. Set both stopband % attenuations to 10 dB and the passband ripple tolerance to 1 dB. Hd1 = designfilt('bandpassfir', ... 'StopbandFrequency1',1/60,'PassbandFrequency1',1/40, ... 'PassbandFrequency2',1/4 ,'StopbandFrequency2',1/2 , ... 'StopbandAttenuation1',10,'PassbandRipple',1, ... 'StopbandAttenuation2',10,'DesignMethod','equiripple','SampleRate',Fs); Hd2 = designfilt('bandpassiir', ... 'StopbandFrequency1',1/60,'PassbandFrequency1',1/40, ... 'PassbandFrequency2',1/4 ,'StopbandFrequency2',1/2 , ... 'StopbandAttenuation1',10,'PassbandRipple',1, ... 'StopbandAttenuation2',10,'DesignMethod','butter','SampleRate',Fs); %% % Compare the order of the FIR and IIR filters and the unwrapped phase % responses. fprintf('The order of the FIR filter is %d\n',filtord(Hd1)) fprintf('The order of the IIR filter is %d\n',filtord(Hd2)) [phifir,w] = phasez(Hd1,[],1); [phiiir,w] = phasez(Hd2,[],1); figure plot(w,unwrap(phifir)) hold on plot(w,unwrap(phiiir)) hold off xlabel('Cycles/Day') ylabel('Radians') legend('FIR Equiripple Filter','IIR Butterworth Filter') grid %% % The IIR filter has a much lower order that the FIR filter. However, the % FIR filter has a linear phase response over the passband, while the IIR % filter does not. The FIR filter delays all frequencies in the filter % passband equally, while the IIR filter does not. % % Additionally, the rate of change of the phase per unit of frequency is % greater in the FIR filter than in the IIR filter. % % Design a lowpass FIR equiripple filter for comparison. The lowpass filter % specifications are: passband [0,1/4] cycles/day, stopband attenuation % equal to 10 dB, and the passband ripple tolerance set to 1 dB. Hdlow = designfilt('lowpassfir', ... 'PassbandFrequency',1/4,'StopbandFrequency',1/2, ... 'PassbandRipple',1,'StopbandAttenuation',10, ... 'DesignMethod','equiripple','SampleRate',1); %% % Filter the data with the bandpass and lowpass filters. yfir = filter(Hd1,y); yiir = filter(Hd2,y); ylow = filter(Hdlow,y); %% % Plot the PSD estimate of the bandpass IIR filter output. You can replace % |yiir| with |yfir| in the following code to view the PSD estimate of the % FIR bandpass filter output. [pxx,f] = periodogram(yiir,[],[],Fs); plot(f,10*log10(pxx)) xlabel('Cycles/day') ylabel('dB') grid %% % The PSD estimate shows the bandpass filter attenuates the low-frequency % trend and high-frequency noise. % % Plot the first 120 days of FIR and IIR filter output. plot(n,yfir,n,yiir) axis([1 120 -2.8 2.8]) xlabel('Days') legend('FIR bandpass filter output','IIR bandpass filter output', ... 'Location','SouthEast') %% % The increased phase delay in the FIR filter is evident in the filter % output. % % Plot the lowpass FIR filter output superimposed on the superposition of % the 7-day and 30-day cycles for comparison. plot(n,x,n,ylow) xlim([1 365]) xlabel('Days') legend('7-day and 30-day cycles','FIR lowpass filter output', ... 'Location','NorthWest') %% % You can see in the preceding plot that the low-frequency trend is evident % in the lowpass filter output. While the lowpass filter preserves the % 7-day and 30-day cycles, the bandpass filters perform better in this % example because the bandpass filters also remove the low-frequency trend. %% Zero-Phase Filtering % This example shows how to perform zero-phase filtering. %% % Repeat the signal generation and lowpass filter design with |fir1| and % |designfilt|. You do not have to execute the following code if you already % have these variables in your workspace. rng default Fs = 1000; t = linspace(0,1,Fs); x = cos(2*pi*100*t)+0.5*randn(size(t)); % Using fir1 fc = 150; Wn = (2/Fs)*fc; b = fir1(20,Wn,'low',kaiser(21,3)); % Using designfilt Hd = designfilt('lowpassfir','FilterOrder',20,'CutoffFrequency',150, ... 'DesignMethod','window','Window',{@kaiser,3},'SampleRate',Fs); %% % Filter the data using |filter|. Plot the first 100 points of the filter % output along with a superimposed sinusoid with the same amplitude and % initial phase as the input signal. yout = filter(Hd,x); xin = cos(2*pi*100*t); plot(t,xin,t,yout) xlim([0 0.1]) xlabel('Time (s)') ylabel('Amplitude') legend('Input Sine Wave','Filtered Data') grid %% % Looking at the initial 0.01 seconds of the filtered data, you see that % the output is delayed with respect to the input. The delay appears to be % approximately 0.01 seconds, which is almost 1/2 the length of the FIR % filter in samples $(10\times0.001)$. % % This delay is due to the filter's phase response. The FIR filter in these % examples is a type I linear-phase filter. The group delay of the filter % is 10 samples. % % Plot the group delay using |fvtool|. fvtool(Hd,'Analysis','grpdelay') %% % In many applications, phase distortion is acceptable. This is % particularly true when phase response is linear. In other applications, % it is desirable to have a filter with a zero-phase response. A zero-phase % response is not technically possibly in a noncausal filter. However, you % can implement zero-phase filtering using a causal filter with |filtfilt|. % % Filter the input signal using |filtfilt|. Plot the responses to compare % the filter outputs obtained with |filter| and |filtfilt|. yzp = filtfilt(Hd,x); plot(t,xin,t,yout,t,yzp) xlim([0 0.1]) xlabel('Time (s)') ylabel('Amplitude') legend('100-Hz Sine Wave','Filtered Signal','Zero-phase Filtering',... 'Location','NorthEast') %% % In the preceding figure, you can see that the output of |filtfilt| does % not exhibit the delay due to the phase response of the FIR filter.