python 滑窗法检测房颤分类
判断信号的峰值间的距离是否相差较少
废话不说,直接上程序!记得点赞!!!!!!
思路主要是使用滑窗找到最大值对应的位置,最大值对应的位置相差间距求出来,相邻较小的位置删除,保留一定间距的位置。最终,每个位置相邻的间距求是否发生心率不齐。
import scipy.io
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
def detect_afib(rr_intervals, threshold=5):
"""
判断给定RR间期是否存在房颤。
Args:
rr_intervals (list): RR间期列表,以秒为单位。
threshold (float): 标准差阈值,用于判断是否存在房颤。默认值为0.14秒。
Returns:
int: 如果存在房颤,则返回1;否则返回0。
"""
sdnn = np.std(rr_intervals)
if sdnn > threshold:
return 1
else:
return 0
def normalized(x):
y = x - np.mean(x) # 消除直流分量
y = y / np.max(np.abs(y)) # 幅值归一化
return (y)
# 读取.mat文件
mat = scipy.io.loadmat(r'C:\AF014.mat') # ECG信号
# 获取ECG信号数据
ecg_datas = mat['ECG014']
# 计算信号长度和采样率
signal_length = len(ecg_datas)
fs = 200
# 定义30秒的样本数
num_samples_30s = int(fs * 30)
# 计算可以分成多少个30秒的片段
num_segments = int(np.floor(signal_length / num_samples_30s))
# 滑动窗口
window_size = 100
threshold = 200
labels = []
# 分割ECG信号为30秒的片段
for i in range(num_segments):
start_idx = i * num_samples_30s
end_idx = start_idx + num_samples_30s
ecg_segment = ecg_datas[start_idx:end_idx]
# ecg_data = normalized(ecg_segment)
ecg_data = ecg_segment
peaks = []
for i in range(0, len(ecg_data) - window_size, window_size):
window = ecg_data[i:i + window_size]
if np.max(window) > threshold:
max_pos = np.argmax(window)
peak_pos = i + max_pos
peaks.append(peak_pos)
rr_intervals = np.diff(peaks)
rr_intervals = [interval for interval in rr_intervals if interval >= 50]
# 在这里,您可以对每个30秒的ECG片段执行您的操作,例如进行分类或分析等。
# label = detect_afib(ecg_data)
# print(label) # 输出0,因为RR间期的标准差是经验值,自己设置。
# 计算标准差
std_rr_intervals = np.std(rr_intervals)
# 判断标签
if std_rr_intervals < 10:
label = 0
else:
label = 1
labels.append(label)
# # 创建一个x轴时间序列
time = [i for i in range(len(ecg_data))]
# 绘制心电信号
plt.plot(time, ecg_data)
# 添加标题和轴标签
plt.title('ECG Signal')
plt.xlabel('Time (samples)')
plt.ylabel('Amplitude (mV)')
# 显示图形
plt.show()
print(label)
# 将每个片段的标签放入一个名为labels的列表中
# 将数据转换为数据框
data = pd.DataFrame({'label': labels})
# 将数据写入Excel文件
data.to_excel('C:/yolov5-heart/labels.xlsx', index=False)