使用Pan-Tompkins算法等QRS波群检测算法来识别QRS波群,并确定R峰的位置。代码
时间: 2024-03-03 21:51:36 浏览: 342
以下是使用Python实现Pan-Tompkins算法进行QRS波群检测的示例代码:
```python
import numpy as np
import matplotlib.pyplot as plt
# 心电信号预处理
def preprocess(signal, fs):
# 对信号进行低通滤波,去除高频噪声
b, a = signal.butter(4, 20 / (fs / 2), 'low')
signal = signal.filtfilt(b, a, signal)
# 对信号进行高通滤波,去除低频漂移
b, a = signal.butter(4, 0.5 / (fs / 2), 'high')
signal = signal.filtfilt(b, a, signal)
# 对信号进行移动平均滤波,降低噪声干扰
window_size = int(0.08 * fs)
signal = np.convolve(signal, np.ones((window_size,)) / window_size, mode='same')
return signal
# 求取信号的一阶差分和二阶差分
def diff(signal):
diff1 = np.diff(signal)
diff2 = np.diff(diff1)
return diff1, diff2
# 计算信号的移动平均值
def moving_average(signal, window_size):
window = np.ones(window_size) / window_size
return np.convolve(signal, window, mode='same')
# 对信号进行带通滤波
def bandpass_filter(signal, lowcut, highcut, fs, order=4):
nyquist_freq = 0.5 * fs
low = lowcut / nyquist_freq
high = highcut / nyquist_freq
b, a = signal.butter(order, [low, high], btype='band')
y = signal.filtfilt(b, a, signal)
return y
# 检测QRS波群的起始点和结束点
def detect_qrs(signal, fs):
# 设置参数
threshold1 = 0.3
threshold2 = 0.6
refractory_period = int(0.2 * fs)
# 计算移动平均值
ma_signal = moving_average(signal, int(0.08 * fs))
# 计算一阶差分和二阶差分
diff1, diff2 = diff(ma_signal)
# 对信号进行带通滤波
filtered_signal = bandpass_filter(signal, 5, 15, fs)
# 计算能量
energy = np.square(filtered_signal)
# 计算阈值
threshold = threshold1 * np.max(energy)
# 检测QRS波群的起始点和结束点
qrs_start = []
qrs_end = []
refractory_counter = 0
for i in range(len(energy)):
if energy[i] > threshold and refractory_counter == 0:
qrs_start.append(i)
refractory_counter = refractory_period
elif energy[i] < threshold2 * threshold and refractory_counter > 0:
refractory_counter -= 1
elif energy[i] > threshold2 * threshold and refractory_counter > 0:
qrs_end.append(i)
refractory_counter = refractory_period
# 对QRS波群的起始点和结束点进行校正
for i in range(len(qrs_start)):
j = qrs_start[i] + np.argmax(diff2[qrs_start[i]:qrs_end[i]]) + 1
qrs_start[i] = j - np.argmax(diff1[j:qrs_end[i]])
return qrs_start
# 定位R峰的位置
def locate_r_peak(signal, qrs_start, fs):
r_peak = []
window_size = int(0.1 * fs)
for i in range(len(qrs_start)):
j = qrs_start[i] + np.argmax(signal[qrs_start[i]:qrs_start[i]+window_size])
r_peak.append(j)
return r_peak
# 读取心电信号
fs = 360
data = np.loadtxt('ecg_signal.txt')
signal = data[:, 1]
# 心电信号预处理
signal = preprocess(signal, fs)
# 检测QRS波群的起始点
qrs_start = detect_qrs(signal, fs)
# 定位R峰的位置
r_peak = locate_r_peak(signal, qrs_start, fs)
# 绘制心电图和R峰位置
t = np.arange(len(signal)) / fs
plt.plot(t, signal)
plt.plot(t[r_peak], signal[r_peak], 'ro')
plt.xlabel('Time (s)')
plt.ylabel('Amplitude (mV)')
plt.show()
```
这段代码假设读取的心电信号数据保存在文件`ecg_signal.txt`中,每行包含时间和电压两个数据。在实际使用时,需要根据数据的格式进行修改。
阅读全文