I\'m trying to get a bandpass filter with a 128-point Hamming window with cutoff frequencies 0.7-4Hz in python. I get my samples for my signal from images. (1 sample = 1 ima
You can use the functions scipy.signal.firwin or scipy.signal.firwin2 to create a bandpass FIR filter. You can also design a FIR filter using scipy.signal.remez
The following code provides some convenience wrappers for creating a bandpass FIR filter. It uses these to create bandpass filters corresponding to the numbers requested in the question. This assumes that the sampling is done uniformly. If the sampling is not uniform, a FIR filter is not appropriate.
from scipy.signal import firwin, remez, kaiser_atten, kaiser_beta
# Several flavors of bandpass FIR filters.
def bandpass_firwin(ntaps, lowcut, highcut, fs, window='hamming'):
nyq = 0.5 * fs
taps = firwin(ntaps, [lowcut, highcut], nyq=nyq, pass_zero=False,
window=window, scale=False)
return taps
def bandpass_kaiser(ntaps, lowcut, highcut, fs, width):
nyq = 0.5 * fs
atten = kaiser_atten(ntaps, width / nyq)
beta = kaiser_beta(atten)
taps = firwin(ntaps, [lowcut, highcut], nyq=nyq, pass_zero=False,
window=('kaiser', beta), scale=False)
return taps
def bandpass_remez(ntaps, lowcut, highcut, fs, width):
delta = 0.5 * width
edges = [0, lowcut - delta, lowcut + delta,
highcut - delta, highcut + delta, 0.5*fs]
taps = remez(ntaps, edges, [0, 1, 0], Hz=fs)
return taps
if __name__ == "__main__":
import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import freqz
# Sample rate and desired cutoff frequencies (in Hz).
fs = 63.0
lowcut = 0.7
highcut = 4.0
ntaps = 128
taps_hamming = bandpass_firwin(ntaps, lowcut, highcut, fs=fs)
taps_kaiser16 = bandpass_kaiser(ntaps, lowcut, highcut, fs=fs, width=1.6)
taps_kaiser10 = bandpass_kaiser(ntaps, lowcut, highcut, fs=fs, width=1.0)
remez_width = 1.0
taps_remez = bandpass_remez(ntaps, lowcut, highcut, fs=fs,
width=remez_width)
# Plot the frequency responses of the filters.
plt.figure(1, figsize=(12, 9))
plt.clf()
# First plot the desired ideal response as a green(ish) rectangle.
rect = plt.Rectangle((lowcut, 0), highcut - lowcut, 1.0,
facecolor="#60ff60", alpha=0.2)
plt.gca().add_patch(rect)
# Plot the frequency response of each filter.
w, h = freqz(taps_hamming, 1, worN=2000)
plt.plot((fs * 0.5 / np.pi) * w, abs(h), label="Hamming window")
w, h = freqz(taps_kaiser16, 1, worN=2000)
plt.plot((fs * 0.5 / np.pi) * w, abs(h), label="Kaiser window, width=1.6")
w, h = freqz(taps_kaiser10, 1, worN=2000)
plt.plot((fs * 0.5 / np.pi) * w, abs(h), label="Kaiser window, width=1.0")
w, h = freqz(taps_remez, 1, worN=2000)
plt.plot((fs * 0.5 / np.pi) * w, abs(h),
label="Remez algorithm, width=%.1f" % remez_width)
plt.xlim(0, 8.0)
plt.ylim(0, 1.1)
plt.grid(True)
plt.legend()
plt.xlabel('Frequency (Hz)')
plt.ylabel('Gain')
plt.title('Frequency response of several FIR filters, %d taps' % ntaps)
plt.show()
Here's the plot generated by the script. Of course, it is much more useful to run the script locally, so you can zoom in on the details.