A low-pass FIR filter lets low frequencies pass and blocks high frequencies. It helps clean signals by removing noise or unwanted fast changes.
Low-pass FIR filter design in Signal Processing
from scipy.signal import firwin # firwin(numtaps, cutoff, window='hamming', pass_zero=True) # numtaps: number of filter taps (length) # cutoff: cutoff frequency (0 to 1, where 1 is Nyquist frequency) # window: type of window to shape filter # pass_zero=True means low-pass filter
The cutoff frequency is given as a fraction of the Nyquist frequency (half the sampling rate).
The number of taps controls filter sharpness and length; more taps mean better filtering but more delay.
from scipy.signal import firwin # Create a low-pass FIR filter with 31 taps and cutoff at 0.3 (30% of Nyquist) filter_coefs = firwin(31, 0.3)
filter_coefs = firwin(51, 0.2, window='blackman')
filter_coefs = firwin(21, 0.4, pass_zero=True)
This program creates a low-pass FIR filter with a cutoff at 100 Hz for a 1000 Hz sampling rate. It filters a signal made of a slow 5 Hz wave and a fast 300 Hz wave. The plots show the original signal, the filtered signal (where the 300 Hz part is removed), and the filter's frequency response.
import numpy as np import matplotlib.pyplot as plt from scipy.signal import firwin, lfilter, freqz # Sampling frequency fs = 1000 # 1000 Hz # Design low-pass FIR filter numtaps = 51 cutoff = 100 # 100 Hz cutoff frequency # Normalize cutoff frequency to Nyquist frequency (fs/2) normalized_cutoff = cutoff / (fs / 2) # Get filter coefficients fir_coeff = firwin(numtaps, normalized_cutoff) # Create a sample signal: 5 Hz + 300 Hz sine waves t = np.linspace(0, 1.0, fs, endpoint=False) signal = np.sin(2 * np.pi * 5 * t) + 0.5 * np.sin(2 * np.pi * 300 * t) # Apply the filter to the signal filtered_signal = lfilter(fir_coeff, 1.0, signal) # Frequency response of the filter w, h = freqz(fir_coeff, worN=8000) # Plot results plt.figure(figsize=(12, 8)) plt.subplot(3, 1, 1) plt.plot(t, signal) plt.title('Original Signal (5 Hz + 300 Hz)') plt.xlabel('Time [seconds]') plt.ylabel('Amplitude') plt.subplot(3, 1, 2) plt.plot(t, filtered_signal) plt.title('Filtered Signal (Low-pass FIR)') plt.xlabel('Time [seconds]') plt.ylabel('Amplitude') plt.subplot(3, 1, 3) plt.plot(w * fs / (2 * np.pi), 20 * np.log10(abs(h))) plt.title('Frequency Response of the Filter') plt.xlabel('Frequency [Hz]') plt.ylabel('Gain [dB]') plt.ylim(-100, 10) plt.grid(True) plt.tight_layout() plt.show()
More taps mean better filtering but slower processing and more delay.
Choosing the right window affects the filter's sharpness and ripple.
Always normalize cutoff frequency by Nyquist frequency (half the sampling rate).
Low-pass FIR filters keep slow changes and remove fast changes in signals.
Use firwin to design filters by specifying taps and cutoff frequency.
Test filters by applying them to signals and checking frequency response.