Spaces:
Runtime error
Runtime error
import numpy as np | |
import matplotlib.pyplot as plt | |
from scipy.signal import detrend,savgol_filter | |
from scipy.ndimage import gaussian_filter1d | |
import streamlit as st | |
def moving_average(signal, window_size=7): | |
return np.convolve(signal, np.ones(window_size) / window_size, mode='full')[window_size:-window_size+1] | |
def window_detrend(signal, window_size=20,trend='linear'): | |
""" | |
Calculate mean of every window_size elements and subtract the mean from the window. | |
""" | |
out = np.array([]) | |
for i in range(0, len(signal)-window_size): | |
# out.append(detrend(signal[i:i+window_size])[-1]) | |
out = np.append(out, detrend(signal[i:i+window_size],type=trend)[-1]) | |
return out | |
if __name__ == '__main__': | |
signal = dict() | |
signal['Linearly increasing sine wave'] = np.sin(np.linspace(0, 100, 1000)) + np.linspace(0, 100, 1000) | |
signal['Resp Signal sample 1'] = np.load('./RR_signal1.npy') | |
signal['Resp Signal sample 2'] = np.load('./RR_signal2.npy') | |
signal['Resp Signal sample 3'] = np.load('./RR_signal3.npy') | |
st.set_page_config(layout="wide") | |
# with st.sidebar: | |
# st.markdown( | |
# """ | |
# <style> | |
# section[data-testid="stSidebar"] { | |
# width: 300px !important; # Set the width to your desired value | |
# } | |
# </style> | |
# """, | |
# unsafe_allow_html=True, | |
# ) | |
# st.header('Detrend and Savitzky-Golay Filter') | |
# st.write('This app demonstrated the effect of detrending and Savitzky-Golay filter to the signal.') | |
# st.header('Detrending : ') | |
# st.write('The detrend function removes the trend from a signal. Trend could either be linear or constant.') | |
# st.header('Savitzky-Golay Filter : ') | |
# st.write('The Savitzky-Golay filter is a filter that fits a polynomial to a window of data and returns the fitted value ') | |
st.title('Detrend and Savitzky-Golay Filter') | |
st.write('This Space demonstrates the effect of Detrending and Savitzky-Golay filter to Respiratory signals.') | |
st.write('---') | |
st.subheader('Detrending : ') | |
st.write('Detrending means removal of the mean value as well as any linear trend that may be in the measurements. A linear trend could be caused by e.g. drift and it is removed by fitting a first order polynomial to each of the measurement channels and then subtracting it afterwards. By default linear trends should be removed since they can disturb the signal processing and modal analysis.') | |
st.subheader('Savitzky-Golay Filter : ') | |
st.write('Savitzky-Golay smoothing filters are typically used to "smooth out" a noisy signal. They are also called digital smoothing polynomial filters or least-squares smoothing filters. Savitzky-Golay filters perform better in some applications than standard averaging FIR filters, which tend to filter high-frequency content along with the noise. Savitzky-Golay filters are more effective at preserving high frequency signal components but less successful at rejecting noise.Savitzky-Golay filters are optimal in the sense that they minimize the least-squares error in fitting a polynomial to frames of noisy data.') | |
st.subheader('Moving Average Filter : ') | |
st.write('The moving average is the most common filter in Signal Processing , mainly because it is the easiest digital filter to understand and use. The moving average filter is optimal for a common task: reducing random noise while retaining a sharp step response.This makes it the premier filter for time domain encoded signals.') | |
st.subheader('Gaussian Filter : ') | |
st.write('Gaussian filters are widely used for noise reduction due to their edge preserving properties. Gaussian filters are also used as smoothing filters. The Gaussian filter is a low-pass filter that removes the high-frequency components.') | |
st.write('---') | |
with st.container(): | |
# show video | |
st.header('Video Demonstration of gathering a respiratory signal') | |
st.video('./SpeedUP_Supine.mp4') | |
st.write('---') | |
st.header('Signal Processing') | |
with st.container(): | |
left,right = st.columns(2) | |
with left: | |
signal_select = st.selectbox('*Please select a signal*',['Linearly increasing sine wave','Resp Signal sample 1','Resp Signal sample 2','Resp Signal sample 3'],index=1) | |
with right: | |
st.subheader('Original Signal') | |
fig1, ax1 = plt.figure(figsize=(10,5),dpi=150), plt.gca() | |
ax1.plot(signal[signal_select]) | |
ax1.set_xlabel('Time') | |
ax1.set_ylabel('Amplitude') | |
ax1.set_title('Original Signal') | |
# ax1.legend() | |
st.pyplot(fig1) | |
st.write('---') | |
with st.container(): | |
left,right = st.columns(2) | |
with left: | |
st.subheader('Detrending') | |
window_size_dt = st.slider('*Window Size for Detrending*',min_value=1,max_value=100,value=20,step=1) | |
st.write('Window size is the number of samples to be considered for detrending.') | |
trend_type = st.selectbox('*Trend Type*',['linear','constant','Dont Remove']) | |
st.write('Trend type is the type of trend to be removed from the signal.') | |
with right: | |
st.subheader('Detrended Signal') | |
fig2, ax2 = plt.figure(figsize=(10,5),dpi=150), plt.gca() | |
if trend_type == 'Dont Remove': | |
detrend_signal = signal[signal_select] | |
else: | |
detrend_signal = window_detrend(signal[signal_select], window_size=window_size_dt, trend=trend_type) | |
ax2.plot(detrend_signal) | |
ax2.set_xlabel('Time') | |
ax2.set_ylabel('Amplitude') | |
ax2.set_title('Detrended Signal') | |
# ax2.legend() | |
st.pyplot(fig2) | |
st.write('---') | |
with st.container(): | |
left,right = st.columns(2) | |
with left: | |
st.subheader('Savitzky-Golay Filter') | |
window_size_sg = st.slider('*Window Size for Savitzky-Golay filter*',min_value=1,max_value=100,value=20,step=1) | |
st.write('Window size is the number of samples to be considered for filtering.') | |
order = st.slider('*Polynomial Order*',min_value=1,max_value=10,value=3,step=1) | |
st.write('Order is the order of the polynomial to be fitted to the window of data.') | |
with right: | |
st.subheader('Savitzky-Golay Filter applied to Detrended Signal') | |
fig3, ax3 = plt.figure(figsize=(10,5),dpi=150), plt.gca() | |
if trend_type == 'Dont Remove': | |
detrend_signal = signal[signal_select] | |
else: | |
detrend_signal = window_detrend(signal[signal_select], window_size=window_size_dt, trend=trend_type) | |
sg_signal = savgol_filter(detrend_signal, window_size_sg, order) | |
ax3.plot(sg_signal) | |
ax3.set_xlabel('Time') | |
ax3.set_ylabel('Amplitude') | |
ax3.set_title('Savitzky-Golay Filtered Signal') | |
# ax3.legend() | |
st.pyplot(fig3) | |
st.write('---') | |
with st.container(): | |
left,right = st.columns(2) | |
with left: | |
st.subheader('Moving Average Filter') | |
window_size_ma = st.slider('*Window Size for Moving Average filter*',min_value=1,max_value=100,value=20,step=1) | |
st.write('Window size is the number of samples to be considered for filtering.') | |
with right: | |
st.subheader('Moving Average Filter applied to Detrended Signal') | |
fig4, ax4 = plt.figure(figsize=(10,5),dpi=150), plt.gca() | |
if trend_type == 'Dont Remove': | |
detrend_signal = signal[signal_select] | |
else: | |
detrend_signal = window_detrend(signal[signal_select], window_size=window_size_dt, trend=trend_type) | |
ma_signal = moving_average(detrend_signal, window_size_ma) | |
ax4.plot(ma_signal) | |
ax4.set_xlabel('Time') | |
ax4.set_ylabel('Amplitude') | |
ax4.set_title('Moving Average Filtered Signal') | |
# ax4.legend() | |
st.pyplot(fig4) | |
st.write('---') | |
with st.container(): | |
left,right = st.columns(2) | |
with left: | |
st.subheader('Gaussian Filter') | |
sigma_gf = st.slider('*Sigma*',min_value=0.1,max_value=10.0,value=3.0,step=0.1) | |
st.write('Sigma is the standard deviation for Gaussian kernel.') | |
mode_gf = st.selectbox('*Mode*',['reflect','constant','nearest','mirror','wrap']) | |
st.write('Mode is the type of boundary condition to be applied to the filter.') | |
st.write('*Reflect :* The input is extended by reflecting about the edge of the last pixel.') | |
st.write('*Constant :* The input is extended by filling all values beyond the edge with the value 0.0') | |
st.write('*Nearest :* The input is extended by replicating the last pixel.') | |
st.write('*Mirror :* The input is extended by reflecting about the center of the last pixel.') | |
st.write('*Wrap :* The input is extended by wrapping around to the opposite edge.') | |
with right: | |
st.subheader('Gaussian Filter apllied to Detrended Signal') | |
fig5, ax5 = plt.figure(figsize=(10,5),dpi=150), plt.gca() | |
if trend_type == 'Dont Remove': | |
detrend_signal = signal[signal_select] | |
else: | |
detrend_signal = window_detrend(signal[signal_select], window_size=window_size_dt, trend=trend_type) | |
gf_signal = gaussian_filter1d(detrend_signal, sigma=sigma_gf, mode=mode_gf) | |
ax5.plot(gf_signal) | |
ax5.set_xlabel('Time') | |
ax5.set_ylabel('Amplitude') | |
ax5.set_title('Gaussian Filtered Signal') | |
st.pyplot(fig5) | |
st.write('---') | |