Skip to content
Related Articles

Related Articles

Design an IIR Notch Filter to Denoise Signal using Python
  • Last Updated : 13 Jan, 2021
GeeksforGeeks - Summer Carnival Banner

IIR stands for Infinite Impulse Response, It is one of the striking features of many linear-time invariant systems that are distinguished by having an impulse response h(t)/h(n) which does not become zero after some point but instead continues infinitely.

What is IIR Notch Filter?

A Notch Filter is a bandstop filter with a very narrow stopband and two passbands, it actually highly attenuates/eliminates a particular frequency component from the input signal while leaving the amplitude of the other frequencies more or less unchanged.

The specifications are as follows:  

  • Generate a signal of 15 Hz corrupted with 50 Hz power line frequency.
  • Sampling frequency: 1 kHz

Approach:

Step 1: Importing all the necessary libraries.



Python3




from scipy import signal
import matplotlib.pyplot as plt
import numpy as np

Step 2: Defining the specifications of the IIR Bandpass Notch-Filter

Python3




# Create/view notch filter
samp_freq = 1000  # Sample frequency (Hz)
notch_freq = 50.0  # Frequency to be removed from signal (Hz)
quality_factor = 20.0  # Quality factor

Step 3:

Python3




# Design a notch filter using signal.iirnotch
b_notch, a_notch = signal.iirnotch(notch_freq, quality_factor, samp_freq)
  
# Compute magnitude response of the designed filter
freq, h = signal.freqz(b_notch, a_notch, fs=samp_freq)

Step 4:

Python3




fig = plt.figure(figsize=(8, 6))
  
# Plot magnitude response of the filter
plt.plot(freq*samp_freq/(2*np.pi), 20 * np.log10(abs(h)),
         'r', label='Bandpass filter', linewidth='2')
  
plt.xlabel('Frequency [Hz]', fontsize=20)
plt.ylabel('Magnitude [dB]', fontsize=20)
plt.title('Notch Filter', fontsize=20)
plt.grid()

Output:



Step 5:

Python3




# Create and view signal that is a mixture 
# of two different frequencies
f1 = 15  # Frequency of 1st signal in Hz
f2 = 50  # Frequency of 2nd signal in Hz
  
# Set time vector
# Generate 1000 sample sequence in 1 sec
n = np.linspace(0, 1, 1000)

Step 6:

Python3




# Generate the signal containing f1 and f2
noisySignal = np.sin(2*np.pi*15*n) + np.sin(2*np.pi*50*n) + \
    np.random.normal(0, .1, 1000)*0.03

Step 7:

Python3




# Plotting
fig = plt.figure(figsize=(8, 6))
plt.subplot(211)
plt.plot(n, noisySignal, color='r', linewidth=2)
plt.xlabel('Time', fontsize=20)
plt.ylabel('Magnitude', fontsize=18)
plt.title('Noisy Signal', fontsize=20)

Output:

Step 8:

Python3




# Apply notch filter to the noisy signal using signal.filtfilt
outputSignal = signal.filtfilt(b_notch, a_notch, noisySignal)

Step 9:

Python3




# Plot notch-filtered version of signal
plt.subplot(212)
  
# Plot output signal of notch filter
plt.plot(n, outputSignal)
plt.xlabel('Time', fontsize=20)
plt.ylabel('Magnitude', fontsize=18)
plt.title('Filtered Signal', fontsize=20)
plt.subplots_adjust(hspace=0.5)
fig.tight_layout()
plt.show()

Output:

Below is the implementation:

Python3




from scipy import signal
import matplotlib.pyplot as plt
import numpy as np
  
# Create/view notch filter
samp_freq = 1000  # Sample frequency (Hz)
notch_freq = 50.0  # Frequency to be removed from signal (Hz)
quality_factor = 20.0  # Quality factor
  
# Design a notch filter using signal.iirnotch
b_notch, a_notch = signal.iirnotch(notch_freq, quality_factor, samp_freq)
  
# Compute magnitude response of the designed filter
freq, h = signal.freqz(b_notch, a_notch, fs=samp_freq)
  
fig = plt.figure(figsize=(8, 6))
  
# Plot magnitude response of the filter
plt.plot(freq*samp_freq/(2*np.pi), 20 * np.log10(abs(h)),
         'r', label='Bandpass filter', linewidth='2')
plt.xlabel('Frequency [Hz]', fontsize=20)
plt.ylabel('Magnitude [dB]', fontsize=20)
plt.title('Notch Filter', fontsize=20)
plt.grid()
  
# Create and view signal that is a mixture of two different frequencies
f1 = 15  # Frequency of 1st signal in Hz
f2 = 50  # Frequency of 2nd signal in Hz
# Set time vector
n = np.linspace(0, 1, 1000# Generate 1000 sample sequence in 1 sec
  
# Generate the signal containing f1 and f2
noisySignal = np.sin(2*np.pi*15*n) + np.sin(2*np.pi*50*n) + \
    np.random.normal(0, .1, 1000)*0.03
  
# Plotting
fig = plt.figure(figsize=(8, 6))
plt.subplot(211)
plt.plot(n, noisySignal, color='r', linewidth=2)
plt.xlabel('Time', fontsize=20)
plt.ylabel('Magnitude', fontsize=18)
plt.title('Noisy Signal', fontsize=20)
  
# Apply notch filter to the noisy signal using signal.filtfilt
outputSignal = signal.filtfilt(b_notch, a_notch, noisySignal)
  
# Plot notch-filtered version of signal
plt.subplot(212)
  
# Plot output signal of notch filter
plt.plot(n, outputSignal)
plt.xlabel('Time', fontsize=20)
plt.ylabel('Magnitude', fontsize=18)
plt.title('Filtered Signal', fontsize=20)
plt.subplots_adjust(hspace=0.5)
fig.tight_layout()
plt.show()

Output:


Attention geek! Strengthen your foundations with the Python Programming Foundation Course and learn the basics.

To begin with, your interview preparations Enhance your Data Structures concepts with the Python DS Course.

My Personal Notes arrow_drop_up
Recommended Articles
Page :