본문 바로가기
Python Library/HeartPy

[HeartPy] 스마트 워치 PPG 신호 분석 (2)

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

스마트 워치 PPG 신호 분석

 

# let's resample to ~100Hz as well
# 10Hz is low for the adaptive threshold analysis HeartPy uses
from scipy.signal import resample

resampled = resample(filtered, len(filtered) * 10)

# don't forget to compute the new sampling rate
new_sample_rate = sample_rate * 10

# run HeartPy over a few segments, fingers crossed, and plot results of each
for s in [[0, 10000], [10000, 20000], [20000, 30000], [30000, 40000], [40000, 50000]]:
    wd, m = hp.process(resampled[s[0]:s[1]], sample_rate = new_sample_rate, 
                       high_precision=True, clean_rr=True)
    hp.plotter(wd, m, title = 'zoomed in section', figsize=(12,6))
    hp.plot_poincare(wd, m)
    plt.show()
    for measure in m.keys():
        print('%s: %f' %(measure, m[measure]))

bpm: 79.359496
ibi: 756.053189
sdnn: 64.994392
sdsd: 47.662905
rmssd: 75.816447
pnn20: 0.687500
pnn50: 0.562500
hr_mad: 38.056933
sd1: 52.474660
sd2: 61.238831
s: 10095.466648
sd1/sd2: 0.856885
breathingrate: 0.166667

bpm: 76.276784
ibi: 786.608936
sdnn: 64.426442
sdsd: 33.842026
rmssd: 52.451344
pnn20: 0.706897
pnn50: 0.258621
hr_mad: 25.028467
sd1: 36.269742
sd2: 57.296852
s: 6528.675837
sd1/sd2: 0.633015
breathingrate: 0.233333

bpm: 80.140527
ibi: 748.684870
sdnn: 47.606192
sdsd: 21.648073
rmssd: 37.633326
pnn20: 0.646154
pnn50: 0.184615
hr_mad: 27.042700
sd1: 26.454880
sd2: 57.468399
s: 4776.224835
sd1/sd2: 0.460338
breathingrate: 0.200000

bpm: 77.007966
ibi: 779.140179
sdnn: 67.149279
sdsd: 26.025919
rmssd: 40.921120
pnn20: 0.620253
pnn50: 0.151899
hr_mad: 35.549817
sd1: 28.690814
sd2: 67.970221
s: 6126.485560
sd1/sd2: 0.422109
breathingrate: 0.266667

bpm: 74.808472
ibi: 802.048196
sdnn: 72.275896
sdsd: 19.707483
rmssd: 32.333149
pnn20: 0.514286
pnn50: 0.085714
hr_mad: 23.028467
sd1: 22.852642
sd2: 37.011862
s: 2657.218189
sd1/sd2: 0.617441
breathingrate: 0.266667

 

합리적인 결과인 것 같다. 지금까지 대부분의 피크가 올바르게 표시되었으며, 노이즈가 많은 구간 (저신뢰도)의 대부분의 피크는 간단히 거부된다.


clean_messages는 기본적으로 약간 공격적인 quotient-messages를 사용한다.

clean_rr_method 플래그로 'iqr' 또는 'z-score'를 설정할 수 있다.

마지막으로 신호 섹션을 추출하고 비신호 섹션을 자동으로 제외하는 방법도 있다.

 

raw = df['ppg'].values

plt.plot(raw)
plt.show()

import sys
from scipy.signal import resample

windowsize = 100
std = []

for i in range(len(raw) // windowsize):
    start = i * windowsize
    end = (i + 1) * windowsize
    sliced = raw[start:end]
    try:
        std.append(np.std(sliced))
    except:
        print(i)
    
plt.plot(std)
plt.show()

plt.plot(raw)
plt.show()

plt.plot(raw[0:(len(raw) // windowsize) * windowsize] - resample(std, len(std)*windowsize))
plt.show()

(len(raw) // windowsize) * windowsize
255300
mx = np.max(raw)
mn = np.min(raw)
global_range = mx - mn

windowsize = 100
filtered = []

for i in range(len(raw) // windowsize):
    start = i * windowsize
    end = (i + 1) * windowsize
    sliced = raw[start:end]
    rng = np.max(sliced) - np.min(sliced)
    
    if ((rng >= (0.5 * global_range)) 
        or 
        (np.max(sliced) >= 0.9 * mx) 
        or 
        (np.min(sliced) <= mn + (0.1 * mn))):
        
        for x in sliced:
            filtered.append(0)
    else:
        for x in sliced:
            filtered.append(x)
   
plt.figure(figsize=(12,6))
plt.plot(raw)
plt.show()

plt.figure(figsize=(12,6))
plt.plot(filtered)
plt.show()

 

빠르고 noise한 자동 추출 이를 위해 window 기능을 사용하고 각 window 테스트에 대해 다음을 수행한다.

 

Raw signal(원시 신호) 범위의 50% 이상의 범위를 갖는다.

최대값이 원시 신호 최대값의 90%이다.

최소값이 원시 신호의 최소값 + 10%이다.

 

https://github.com/paulvangentcom/heartrate_analysis_python/blob/master/examples/3_smartwatch_data/Analysing_Smartwatch_Data.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