모든 글

【TECH】박동 세기: 피크 검출과 BPM 추정

MonoPump가 정리된 PPG 파형을 피크 간격, 타임스탬프, 이상치 필터링, EMA 평활화로 BPM으로 바꾸는 방법입니다.

BPM피크 검출PPG알고리즘
【TECH】박동 세기: 피크 검출과 BPM 추정

정리된 파형은 보기 좋지만, 사용자가 알고 싶은 것은 결국 하나입니다. 지금 심박수가 얼마인가. 답은 피크의 높이에 있지 않습니다. 피크와 피크 사이의 거리에 있습니다.

건강 앱 화면의 맥파와 강조된 피크 지점
BPM은 파형의 높이가 아니라 피크 사이의 시간 거리에서 나옵니다.

MonoPump의 방법은 일부러 단순합니다. 그럴듯한 피크를 찾고, 타임스탬프로 간격을 재고, 의심스러운 간격을 제거하고, 초를 BPM으로 바꾼 뒤, UI가 흔들리지 않도록 평활화합니다.

Flow diagram Preparing diagram
View diagram source
flowchart LR
    A[정리된 PPG 윈도우] --> B[적응형 피크 임계값]
    B --> C[국소 최대값]
    C --> D[피크 간격 목록]
    D --> E[중앙값 기반 이상치 필터]
    E --> F[BPM = 60 / 평균 간격]
    F --> G[EMA 평활화]

왜 FFT부터 쓰지 않았나

FFT는 아름다운 모델을 줍니다. 맥박 대역에서 가장 강한 주파수를 찾고 BPM으로 바꾸면 됩니다. 하지만 모바일 카메라의 짧고 지저분한 윈도우에서는 그 우아함이 항상 이기지 않습니다. 움직임, 프레임 누락, 접촉 불안정이 있으면 잘못된 주파수가 자신 있어 보일 수 있습니다.

피크 검출은 화려하지 않지만 디버깅하기 쉽습니다. 추정이 틀리면 피크와 간격을 직접 볼 수 있습니다.

피크는 시간 표식이다

MonoPump는 적응형 임계값을 넘는 국소 최대값을 찾습니다. 동시에 한 번의 박동이 여러 작은 피크로 쪼개지지 않도록 피크 사이 최소 거리를 둡니다.

minPeakDistance = sampleRate * 60 / maxBPM
threshold = mean + 0.5 * standardDeviation

고정 임계값은 신호 크기가 안정적일 때만 좋습니다. 카메라 PPG의 진폭은 충분히 예측 가능하지 않기 때문에 윈도우마다 임계값을 맞춥니다.

Flow diagram Preparing diagram
View diagram source
flowchart TD
    P1[t1 피크] --> I1[t2 - t1]
    P2[t2 피크] --> I2[t3 - t2]
    P3[t3 피크] --> I3[t4 - t3]
    I1 --> M[중앙값 간격]
    I2 --> M
    I3 --> M
    M --> F[너무 벗어난 간격 제거]

숫자를 안정시키되 숨기지 않는다

원시 BPM은 업데이트마다 흔들립니다. 모두 보여 주면 앱이 불안해 보입니다. 반대로 숫자를 너무 고정하면 가짜처럼 느껴집니다. MonoPump는 EMA를 쓰고 업데이트마다 변할 수 있는 폭도 제한합니다.

smoothed = 0.35 * current + 0.65 * previous
smoothed = clamp(smoothed, previous - maxDelta, previous + maxDelta)

신뢰도는 장식이 아닙니다. 사용 가능한 피크 간격 수와 최근 신호 변화가 최종 결과의 문지기 역할을 합니다. 숫자를 출력하는 것은 쉽습니다. 출력하지 않을 때를 아는 것이 더 어렵습니다.

MonoWare에서

MonoPump에는 이 노트의 더 많은 맥락이 있습니다.

제품 사이트를 열거나 MonoPump로 필터된 노트를 계속 읽으세요.

뉴스레터

개인정보와 제품 엔지니어링 노트를 가끔 보내드립니다.