EMG_Biometrics_2021/Signal_prep.py

86 lines
2.6 KiB
Python
Raw Normal View History

import numpy as np
import matplotlib.pyplot as plt
import pandas
2021-06-23 13:56:35 +00:00
from pandas.core.frame import DataFrame
from scipy.fft import fft, fftfreq
2021-06-24 10:02:49 +00:00
import pywt
#from scipy.signal import wavelets
2021-06-24 12:17:31 +00:00
#import pyyawt
2021-06-23 13:56:35 +00:00
import Handle_emg_data as Handler
2021-06-23 11:26:17 +00:00
2021-06-23 13:56:35 +00:00
SAMPLE_RATE = 200
2021-06-23 11:26:17 +00:00
# Takes in a df and outputs np arrays for x and y values
2021-06-24 13:45:33 +00:00
def get_xory_from_df(x_or_y, df:DataFrame):
swither = {
'x': df.iloc[:,0].to_numpy(),
'y': df.iloc[:,1].to_numpy()
}
return swither.get(x_or_y, 0)
# Normalizes a ndarray of a signal to the scale of int16(32767)
2021-06-23 13:56:35 +00:00
def normalize_wave(y_values):
2021-06-24 07:40:30 +00:00
y = np.int16((y_values / y_values.max()) * 32767)
return y
2021-06-23 13:56:35 +00:00
# Takes the FFT of a DataFrame object
2021-06-24 10:02:49 +00:00
def fft_of_df(df:DataFrame):
2021-06-24 13:45:33 +00:00
y_values = get_xory_from_df('y', df)
2021-06-24 10:02:49 +00:00
N = y_values.size
norm = normalize_wave(y_values)
N_trans = fftfreq(N, 1 / SAMPLE_RATE)
y_f = fft(norm)
return N_trans, y_f
2021-06-24 10:02:49 +00:00
# Removes noise with db4 wavelet function
def wavelet_db4_denoising(df:DataFrame):
2021-06-24 13:45:33 +00:00
y_values = get_xory_from_df('y', df)
#y_values = normalize_wave(y_values)
2021-06-24 10:02:49 +00:00
wavelet = pywt.Wavelet('db4')
cA, cD = pywt.dwt(y_values, wavelet)
N_trans = np.array(range(int(np.floor((y_values.size + wavelet.dec_len - 1) / 2))))
return N_trans, cA, cD
# Filters signal accordning to Stein's Unbiased Risk Estimate(SURE)
2021-06-25 09:47:12 +00:00
'''
def sure_threshold_filter(cA, cD):
2021-06-24 12:35:37 +00:00
cA_filt = pyyawt.theselect(cA, 'rigrsure')
cD_filt = cD
return cA_filt, cD_filt
2021-06-25 09:47:12 +00:00
'''
2021-06-25 07:12:12 +00:00
# soft filtering of wavelet trans with the 40% lowest removed
def soft_threshold_filter(cA, cD, threshold):
cA_filt = pywt.threshold(cA, threshold * cA.max())
2021-06-24 12:35:37 +00:00
cD_filt = cD
return cA_filt, cD_filt
2021-06-24 13:45:33 +00:00
# Inverse dwt for brining denoise signal back to the time domainfi
def inverse_wavelet(df, cA_filt, cD_filt):
2021-06-24 12:35:37 +00:00
wavelet = pywt.Wavelet('db4')
y_new_values = pywt.idwt(cA_filt, cD_filt, wavelet)
2021-06-24 13:45:33 +00:00
new_len = len(y_new_values)
old_len = len(get_xory_from_df('y', df))
if new_len > old_len:
while new_len > old_len:
y_new_values = y_new_values[:-1]
new_len = len(y_new_values)
old_len = len(get_xory_from_df('y', df))
2021-06-24 12:35:37 +00:00
return y_new_values
# Takes in handler and detailes to denoise. Returns arrays and df
def denoice_dataset(handler:Handler.CSV_handler, subject_nr, which_arm, round, emg_nr, threshold):
2021-06-25 12:00:25 +00:00
df = handler.get_df_from_data_dict(subject_nr, which_arm, round, emg_nr)
N = get_xory_from_df('x', df)
N_trans, cA, cD = wavelet_db4_denoising(df)
cA_filt, cD_filt = soft_threshold_filter(cA, cD, threshold)
y_values = inverse_wavelet(df, cA_filt, cD_filt)
2021-06-25 12:27:51 +00:00
df_new = Handler.make_df_from_xandy(N, y_values, emg_nr)
return df_new