[파이썬] scipy FIR 및 IIR 필터 설계

Filters are essential tools in signal processing. They are used to eliminate unwanted noise, extract specific frequency components, and enhance the signal quality. In this blog post, we will explore how to design Finite Impulse Response (FIR) and Infinite Impulse Response (IIR) filters using the scipy library in Python.

FIR Filters

FIR filters have a finite impulse response, which means their impulse response decays to zero over time. They are known for their linear phase response and stability. scipy provides various functions to design FIR filters, such as firwin, remez, and kaiser.

Designing a Lowpass FIR Filter

To design a lowpass FIR filter using the firwin function, we need to specify the cutoff frequency and the filter length.

import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import firwin, freqz

# Parameters
cutoff_freq = 0.2
filter_length = 51

# Design FIR filter
fir_coeff = firwin(filter_length, cutoff_freq)

# Frequency response
w, h = freqz(fir_coeff)

# Plot frequency response
fig, ax = plt.subplots()
ax.plot(w, np.abs(h))
ax.set_title("FIR Filter Frequency Response")
ax.set_xlabel("Frequency")
ax.set_ylabel("Magnitude")
plt.show()

In the above code, we import the required modules (numpy, matplotlib, and firwin from scipy.signal). We set the cutoff frequency to 0.2 and the filter length to 51. Then, we design the FIR filter using the firwin function and compute its frequency response using freqz. Finally, we plot the frequency response using matplotlib.

Designing a Highpass FIR Filter

Similarly, we can design a highpass FIR filter by simply changing the type of filter and adjusting the cutoff frequency. Here’s an example:

import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import firwin, freqz

# Parameters
cutoff_freq = 0.5
filter_length = 101

# Design FIR filter
fir_coeff = firwin(filter_length, cutoff_freq, pass_zero=False)

# Frequency response
w, h = freqz(fir_coeff)

# Plot frequency response
fig, ax = plt.subplots()
ax.plot(w, np.abs(h))
ax.set_title("FIR Filter Frequency Response")
ax.set_xlabel("Frequency")
ax.set_ylabel("Magnitude")
plt.show()

Designing a Bandpass FIR Filter

To design a bandpass FIR filter, we need to specify the lower and upper cutoff frequencies. Here’s an example:

import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import firwin, freqz

# Parameters
cutoff_freq_low = 0.2
cutoff_freq_high = 0.8
filter_length = 101

# Design FIR filter
fir_coeff = firwin(filter_length, [cutoff_freq_low, cutoff_freq_high], pass_zero=False)

# Frequency response
w, h = freqz(fir_coeff)

# Plot frequency response
fig, ax = plt.subplots()
ax.plot(w, np.abs(h))
ax.set_title("FIR Filter Frequency Response")
ax.set_xlabel("Frequency")
ax.set_ylabel("Magnitude")
plt.show()

IIR Filters

IIR filters have an infinite impulse response, meaning their impulse response does not decay to zero over time. They can achieve a steeper roll-off compared to FIR filters but may introduce phase distortion. scipy provides functions such as butter, cheby1, and ellip to design IIR filters.

Designing a Lowpass IIR Filter

To design a lowpass IIR filter using the butter function, we need to specify the filter order and cutoff frequency.

import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import butter, freqz

# Parameters
order = 4
cutoff_freq = 0.2

# Design IIR filter
b, a = butter(order, cutoff_freq, btype='low', analog=False, output='ba')

# Frequency response
w, h = freqz(b, a)

# Plot frequency response
fig, ax = plt.subplots()
ax.plot(w, np.abs(h))
ax.set_title("IIR Filter Frequency Response")
ax.set_xlabel("Frequency")
ax.set_ylabel("Magnitude")
plt.show()

In the above code, we import the required modules (numpy, matplotlib, and butter from scipy.signal). We set the filter order to 4 and the cutoff frequency to 0.2. Then, we design the IIR filter using the butter function and compute its frequency response using freqz. Finally, we plot the frequency response using matplotlib.

Designing a Highpass IIR Filter

Similarly, we can design a highpass IIR filter by changing the type of filter and adjusting the cutoff frequency. Here’s an example:

import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import butter, freqz

# Parameters
order = 4
cutoff_freq = 0.5

# Design IIR filter
b, a = butter(order, cutoff_freq, btype='high', analog=False, output='ba')

# Frequency response
w, h = freqz(b, a)

# Plot frequency response
fig, ax = plt.subplots()
ax.plot(w, np.abs(h))
ax.set_title("IIR Filter Frequency Response")
ax.set_xlabel("Frequency")
ax.set_ylabel("Magnitude")
plt.show()

Designing a Bandpass IIR Filter

To design a bandpass IIR filter, we need to specify the lower and upper cutoff frequencies. Here’s an example:

import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import butter, freqz

# Parameters
order = 4
cutoff_freq_low = 0.2
cutoff_freq_high = 0.8

# Design IIR filter
b, a = butter(order, [cutoff_freq_low, cutoff_freq_high], btype='band', analog=False, output='ba')

# Frequency response
w, h = freqz(b, a)

# Plot frequency response
fig, ax = plt.subplots()
ax.plot(w, np.abs(h))
ax.set_title("IIR Filter Frequency Response")
ax.set_xlabel("Frequency")
ax.set_ylabel("Magnitude")
plt.show()

In this blog post, we explored how to design FIR and IIR filters using the scipy library in Python. We covered the design of lowpass, highpass, and bandpass filters for both FIR and IIR filters. I hope you found this tutorial useful for your signal processing tasks!