손가락 덮임이 안정되면 바로 BPM을 계산하고 싶어집니다. 저도 처음에는 그렇게 했습니다. 숫자는 나왔지만, 숫자가 나온다는 것과 측정할 만한 신호라는 것은 다릅니다.

통과한 프레임마다 빨간색 강도 하나와 타임스탬프 하나가 들어옵니다. 이 단계의 처리는 이 시계열을 더 정직하게 만드는 과정입니다.
This diagram could not be rendered. Its source is still available below.
View diagram source
flowchart LR
A[통과한 카메라 프레임] --> B[빨간색 강도 샘플]
B --> C[타임스탬프 버퍼]
C --> D[기준선 드리프트 제거]
D --> E[고주파 노이즈 평활화]
E --> F[정규화 파형]
F --> G[피크 검출]
원시 빨간 값만으로는 부족하다
손끝은 실험 장비에 고정되어 있지 않습니다. 사용자는 조금 세게 누르다가 힘을 뺍니다. 플래시는 피부를 데우고, 노출은 안정화되며, 손은 아주 조금 움직입니다. 이 모든 것이 빨간 값에 느린 변화를 만듭니다.
30 fps만 믿지 않는다
30 fps라고 가정하고 샘플 인덱스를 시간으로 바꾸는 방법은 쉽습니다. 하지만 실제 기기는 프레임을 놓치고, 처리 큐는 늦은 프레임을 버릴 수 있습니다. MonoPump는 각 샘플의 presentation timestamp를 보관합니다.
This diagram could not be rendered. Its source is still available below.
View diagram source
sequenceDiagram
participant C as Camera
participant B as Buffer
participant P as Preprocessor
C->>B: t0 값
C->>B: t1 값
C->>B: t2 값
B->>P: 값 + 타임스탬프
P->>P: 실제 샘플링 속도 추정
BPM은 시간 측정입니다. 배열 인덱스 측정이 아닙니다.
디트렌딩과 가벼운 평활화
맥박은 비교적 빠른 진동입니다. 손가락 압력과 노출 드리프트는 더 느립니다. MonoPump는 국소 이동 평균을 기준선으로 삼아 빼고, 가벼운 이동 평균으로 노이즈를 줄입니다.
detrended[i] = signal[i] - average(signal around i)
This diagram could not be rendered. Its source is still available below.
View diagram source
flowchart TD
R[원시 빨간 시계열] --> D[국소 기준선 제거]
D --> S[3점 이동 평균]
S --> N[정규화]
N --> W[UI 파형]
N --> P[피크 검출 입력]
예쁜 파형을 너무 믿으면 안 됩니다. 목표는 보기 좋은 애니메이션이 아니라 타이밍을 보존하는 것입니다.