-
Notifications
You must be signed in to change notification settings - Fork 14
/
signal_processing_utils.py
132 lines (99 loc) · 3.96 KB
/
signal_processing_utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import pywt
import numpy as np
import matplotlib.pyplot as plt
import logging
from skimage.restoration import denoise_wavelet, estimate_sigma
from scipy import signal
from scipy.signal import butter, firwin, lfilter, filtfilt, hilbert
from scipy.ndimage.filters import uniform_filter1d
def bw_filter(acc_x, acc_y, acc_z, ang_x, ang_y, ang_z):
"""Third order butterworth bandpass filter for IMU data.
params:
acc_x: linear acceleration in x-direction [m/s^2].
acc_y: linear acceleration in y-direction [m/s^2].
acc_z: linear acceleration in z-direction [m/s^2].
ang_x: angular velocity about x-axis [rad/s].
ang_y: angular velocity about y-axis [rad/s].
ang_z: angular velocity about z-axis [rad/s].
"""
b, a = signal.butter(3, 0.002)
acc_x2 = signal.filtfilt(b,a,acc_x)
acc_y2 = signal.filtfilt(b,a,acc_y)
acc_z2 = signal.filtfilt(b,a,acc_z)
ang_x2 = signal.filtfilt(b,a,ang_x)
ang_y2 = signal.filtfilt(b,a,ang_y)
ang_z2 = signal.filtfilt(b,a,ang_z)
return acc_x2, acc_y2, acc_z2, ang_x2, ang_y2, ang_z2
def dewow(config, gpr_img):
"""Polynomial dewow filter.
params:
config: Dewow configuration parameters.
trace_im: np.2darray of horizontally stacked traces.
"""
first_trace = gpr_img[:,0]
model = np.polyfit(np.arange(gpr_img.shape[0]), first_trace, config.degree)
pred = np.polyval(model, gpr_img.shape[0])
return gpr_img + pred
def discrete_wavelet_transform(trace_1d, threshold=.45):
"""Performs discrete wavelet transforms on 1D waveform.
params:
trace_1d: list containing amplitudes of GPR signal.
threshold: float in [0,1] provided to the wavelet filter.
More information is available in the pywavelets documentation.
https://pywavelets.readthedocs.io/en/latest/ref/idwt-inverse-discrete-wavelet-transform.html
"""
wavelet = pywt.Wavelet('db2')
coeffs = pywt.wavedec(trace_1d, wavelet, level=3)
for i in range(len(coeffs)):
if i == 0:
continue
K = np.round(threshold * len(coeffs[i])).astype(int)
coeffs[i][K:] = np.zeros(len(coeffs[i]) - K)
return pywt.waverec(coeffs, wavelet)
def bgr(gpr_img, window=0, verbose=False):
"""Horizontal background removal filter.
params:
config: AttrDict structure containing window parameters.
trace_im: np.2darray of horizontally stacked traces.
"""
if window == 0:
return gpr_img
elif window == -1:
return gpr_img - np.average(gpr_img, axis=1)[:, np.newaxis]
else:
if window < 10:
logging.warning(f'BGR window of size {window} is short.')
if (window / 2.0 == int(window / 2)):
window = window + 1
gpr_img -= uniform_filter1d(gpr_img,
size=window,
mode='constant',
cval=0.0,
axis=1)
return gpr_img
def triangular(config, gpr_img):
"""Triangle FIR bandpass filter.
params:
config: AttrDict structure containing relevant system freq parameters.
gpr_img: np.2darray of horizontally stacked traces.
"""
filt = firwin(numtaps=int(config.num_taps),
cutoff=[int(config.min_freq), int(config.max_freq)],
window='triangle',
pass_zero='bandpass',
fs=int(config.sampling_freq))
proc_trace = np.copy(lfilter(filt, 1.0, gpr_img, axis=0))
proc_trace = lfilter(filt, 1.0, proc_trace[::-1], axis=0)[::-1]
return proc_trace
def sec_gain(gpr_img, a=0.02, b=1, threshold=90):
"""Spreading and Exponential Compensation (SEC) gain function.
params:
gpr_img: np.2darray of horizontally stacked traces.
a: Power gain component.
b: Linear gain component.
threshold: Cut-off array element where gain is flattened.
"""
t = np.arange(gpr_img.shape[0])
gain_fn = t**b * np.exp(t*a)
gain_fn[threshold:] = gain_fn[threshold]
return np.multiply(gain_fn[:, np.newaxis], gpr_img)