본문 바로가기
Python Library/HeartPy

[HeartPy] ECG 신호 분석

by goatlab 2022. 8. 24.
728x90
반응형
SMALL

ECG 신호 분석

 

data.zip
0.08MB

# import packages
import heartpy as hp
import matplotlib.pyplot as plt

sample_rate = 250

data = hp.get_data('e0103.csv')

plt.figure(figsize=(12,4))
plt.plot(data)
plt.show()

 

이것은 매우 좋고 깨끗한 신호이다. 사전 처리를 수행할 필요가 없으며 즉시 분석을 실행할 수 있다.

 

# run analysis
wd, m = hp.process(data, sample_rate)

# visualise in plot of custom size
plt.figure(figsize=(12,4))
hp.plotter(wd, m)

# display computed measures
for measure in m.keys():
    print('%s: %f' %(measure, m[measure]))

bpm: 59.697000
ibi: 1005.075630
sdnn: 45.612021
sdsd: 17.278462
rmssd: 30.487563
pnn20: 0.483051
pnn50: 0.118644
hr_mad: 28.000000
sd1: 21.545153
sd2: 59.911382
s: 4055.167506
sd1/sd2: 0.359617
breathingrate: 0.166667
data = hp.get_data('e0110.csv')

plt.figure(figsize=(12,4))
plt.plot(data)
plt.show()

# and zoom in a bit
plt.figure(figsize=(12,4))
plt.plot(data[0:2500])
plt.show()

 

T파 (주 QRS 복합체의 바로 뒤에 있는 넓은 파동)가 존재하는 문제가 있다. QRS 완료에 관심이 있기 때문에 노치 필터를 사용하여 필터링할 수 있다.

노치 필터는 매우 좁은 주파수 범위에 주파수 필터를 적용하여 QRS 복합체를 방해하지 않고 일부 사항을 제거할 수 있도록 한다.

 

filtered = hp.filter_signal(data, cutoff = 0.05, sample_rate = sample_rate, filtertype='notch')

# visualize again
plt.figure(figsize=(12,4))
plt.plot(filtered)
plt.show()

# and zoom in a bit
plt.figure(figsize=(12,4))
plt.plot(data[0:2500], label = 'original signal')
plt.plot(filtered[0:2500], alpha=0.5, label = 'filtered signal')
plt.legend()
plt.show()

# run analysis
wd, m = hp.process(hp.scale_data(filtered), sample_rate)

# visualise in plot of custom size
plt.figure(figsize=(12,4))
hp.plotter(wd, m)

# display computed measures
for measure in m.keys():
    print('%s: %f' %(measure, m[measure]))

bpm: 57.843015
ibi: 1037.290323
sdnn: 60.906871
sdsd: 20.513036
rmssd: 33.059617
pnn20: 0.493827
pnn50: 0.135802
hr_mad: 36.000000
sd1: 23.285718
sd2: 84.305770
s: 6167.324586
sd1/sd2: 0.276206
breathingrate: 0.075000

 

HeartPy는 일부 peak를 불신하고 있다. 이는 HeartPy의 옵티마이저가 일부 ECG 녹음이 제공하는 것보다 더 넓은 피크를 좋아하기 때문이다 (특히, 더 낮은 샘플링 속도). 일반적으로 필터링할 때 피크 너비도 감소하여 문제가 발생할 수 있다.

해결책은 간단하다. scipy.signal.resample을 사용하여 신호를 업샘플링할 수 있다.

 

from scipy.signal import resample

# resample the data. Usually 2, 4, or 6 times is enough depending on original sampling rate
resampled_data = resample(filtered, len(filtered) * 2)

# And run the analysis again. Don't forget to up the sample rate as well!
wd, m = hp.process(hp.scale_data(resampled_data), sample_rate * 2)

# visualise in plot of custom size
plt.figure(figsize=(12,4))
hp.plotter(wd, m)

# display computed measures
for measure in m.keys():
    print('%s: %f' %(measure, m[measure]))

bpm: 58.018220
ibi: 1034.157895
sdnn: 59.536305
sdsd: 21.549303
rmssd: 34.825073
pnn20: 0.544643
pnn50: 0.133929
hr_mad: 35.000000
sd1: 24.588644
sd2: 80.051446
s: 6183.774312
sd1/sd2: 0.307161
breathingrate: 0.116667

 

신호를 업샘플링하면 HeartPy가 신호의 모든 피크를 최적화하고 위치를 찾을 수 있다. 처리 함수에서 hp.scale_data()를 사용한다. 진폭이 낮을 때 (원래 데이터의 경우 2.4 ~ 3.8) 권장된다.

 

data = hp.get_data('e0124.csv')

plt.figure(figsize=(12,4))
plt.plot(data)
plt.show()

# and zoom in a bit
plt.figure(figsize=(12,4))
plt.plot(data[0:2500])
plt.show()

# run analysis
wd, m = hp.process(hp.scale_data(data), sample_rate)

# visualise in plot of custom size
plt.figure(figsize=(12,4))
hp.plotter(wd, m)

# display computed measures
for measure in m.keys():
    print('%s: %f' %(measure, m[measure]))

bpm: 74.642232
ibi: 803.834483
sdnn: 25.854237
sdsd: 8.060314
rmssd: 13.118076
pnn20: 0.104895
pnn50: 0.000000
hr_mad: 16.000000
sd1: 9.272843
sd2: 35.470837
s: 1033.318549
sd1/sd2: 0.261422
breathingrate: 0.175000

 

그리고  '신뢰할 수 없는' 피크를 적당한 업샘플링으로 고칠 수 있다.

 

# resample the data. Usually 2, 4, or 6 times is enough depending on original sampling rate
resampled_data = resample(data, len(filtered) * 2)

# And run the analysis again. Don't forget to up the sample rate as well!
wd, m = hp.process(hp.scale_data(resampled_data), sample_rate * 2)

# visualise in plot of custom size
plt.figure(figsize=(12,4))
hp.plotter(wd, m)

# display computed measures
for measure in m.keys():
    print('%s: %f' %(measure, m[measure]))

bpm: 74.700944
ibi: 803.202703
sdnn: 25.987252
sdsd: 8.037765
rmssd: 13.000262
pnn20: 0.095238
pnn50: 0.000000
hr_mad: 14.000000
sd1: 9.192447
sd2: 35.707405
s: 1031.191456
sd1/sd2: 0.257438
breathingrate: 0.125000

 

HeartPy에는 Poincare 비선형 방법도 포함되어 있다.

 

hp.plot_poincare(wd, m)

# print poincare measures
poincare_measures = ['sd1', 'sd2', 's', 'sd1/sd2']
print('\nnonlinear poincare measures:')
for measure in poincare_measures:
    print('%s: %f' %(measure, m[measure]))

 

nonlinear poincare measures:
sd1: 9.192447
sd2: 35.707405
s: 1031.191456
sd1/sd2: 0.257438

 

https://github.com/paulvangentcom/heartrate_analysis_python/blob/master/examples/2_regular_ECG/Analysing_a_regular_ECG_signal.ipynb

 

GitHub - paulvangentcom/heartrate_analysis_python: Python Heart Rate Analysis Package, for both PPG and ECG signals

Python Heart Rate Analysis Package, for both PPG and ECG signals - GitHub - paulvangentcom/heartrate_analysis_python: Python Heart Rate Analysis Package, for both PPG and ECG signals

github.com

 

728x90
반응형
LIST