def test_signal_smooth(): # TODO: test kernels other than "boxcar" signal = np.cos(np.linspace(start=0, stop=20, num=1000)) smooth1 = nk.signal_smooth(signal, kernel="boxcar", size=100) smooth2 = nk.signal_smooth(signal, kernel="boxcar", size=500) # assert that the signal's amplitude is attenuated more with wider kernels assert np.allclose(np.std(smooth1), 0.6044, atol=0.00001) assert np.allclose(np.std(smooth2), 0.1771, atol=0.0001)
def signals_analysis(signals, is_out=False, is_show=False, out_path="figs"): """ 数据的分析 主要是特征参数的获取 :param signals: 初步处理过的数据 :param is_out: :param is_show: :param out_path: :return: """ sampling_rate = signals["Sampling Rate"] feature_points = signals["Feature Points"] cleaned_pulses = feature_points["Cleaned Pulses"] peaks = feature_points["Peaks"] title = "Time Analysis" hrv_time = nk.hrv_time(peaks, sampling_rate, show=is_show) if is_out: no = datetime.datetime.now().strftime("%Y%m%d%H%M%S") out_name = os.path.join("outputs", str(out_path) + "___" + no + title + ".png") plt.savefig(out_name, dpi=300) if is_show: plt.show() title = "Frequency Analysis" hrv_freq = nk.hrv_frequency(peaks, sampling_rate, show=is_show) if is_out: no = datetime.datetime.now().strftime("%Y%m%d%H%M%S") out_name = os.path.join("outputs", str(out_path) + "___" + no + title + ".png") plt.savefig(out_name, dpi=300) if is_show: plt.show() title = "Nonlinear Analysis" hrv_nonlinear = nk.hrv_nonlinear(peaks, sampling_rate, show=is_show) if is_out: no = datetime.datetime.now().strftime("%Y%m%d%H%M%S") out_name = os.path.join("outputs", str(out_path) + "___" + no + title + ".png") plt.savefig(out_name, dpi=300) if is_show: plt.show() # 傅里叶分析 对应给的文章 xFFT = np.abs(np.fft.rfft(cleaned_pulses) / len(cleaned_pulses)) xFFT = xFFT[:600] xFreqs = np.linspace(0, sampling_rate // 2, len(cleaned_pulses) // 2 + 1) xFreqs = xFreqs[:600] # 滤波处理 平滑去噪 只处理前200个信号即可 # TODO 去噪方法可以调节 cleaned_xFFT = nk.signal_smooth(xFFT, method="loess") # 计算特征值 # F1值 cleaned_FFT = cleaned_xFFT.copy() locmax, props = spsg.find_peaks(cleaned_xFFT) hr_hz_index = np.argmax(cleaned_xFFT) f1 = np.argmax(xFFT) fmax = np.argmax(cleaned_xFFT[locmax]) cleaned_xFFT[locmax[fmax]] = np.min(cleaned_xFFT) f2s = np.argmax(cleaned_xFFT[locmax]) if f2s - fmax != 1: hr_hz_index = locmax[0] + int(np.sqrt(locmax[1] - locmax[0])) # F2值 f2 = locmax[np.argmax(cleaned_xFFT[locmax])] F1 = np.round(xFreqs[f1], 2) F2 = np.round(xFreqs[f2], 2) # 相位差 F2_F1 = F2 - F1 # 心率 HR_FFT = xFreqs[hr_hz_index] * 60 print(HR_FFT) if is_show: plt.plot(xFreqs, cleaned_FFT) plt.scatter(xFreqs[f1], cleaned_FFT[f1], color="red", label="F1 = " + str(F1) + "HZ") plt.scatter(xFreqs[f2], cleaned_FFT[f2], color="orange", label="F2 = " + str(F2) + "HZ") plt.legend(loc="upper right") plt.ylabel("Power") plt.xlabel("Freq(Hz)") title = "FFT analysis" plt.title(title) if is_out: no = datetime.datetime.now().strftime("%Y%m%d%H%M%S") out_name = os.path.join( "outputs", str(out_path) + "___" + no + title + ".png") plt.savefig(out_name, dpi=300) plt.show() hrv_new = { "Power": xFFT, "Freq": cleaned_FFT, "X": xFreqs, "F1": F1, "F2": F2, "F2_F1": F2_F1, "HR_FFT": HR_FFT } return { "HRV New": hrv_new, "HRV Time": hrv_time, "HRV Frequency": hrv_freq, "HRV Nonlinear": hrv_nonlinear }