Monday, October 9, 2023

TKINTER: WAVELET DENOISING

This is the product of BALIGE ACADEMY TEAM: Vivian Siahaan and Rismon Hasiholan Sianipar.

SEMANGAT BELAJAR dan HORAS!!!

BALIGE CITY, NORTH SUMATERA


SUPPORT OUR CHANNEL BY SUBSCRIBING TO IT:


SCALING AND WAVELET FUNCTIONS:



#wavelet_utils.py
import matplotlib.pyplot as plt
import numpy as np 
import pywt
from scipy.fft import fft, fftfreq
from scipy.signal.windows import blackman

class Wavelet_Utils:
    def __init__(self):
        pass

    def create_orthogonal_scaling_wavelet_functions(self, wave_type, level):
        obj_wavelet = pywt.Wavelet(wave_type)
        (phi, psi, x) = obj_wavelet.wavefun(level=level)
        return phi, psi, x
    
    def fft_wavelet(self, x, y):
        N = len(x)
        w = blackman(len(x))
        yf = fft(y*w)
        xf = fftfreq(N, 1)
        return N, xf, yf
        
    def plot_orthogonal_wavelet_functions(self, wave_type, level, figure, canvas):
        figure.clear() 
        
        #Creates orthogonal scaling and wavelet functions
        phi, psi, x = self.create_orthogonal_scaling_wavelet_functions(wave_type, level)
        ax1 = figure.add_subplot(2,2,1)
        ax1.plot(x, phi, linewidth=3.0, color='red')
        ax1.set_ylabel('Amplitude', color='blue')
        ax1.set_xlabel('x', color='blue')
        ax1.set_title("$\phi$ (Scaling Function)" + " of " + wave_type)
        ax1.set_facecolor('#F0F0F0')
        ax1.grid(True)   

        ax2 = figure.add_subplot(2,2,2)
        N, xf_phi, yf_phi = self.fft_wavelet(x, phi)
        ax2.semilogy(xf_phi[1:N//2], 2.0/N * np.abs(yf_phi[1:N//2]), linewidth=2.0, color='red')
        ax2.set_ylabel('Decible', color='blue')
        ax2.set_xlabel('$\omega$', color='blue')
        ax2.set_title("FFT of ($\phi$)" + " of " + wave_type)
        ax2.set_facecolor('#F0F0F0')
        ax2.grid(True) 
        
        ax3 = figure.add_subplot(2,2,3)
        ax3.plot(x, psi, linewidth=3.0, color='blue')
        ax3.set_ylabel('Amplitude', color='blue')
        ax3.set_xlabel('x', color='blue')
        ax3.set_title("$\psi$ (Wavelet Function)"+ " of " + wave_type)
        ax3.set_facecolor('#F0F0F0')
        ax3.grid(True)           

        ax4 = figure.add_subplot(2,2,4)
        N, xf_psi, yf_psi = self.fft_wavelet(x, psi)
        ax4.semilogy(xf_psi[1:N//2], 2.0/N * np.abs(yf_psi[1:N//2]), linewidth=2.0, color='blue')
        ax4.set_ylabel('Decible', color='blue')
        ax4.set_xlabel('$\omega$', color='blue')
        ax4.set_title("FFT of ($\psi$)" + " of " + wave_type)
        ax4.set_facecolor('#F0F0F0')
        ax4.grid(True)
        
        figure.tight_layout()
        canvas.draw()     
    
#form_wavelet.py
import tkinter as tk
from tkinter import ttk
from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from wavelet_utils import Wavelet_Utils

class Form_Wavelet:
    def __init__(self, window):
        self.window = window
        width = 1520
        height = 760
        self.window.geometry(f"{width}x{height}")
        self.wavelet_utils = Wavelet_Utils()
    
        #Adds widgets
        self.add_canvas(self.window)
        self.add_labels(self.window)
        self.add_comboboxes(self.window)
        self.add_entries(self.window)
        
        #Binds events
        self.binds_event()
        
    def add_labels(self, master):
        # Create labels
        self.label1 = tk.Label(master, text="CHOOSE LEVEL")
        self.label1.grid(row=0, column=0, padx=5, pady=0.1, sticky="w")
        
        self.label2 = tk.Label(master, text="CHOOSE WAVELET")
        self.label2.grid(row=2, column=0, padx=5, pady=0.1, sticky="w")

    def add_entries(self, master):
        # Create entry widgets
        self.entry_level = tk.Entry(master, width=20, bg="lightblue")
        self.entry_level.grid(row=1, column=0, padx=5, pady=0.1, sticky="nw")  
        self.entry_level.insert(0, "5")
        self.entry_level.bind('<Return>', self.choose_wavelet)
        
    def add_comboboxes(self, root):
        # Create ComboBoxes
        self.combo_wavelet = ttk.Combobox(root, width=20)
        self.combo_wavelet["values"] = ["db1", "db2", "db3", "db4", "db5",
                 "db6", "db7", "db8", "db9", "db10",                       
                 'sym2', 'sym3', "sym4", "sym5", "sym6",
                 "sym7", "sym8", "sym9", "sym10", "sym11", "sym12",
                 "coif1", "coif2", "coif3", "coif4", "coif5",
                 "coif6", "coif7", "coif8", "coif9", "coif10"]
        self.combo_wavelet.grid(row=3, column=0, padx=5, pady=1, sticky="n")        
        
    def add_canvas(self, master):    
        # Create a frame for canvas1 with a border
        frame1 = ttk.Frame(master, borderwidth=3, relief="groove")
        frame1.grid(row=0, column=1, columnspan=1, rowspan=25, padx=5, pady=5, sticky="n")

        # Adds canvas1 widget to frame1
        self.figure1 = Figure(figsize=(13.4, 7.4), dpi=100)
        self.figure1.patch.set_facecolor('#F0F0F0')
        self.canvas1 = FigureCanvasTkAgg(self.figure1, master=frame1)
        self.canvas1.get_tk_widget().pack(fill=tk.BOTH, expand=True)

    def binds_event(self):
        # Binds combo_wavelet to choose_wavelet()
        self.combo_wavelet.bind("<<ComboboxSelected>>", self.choose_wavelet)
        
    def choose_wavelet(self, event): 
        #Reads level
        level = int(self.entry_level.get())
        #Reads wavelet type
        chosen = self.combo_wavelet.get()
          
        self.wavelet_utils.plot_orthogonal_wavelet_functions(chosen, level, self.figure1, self.canvas1)
            
if __name__ == "__main__":
    window = tk.Tk()
    Form_Wavelet(window)
    window.mainloop()


DOWNLOAD FULL SOURCE CODE VERSION 17.0


WAVELET DECOMPOSITION:





#wavelet_utils.py
import matplotlib.pyplot as plt import numpy as np import pywt from scipy.fft import fft, fftfreq from scipy.signal.windows import blackman from pywt import wavedec class Wavelet_Utils: def __init__(self): pass def create_orthogonal_scaling_wavelet_functions(self, wave_type, level): obj_wavelet = pywt.Wavelet(wave_type) (phi, psi, x) = obj_wavelet.wavefun(level=level) return phi, psi, x def fft_wavelet(self, x, y): N = len(x) w = blackman(len(x)) yf = fft(y*w) xf = fftfreq(N, 1) return N, xf, yf def plot_orthogonal_wavelet_functions(self, wave_type, level, figure, canvas): figure.clear() #Creates orthogonal scaling and wavelet functions phi, psi, x = self.create_orthogonal_scaling_wavelet_functions(wave_type, level) ax1 = figure.add_subplot(2,2,1) ax1.plot(x, phi, linewidth=3.0, color='red') ax1.set_ylabel('Amplitude', color='blue') ax1.set_xlabel('x', color='blue') ax1.set_title("$\phi$ (Scaling Function)" + " of " + wave_type) ax1.set_facecolor('#F0F0F0') ax1.grid(True) ax2 = figure.add_subplot(2,2,2) N, xf_phi, yf_phi = self.fft_wavelet(x, phi) ax2.semilogy(xf_phi[1:N//2], 2.0/N * np.abs(yf_phi[1:N//2]), linewidth=2.0, color='red') ax2.set_ylabel('Decible', color='blue') ax2.set_xlabel('$\omega$', color='blue') ax2.set_title("FFT of ($\phi$)" + " of " + wave_type) ax2.set_facecolor('#F0F0F0') ax2.grid(True) ax3 = figure.add_subplot(2,2,3) ax3.plot(x, psi, linewidth=3.0, color='blue') ax3.set_ylabel('Amplitude', color='blue') ax3.set_xlabel('x', color='blue') ax3.set_title("$\psi$ (Wavelet Function)"+ " of " + wave_type) ax3.set_facecolor('#F0F0F0') ax3.grid(True) ax4 = figure.add_subplot(2,2,4) N, xf_psi, yf_psi = self.fft_wavelet(x, psi) ax4.semilogy(xf_psi[1:N//2], 2.0/N * np.abs(yf_psi[1:N//2]), linewidth=2.0, color='blue') ax4.set_ylabel('Decible', color='blue') ax4.set_xlabel('$\omega$', color='blue') ax4.set_title("FFT of ($\psi$)" + " of " + wave_type) ax4.set_facecolor('#F0F0F0') ax4.grid(True) figure.tight_layout() canvas.draw() def wavelet_two_level_dec(self, signal_in, wave_type): coeffs = wavedec(signal_in, wave_type, mode='symmetric', level=2) cA2, cD2, cD1 = coeffs return cA2, cD2, cD1 def plot_wavelet_decomposition(self, t, signal_in, title, wave_type, figure, canvas): figure.clear() cA2, cD2, cD1 = self.wavelet_two_level_dec(signal_in, wave_type) ax1 = figure.add_subplot(2,2,1) ax1.plot(t, signal_in, linewidth=2.0, color='red') ax1.set_ylabel('Amplitude', color='blue') ax1.set_xlabel('Time (second)', color='blue') ax1.set_title(title) ax1.set_facecolor('#F0F0F0') ax1.grid(True) ax2 = figure.add_subplot(2,2,2) ax2.stem(range(len(cA2)), cA2) ax2.set_xlabel('n', color='blue') ax2.set_title("Approximation Coefficients (cA2)" + " with " + wave_type) ax2.set_facecolor('#F0F0F0') ax2.grid(True) ax3 = figure.add_subplot(2,2,3) ax3.stem(range(len(cD1)), cD1) ax3.set_xlabel('n', color='blue') ax3.set_title("Detail 1 Coefficients (cD1)" + " with " + wave_type) ax3.set_facecolor('#F0F0F0') ax3.grid(True) ax4 = figure.add_subplot(2,2,4) ax4.stem(range(len(cD2)), cD2) ax4.set_xlabel('n', color='blue') ax4.set_title("Detail 2 Coefficients (cD2)" + " with " + wave_type) ax4.set_facecolor('#F0F0F0') ax4.grid(True) figure.tight_layout() canvas.draw() #form_decomposition.py import tkinter as tk from tkinter import ttk from matplotlib.figure import Figure from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg from wavelet_utils import Wavelet_Utils from filter_utils import Filter_Utils class Form_Decomposition: def __init__(self, window): self.window = window width = 1520 height = 760 self.window.geometry(f"{width}x{height}") self.wavelet_utils = Wavelet_Utils() #Adds widgets self.add_canvas(self.window) self.add_labels(self.window) self.add_comboboxes(self.window) self.add_listbox(self.window) self.add_entries(self.window) #Binds events self.binds_event() #Creates neccesary objects self.filter_utils = Filter_Utils() self.wavelet_utils = Wavelet_Utils() self.chosen_signal = "Noisy Sinusoidal" self.chosen_wavelet = "db5" def add_labels(self, master): # Create labels self.label1 = tk.Label(master, text="SAMPLING FREQUENCY") self.label1.grid(row=0, column=0, padx=5, pady=0.1, sticky="w") self.label2 = tk.Label(master, text="TIME PERIODE") self.label2.grid(row=2, column=0, padx=5, pady=0.1, sticky="nw") self.label3 = tk.Label(master, text="NOISE AMPLITUDE") self.label3.grid(row=4, column=0, padx=5, pady=0.1, sticky="nw") self.label4 = tk.Label(master, text="CHOOSE TEST SIGNAL") self.label4.grid(row=6, column=0, padx=5, pady=0.1, sticky="w") self.label5 = tk.Label(master, text="CHOOSE WAVELET") self.label5.grid(row=8, column=0, padx=5, pady=0.1, sticky="w") def add_entries(self, master): # Create entry widgets self.entry_fs = tk.Entry(master, width=20, bg="lightblue") self.entry_fs.grid(row=1, column=0, padx=5, pady=0.1, sticky="nw") self.entry_fs.insert(0, "100") self.entry_fs.bind('<Return>', self.choose_list_widget) self.entry_periode = tk.Entry(master, width=20, bg="lightblue") self.entry_periode.grid(row=3, column=0, padx=5, pady=0.1, sticky="nw") self.entry_periode.insert(0, "1") self.entry_periode.bind('<Return>', self.choose_list_widget) self.entry_noise = tk.Entry(master, width=20, bg="lightblue") self.entry_noise.grid(row=5, column=0, padx=5, pady=0.1, sticky="nw") self.entry_noise.insert(0, "0.1") self.entry_noise.bind('<Return>', self.choose_list_widget) def add_listbox(self, root): #Menambahkan listbox widget self.listbox = tk.Listbox(root, selectmode=tk.SINGLE, width=25) self.listbox.grid(row=7, column=0, sticky='nw', padx=1, pady=1) # Menyisipkan item ke dalam list widget items = ["Noisy Sinusoidal", "Noisy Square Wave", "Noisy Amplitude Modulation Signal", "Noisy Frequency Modulation Signal", "Noisy Phase Modulation Signal", "Noisy ASK Modulation Signal", "Noisy FSK Modulation Signal", "Noisy PSK Modulation Signal"] for item in items: self.listbox.insert(tk.END, item) self.listbox.config(height=len(items)) def add_comboboxes(self, root): # Create ComboBoxes self.combo_wavelet = ttk.Combobox(root, width=20) self.combo_wavelet["values"] = ["db1", "db2", "db3", "db4", "db5", "db6", "db7", "db8", "db9", "db10", 'sym2', 'sym3', "sym4", "sym5", "sym6", "sym7", "sym8", "sym9", "sym10", "sym11", "sym12", "coif1", "coif2", "coif3", "coif4", "coif5", "coif6", "coif7", "coif8", "coif9", "coif10"] self.combo_wavelet.grid(row=9, column=0, padx=5, pady=1, sticky="n") def add_canvas(self, master): # Create a frame for canvas1 with a border frame1 = ttk.Frame(master, borderwidth=3, relief="groove") frame1.grid(row=0, column=1, columnspan=1, rowspan=25, padx=5, pady=5, sticky="n") # Adds canvas1 widget to frame1 self.figure1 = Figure(figsize=(13.4, 7.4), dpi=100) self.figure1.patch.set_facecolor('#F0F0F0') self.canvas1 = FigureCanvasTkAgg(self.figure1, master=frame1) self.canvas1.get_tk_widget().pack(fill=tk.BOTH, expand=True) def read_and_check_input(self, fs, T, amp): try: fsampling = float(fs) except ValueError: fsampling = 1000 self.entry_fs.delete(0, tk.END) self.entry_fs.insert(0, "1000") try: periode = float(T) except ValueError: periode = 1 self.entry_periode.delete(0, tk.END) self.entry_periode.insert(0, "1") try: noise_amp = float(amp) except ValueError: noise_amp = 0.1 self.entry_noise.delete(0, tk.END) self.entry_noise.insert(0, "0.1") return fsampling, periode, noise_amp def binds_event(self): # Binds combo_wavelet to choose_wavelet() self.combo_wavelet.bind("<<ComboboxSelected>>", self.choose_wavelet) #Binds listbox to choose_list_widget() function self.listbox.bind("<<ListboxSelect>>", self.choose_list_widget) def choose_list_widget(self, event): self.chosen_signal = self.listbox.get(self.listbox.curselection()) #Reads and checks params fsampling = self.entry_fs.get() periode = self.entry_periode.get() amp = self.entry_noise.get() Fs, T, noise_amp = self.read_and_check_input(fsampling, periode, amp) if self.chosen_signal == "Noisy Sinusoidal": freq_sinus = 10 self.t, self.y = self.filter_utils.generate_noisy_sinusoidal(T, freq_sinus, Fs, noise_amp) self.wavelet_utils.plot_wavelet_decomposition(self.t, self.y, self.chosen_signal, self.chosen_wavelet, self.figure1, self.canvas1) if self.chosen_signal == "Noisy Square Wave": self.t, self.y = self.filter_utils.generate_noisy_square(T, Fs, 20, noise_amp) self.wavelet_utils.plot_wavelet_decomposition(self.t, self.y, self.chosen_signal, self.chosen_wavelet, self.figure1, self.canvas1) if self.chosen_signal == "Noisy Amplitude Modulation Signal": self.t, self.y = self.filter_utils.generate_noisy_amp_modulation(T, Fs, noise_amp) self.wavelet_utils.plot_wavelet_decomposition(self.t, self.y, self.chosen_signal, self.chosen_wavelet, self.figure1, self.canvas1) if self.chosen_signal == "Noisy Frequency Modulation Signal": self.t, self.y = self.filter_utils.generate_noisy_freq_modulation(T, Fs, noise_amp) self.wavelet_utils.plot_wavelet_decomposition(self.t, self.y, self.chosen_signal, self.chosen_wavelet, self.figure1, self.canvas1) if self.chosen_signal == "Noisy Phase Modulation Signal": t, y = self.filter_utils.generate_noisy_phase_modulation(T, Fs, noise_amp) self.wavelet_utils.plot_wavelet_decomposition(self.t, self.y, self.chosen_signal, self.chosen_wavelet, self.figure1, self.canvas1) if self.chosen_signal == "Noisy ASK Modulation Signal": self.t, self.y = self.filter_utils.generate_noisy_ask_modulation(T, Fs, noise_amp) self.wavelet_utils.plot_wavelet_decomposition(self.t, self.y, self.chosen_signal, self.chosen_wavelet, self.figure1, self.canvas1) if self.chosen_signal == "Noisy FSK Modulation Signal": self.t, self.y = self.filter_utils.generate_noisy_fsk_modulation(T, Fs, noise_amp) self.wavelet_utils.plot_wavelet_decomposition(self.t, self.y, self.chosen_signal, self.chosen_wavelet, self.figure1, self.canvas1) if self.chosen_signal == "Noisy PSK Modulation Signal": self.t, self.y = self.filter_utils.generate_noisy_psk_modulation(T, Fs, noise_amp) self.wavelet_utils.plot_wavelet_decomposition(self.t, self.y, self.chosen_signal, self.chosen_wavelet, self.figure1, self.canvas1) def choose_wavelet(self, event): #Reads wavelet type self.chosen_wavelet = self.combo_wavelet.get() self.wavelet_utils.plot_wavelet_decomposition(self.t, self.y, self.chosen_signal, self.chosen_wavelet, self.figure1, self.canvas1) if __name__ == "__main__": window = tk.Tk() Form_Decomposition(window) window.mainloop()


DOWNLOAD FULL SOURCE CODE VERSION 18.0


WAVELET-BASED DENOISING



#wavelet_utils.py
import matplotlib.pyplot as plt import numpy as np import pywt from scipy.fft import fft, fftfreq from scipy.signal.windows import blackman from pywt import wavedec class Wavelet_Utils: def __init__(self): pass def create_orthogonal_scaling_wavelet_functions(self, wave_type, level): obj_wavelet = pywt.Wavelet(wave_type) (phi, psi, x) = obj_wavelet.wavefun(level=level) return phi, psi, x def fft_wavelet(self, x, y): N = len(x) w = blackman(len(x)) yf = fft(y*w) xf = fftfreq(N, 1) return N, xf, yf def plot_orthogonal_wavelet_functions(self, wave_type, level, figure, canvas): figure.clear() #Creates orthogonal scaling and wavelet functions phi, psi, x = self.create_orthogonal_scaling_wavelet_functions(wave_type, level) ax1 = figure.add_subplot(2,2,1) ax1.plot(x, phi, linewidth=3.0, color='red') ax1.set_ylabel('Amplitude', color='blue') ax1.set_xlabel('x', color='blue') ax1.set_title("$\phi$ (Scaling Function)" + " of " + wave_type) ax1.set_facecolor('#F0F0F0') ax1.grid(True) ax2 = figure.add_subplot(2,2,2) N, xf_phi, yf_phi = self.fft_wavelet(x, phi) ax2.semilogy(xf_phi[1:N//2], 2.0/N * np.abs(yf_phi[1:N//2]), linewidth=2.0, color='red') ax2.set_ylabel('Decible', color='blue') ax2.set_xlabel('$\omega$', color='blue') ax2.set_title("FFT of ($\phi$)" + " of " + wave_type) ax2.set_facecolor('#F0F0F0') ax2.grid(True) ax3 = figure.add_subplot(2,2,3) ax3.plot(x, psi, linewidth=3.0, color='blue') ax3.set_ylabel('Amplitude', color='blue') ax3.set_xlabel('x', color='blue') ax3.set_title("$\psi$ (Wavelet Function)"+ " of " + wave_type) ax3.set_facecolor('#F0F0F0') ax3.grid(True) ax4 = figure.add_subplot(2,2,4) N, xf_psi, yf_psi = self.fft_wavelet(x, psi) ax4.semilogy(xf_psi[1:N//2], 2.0/N * np.abs(yf_psi[1:N//2]), linewidth=2.0, color='blue') ax4.set_ylabel('Decible', color='blue') ax4.set_xlabel('$\omega$', color='blue') ax4.set_title("FFT of ($\psi$)" + " of " + wave_type) ax4.set_facecolor('#F0F0F0') ax4.grid(True) figure.tight_layout() canvas.draw() def wavelet_two_level_dec(self, signal_in, wave_type): coeffs = wavedec(signal_in, wave_type, mode='symmetric', level=2) cA2, cD2, cD1 = coeffs return cA2, cD2, cD1 def plot_wavelet_decomposition(self, t, signal_in, title, wave_type, figure, canvas): figure.clear() cA2, cD2, cD1 = self.wavelet_two_level_dec(signal_in, wave_type) ax1 = figure.add_subplot(2,2,1) ax1.plot(t, signal_in, linewidth=2.0, color='red') ax1.set_ylabel('Amplitude', color='blue') ax1.set_xlabel('Time (second)', color='blue') ax1.set_title(title) ax1.set_facecolor('#F0F0F0') ax1.grid(True) ax2 = figure.add_subplot(2,2,2) ax2.stem(range(len(cA2)), cA2) ax2.set_xlabel('n', color='blue') ax2.set_title("Approximation Coefficients (cA2)" + " with " + wave_type) ax2.set_facecolor('#F0F0F0') ax2.grid(True) ax3 = figure.add_subplot(2,2,3) ax3.stem(range(len(cD1)), cD1) ax3.set_xlabel('n', color='blue') ax3.set_title("Detail 1 Coefficients (cD1)" + " with " + wave_type) ax3.set_facecolor('#F0F0F0') ax3.grid(True) ax4 = figure.add_subplot(2,2,4) ax4.stem(range(len(cD2)), cD2) ax4.set_xlabel('n', color='blue') ax4.set_title("Detail 2 Coefficients (cD2)" + " with " + wave_type) ax4.set_facecolor('#F0F0F0') ax4.grid(True) figure.tight_layout() canvas.draw() # Soft thresholding function def soft_threshold(self, x, threshold): return np.sign(x) * np.maximum(np.abs(x) - threshold, 0) def wavelet_soft_thresholding_denoising(self, signal_in, wave_type, level=5, threshold=0.2): # Performs a wavelet decomposition coeffs = pywt.wavedec(signal_in, wave_type, level=level) # Applies soft thresholding to coefficients coeffs_thresh = [self.soft_threshold(c, threshold) if i > 0 else c for i, c in enumerate(coeffs)] # Reconstructs the denoised signal signal_denoised = pywt.waverec(coeffs_thresh, wave_type) return signal_denoised # Define thresholding function using SURE threshold def sure_shrink(self, x, noise_sigma): threshold = noise_sigma * np.sqrt(2 * np.log(len(x))) return np.sign(x) * np.maximum(np.abs(x) - threshold, 0) def estimate_noise_sigma(self, signal): # Calculate the Median Absolute Deviation (MAD) median = np.median(signal) mad = np.median(np.abs(signal - median)) # Estimate noise standard deviation as a multiple of MAD noise_sigma = 1.4826 * mad return noise_sigma def wavelet_sure_shrink_denoising(self, signal_in, wave_type, level=5): # Performs a wavelet decomposition coeffs = pywt.wavedec(signal_in, wave_type, level=level) # Estimate noise standard deviation (sigma) from the noisy signal noise_sigma = self.estimate_noise_sigma(signal_in) # Apply SureShrink thresholding to coefficients coeffs_thresh = [self.sure_shrink(c, noise_sigma) if i > 0 else c for i, c in enumerate(coeffs)] # Reconstructs the denoised signal signal_denoised = pywt.waverec(coeffs_thresh, wave_type) return signal_denoised # Define thresholding function using VisuShrink threshold def visu_shrink(self, x, noise_sigma): threshold = noise_sigma * np.sqrt(2 * np.log(len(x))) return np.sign(x) * np.maximum(np.abs(x) - threshold, 0) def wavelet_visu_shrink_denoising(self, signal_in, wave_type, level=5): # Performs a wavelet decomposition coeffs = pywt.wavedec(signal_in, wave_type, level=level) # Estimate noise standard deviation (sigma) from the noisy signal noise_sigma = self.estimate_noise_sigma(signal_in) # Apply VisuShrink thresholding to coefficients coeffs_thresh = [self.visu_shrink(c, noise_sigma) if i > 0 else c for i, c in enumerate(coeffs)] # Reconstructs the denoised signal signal_denoised = pywt.waverec(coeffs_thresh, wave_type) return signal_denoised # Define a function for local thresholding def local_threshold(self, x, window_size, threshold_multiplier): thresholded_coeffs = [] for i in range(len(x)): start = max(0, i - window_size) end = min(len(x), i + window_size + 1) window = x[start:end] local_threshold = np.std(window) * threshold_multiplier thresholded_coeffs.append(np.sign(x[i]) * np.maximum(np.abs(x[i]) - local_threshold, 0)) return np.array(thresholded_coeffs) def wavelet_local_thresholding_denoising(self, signal_in, wave_type, level=5): # Set parameters for local thresholding window_size = 10 # Size of the local window threshold_multiplier = 3 # Multiplier for threshold calculation # Performs a wavelet decomposition coeffs = pywt.wavedec(signal_in, wave_type, level=level) # Apply local thresholding to coefficients (except the approximation coefficients) coeffs_thresh = [self.local_threshold(c, window_size, threshold_multiplier) if i > 0 else c for i, c in enumerate(coeffs)] # Reconstructs the denoised signal signal_denoised = pywt.waverec(coeffs_thresh, wave_type) return signal_denoised # Define a function for adaptive thresholding def adaptive_threshold(self, x, threshold_multiplier): thresholded_coeffs = [] for i in range(len(x)): local_threshold = np.std(x) * threshold_multiplier thresholded_coeffs.append(np.sign(x[i]) * np.maximum(np.abs(x[i]) - local_threshold, 0)) return np.array(thresholded_coeffs) def wavelet_adaptive_thresholding_denoising(self, signal_in, wave_type, level=5): threshold_multiplier = 3 # Multiplier for threshold calculation # Performs a wavelet decomposition coeffs = pywt.wavedec(signal_in, wave_type, level=level) # Apply adaptive thresholding to coefficients (except the approximation coefficients) coeffs_thresh = [self.adaptive_threshold(c, threshold_multiplier) if i > 0 else c for i, c in enumerate(coeffs)] # Reconstructs the denoised signal signal_denoised = pywt.waverec(coeffs_thresh, wave_type) return signal_denoised def plot_wavelet_denoising(self, t, signal_in, title, wave_type, level, threshold, figure, canvas): figure.clear() ax1 = figure.add_subplot(3,2,1) ax1.plot(t, signal_in, linewidth=2.0, color='red') ax1.set_ylabel('Amplitude', color='blue') ax1.set_xlabel('Time (second)', color='blue') ax1.set_title(title) ax1.set_facecolor('#F0F0F0') ax1.grid(True) signal_soft_denoised = self.wavelet_soft_thresholding_denoising(signal_in, wave_type, level, threshold) ax2 = figure.add_subplot(3,2,2) ax2.plot(t, signal_soft_denoised, linewidth=2.0, color='blue') ax2.set_xlabel('Time (second)', color='blue') ax2.set_title("Soft Thresholding Denoising" + " with " + wave_type) ax2.set_facecolor('#F0F0F0') ax2.grid(True) signal_sure_denoised = self.wavelet_sure_shrink_denoising(signal_in, wave_type, level) ax3 = figure.add_subplot(3,2,3) ax3.plot(t, signal_sure_denoised, linewidth=2.0, color='green') ax3.set_xlabel('Time (second)', color='blue') ax3.set_title("SureShrink Thresholding Denoising" + " with " + wave_type) ax3.set_facecolor('#F0F0F0') ax3.grid(True) signal_visu_denoised = self.wavelet_visu_shrink_denoising(signal_in, wave_type, level) ax4 = figure.add_subplot(3,2,4) ax4.plot(t, signal_visu_denoised, linewidth=2.0, color='black') ax4.set_xlabel('Time (second)', color='blue') ax4.set_title("VisuShrink Thresholding Denoising" + " with " + wave_type) ax4.set_facecolor('#F0F0F0') ax4.grid(True) signal_local_denoised = self.wavelet_local_thresholding_denoising(signal_in, wave_type, level) ax5 = figure.add_subplot(3,2,5) ax5.plot(t, signal_local_denoised, linewidth=2.0, color='orange') ax5.set_xlabel('Time (second)', color='blue') ax5.set_title("Local Thresholding Denoising" + " with " + wave_type) ax5.set_facecolor('#F0F0F0') ax5.grid(True) signal_adapt_denoised = self.wavelet_adaptive_thresholding_denoising(signal_in, wave_type, level) ax5 = figure.add_subplot(3,2,6) ax5.plot(t, signal_adapt_denoised, linewidth=2.0, color='brown') ax5.set_xlabel('Time (second)', color='blue') ax5.set_title("Adaptive Thresholding Denoising" + " with " + wave_type) ax5.set_facecolor('#F0F0F0') ax5.grid(True) figure.tight_layout() canvas.draw() #form_denoising.py import tkinter as tk from tkinter import ttk from matplotlib.figure import Figure from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg from wavelet_utils import Wavelet_Utils from filter_utils import Filter_Utils class Form_Denoising: def __init__(self, window): self.window = window width = 1520 height = 760 self.window.geometry(f"{width}x{height}") self.wavelet_utils = Wavelet_Utils() #Adds widgets self.add_canvas(self.window) self.add_labels(self.window) self.add_comboboxes(self.window) self.add_listbox(self.window) self.add_entries(self.window) #Binds events self.binds_event() #Creates neccesary objects self.filter_utils = Filter_Utils() self.wavelet_utils = Wavelet_Utils() self.chosen_signal = "Noisy Sinusoidal" self.chosen_wavelet = "db5" def add_labels(self, master): # Create labels self.label1 = tk.Label(master, text="SAMPLING FREQUENCY") self.label1.grid(row=0, column=0, padx=5, pady=0.1, sticky="w") self.label2 = tk.Label(master, text="TIME PERIODE") self.label2.grid(row=2, column=0, padx=5, pady=0.1, sticky="nw") self.label3 = tk.Label(master, text="NOISE AMPLITUDE") self.label3.grid(row=4, column=0, padx=5, pady=0.1, sticky="nw") self.label4 = tk.Label(master, text="DECOMPOSITION LEVEL") self.label4.grid(row=6, column=0, padx=5, pady=0.1, sticky="nw") self.label5 = tk.Label(master, text="THRESHOLD") self.label5.grid(row=8, column=0, padx=5, pady=0.1, sticky="nw") self.label6 = tk.Label(master, text="CHOOSE TEST SIGNAL") self.label6.grid(row=10, column=0, padx=5, pady=0.1, sticky="w") self.label7 = tk.Label(master, text="CHOOSE WAVELET") self.label7.grid(row=12, column=0, padx=5, pady=0.1, sticky="w") def add_entries(self, master): # Create entry widgets self.entry_fs = tk.Entry(master, width=20, bg="lightblue") self.entry_fs.grid(row=1, column=0, padx=5, pady=0.1, sticky="nw") self.entry_fs.insert(0, "1000") self.entry_fs.bind('<Return>', self.choose_list_widget) self.entry_periode = tk.Entry(master, width=20, bg="lightblue") self.entry_periode.grid(row=3, column=0, padx=5, pady=0.1, sticky="nw") self.entry_periode.insert(0, "1") self.entry_periode.bind('<Return>', self.choose_list_widget) self.entry_noise = tk.Entry(master, width=20, bg="lightblue") self.entry_noise.grid(row=5, column=0, padx=5, pady=0.1, sticky="nw") self.entry_noise.insert(0, "0.1") self.entry_noise.bind('<Return>', self.choose_list_widget) self.entry_level = tk.Entry(master, width=20, bg="lightblue") self.entry_level.grid(row=7, column=0, padx=5, pady=0.1, sticky="nw") self.entry_level.insert(0, "5") self.entry_level.bind('<Return>', self.choose_list_widget) self.entry_thresh = tk.Entry(master, width=20, bg="lightblue") self.entry_thresh.grid(row=9, column=0, padx=5, pady=0.1, sticky="nw") self.entry_thresh.insert(0, "0.2") self.entry_thresh.bind('<Return>', self.choose_list_widget) def add_listbox(self, root): #Menambahkan listbox widget self.listbox = tk.Listbox(root, selectmode=tk.SINGLE, width=25) self.listbox.grid(row=11, column=0, sticky='nw', padx=1, pady=1) # Menyisipkan item ke dalam list widget items = ["Noisy Sinusoidal", "Noisy Square Wave", "Noisy Amplitude Modulation Signal", "Noisy Frequency Modulation Signal", "Noisy Phase Modulation Signal", "Noisy ASK Modulation Signal", "Noisy FSK Modulation Signal", "Noisy PSK Modulation Signal"] for item in items: self.listbox.insert(tk.END, item) self.listbox.config(height=len(items)) def add_comboboxes(self, root): # Create ComboBoxes self.combo_wavelet = ttk.Combobox(root, width=20) self.combo_wavelet["values"] = ["db1", "db2", "db3", "db4", "db5", "db6", "db7", "db8", "db9", "db10", 'sym2', 'sym3', "sym4", "sym5", "sym6", "sym7", "sym8", "sym9", "sym10", "sym11", "sym12", "coif1", "coif2", "coif3", "coif4", "coif5", "coif6", "coif7", "coif8", "coif9", "coif10"] self.combo_wavelet.grid(row=13, column=0, padx=5, pady=1, sticky="n") def add_canvas(self, master): # Create a frame for canvas1 with a border frame1 = ttk.Frame(master, borderwidth=3, relief="groove") frame1.grid(row=0, column=1, columnspan=1, rowspan=25, padx=5, pady=5, sticky="n") # Adds canvas1 widget to frame1 self.figure1 = Figure(figsize=(13.4, 7.4), dpi=100) self.figure1.patch.set_facecolor('#F0F0F0') self.canvas1 = FigureCanvasTkAgg(self.figure1, master=frame1) self.canvas1.get_tk_widget().pack(fill=tk.BOTH, expand=True) def read_and_check_input(self, fs, T, amp, level, thresh): try: fsampling = float(fs) except ValueError: fsampling = 1000 self.entry_fs.delete(0, tk.END) self.entry_fs.insert(0, "1000") try: periode = float(T) except ValueError: periode = 1 self.entry_periode.delete(0, tk.END) self.entry_periode.insert(0, "1") try: noise_amp = float(amp) except ValueError: noise_amp = 0.1 self.entry_noise.delete(0, tk.END) self.entry_noise.insert(0, "0.1") try: level_dec = int(level) except ValueError: level_dec = 5 self.entry_level.delete(0, tk.END) self.entry_level.insert(0, "5") try: threshold = float(thresh) except ValueError: threshold = 0.2 self.entry_thresh.delete(0, tk.END) self.entry_thresh.insert(0, "0.2") return fsampling, periode, noise_amp, level_dec, threshold def binds_event(self): # Binds combo_wavelet to choose_wavelet() self.combo_wavelet.bind("<<ComboboxSelected>>", self.choose_wavelet) #Binds listbox to choose_list_widget() function self.listbox.bind("<<ListboxSelect>>", self.choose_list_widget) def choose_list_widget(self, event): self.chosen_signal = self.listbox.get(self.listbox.curselection()) #Reads and checks params fsampling = self.entry_fs.get() periode = self.entry_periode.get() amp = self.entry_noise.get() level = self.entry_level.get() thresh = self.entry_thresh.get() Fs, T, noise_amp, level_dec, threshold = self.read_and_check_input(fsampling, periode, amp, level, thresh) if self.chosen_signal == "Noisy Sinusoidal": freq_sinus = 10 self.t, self.y = self.filter_utils.generate_noisy_sinusoidal(T, freq_sinus, Fs, noise_amp) self.wavelet_utils.plot_wavelet_denoising(self.t, self.y, self.chosen_signal, self.chosen_wavelet, level_dec, threshold, self.figure1, self.canvas1) if self.chosen_signal == "Noisy Square Wave": self.t, self.y = self.filter_utils.generate_noisy_square(T, Fs, 20, noise_amp) self.wavelet_utils.plot_wavelet_denoising(self.t, self.y, self.chosen_signal, self.chosen_wavelet, level_dec, threshold, self.figure1, self.canvas1) if self.chosen_signal == "Noisy Amplitude Modulation Signal": self.t, self.y = self.filter_utils.generate_noisy_amp_modulation(T, Fs, noise_amp) self.wavelet_utils.plot_wavelet_denoising(self.t, self.y, self.chosen_signal, self.chosen_wavelet, level_dec, threshold, self.figure1, self.canvas1) if self.chosen_signal == "Noisy Frequency Modulation Signal": self.t, self.y = self.filter_utils.generate_noisy_freq_modulation(T, Fs, noise_amp) self.wavelet_utils.plot_wavelet_denoising(self.t, self.y, self.chosen_signal, self.chosen_wavelet, level_dec, threshold, self.figure1, self.canvas1) if self.chosen_signal == "Noisy Phase Modulation Signal": self.t, self.y = self.filter_utils.generate_noisy_phase_modulation(T, Fs, noise_amp) self.wavelet_utils.plot_wavelet_denoising(self.t, self.y, self.chosen_signal, self.chosen_wavelet, level_dec, threshold, self.figure1, self.canvas1) if self.chosen_signal == "Noisy ASK Modulation Signal": self.t, self.y = self.filter_utils.generate_noisy_ask_modulation(T, Fs, noise_amp) self.wavelet_utils.plot_wavelet_denoising(self.t, self.y, self.chosen_signal, self.chosen_wavelet, level_dec, threshold, self.figure1, self.canvas1) if self.chosen_signal == "Noisy FSK Modulation Signal": self.t, self.y = self.filter_utils.generate_noisy_fsk_modulation(T, Fs, noise_amp) self.wavelet_utils.plot_wavelet_denoising(self.t, self.y, self.chosen_signal, self.chosen_wavelet, level_dec, threshold, self.figure1, self.canvas1) if self.chosen_signal == "Noisy PSK Modulation Signal": self.t, self.y = self.filter_utils.generate_noisy_psk_modulation(T, Fs, noise_amp) self.wavelet_utils.plot_wavelet_denoising(self.t, self.y, self.chosen_signal, self.chosen_wavelet, level_dec, threshold, self.figure1, self.canvas1) def choose_wavelet(self, event): #Reads wavelet type self.chosen_wavelet = self.combo_wavelet.get() #Reads and checks params fsampling = self.entry_fs.get() periode = self.entry_periode.get() amp = self.entry_noise.get() level = self.entry_level.get() thresh = self.entry_thresh.get() Fs, T, noise_amp, level_dec, threshold = self.read_and_check_input(fsampling, periode, amp, level, thresh) self.wavelet_utils.plot_wavelet_denoising(self.t, self.y, \ self.chosen_signal, self.chosen_wavelet, level_dec, threshold, self.figure1, self.canvas1) if __name__ == "__main__": window = tk.Tk() Form_Denoising(window) window.mainloop()


DOWNLOAD FULL SOURCE CODE VERSION 19.0






No comments:

Post a Comment