すべての記事

【TECH】カメラフレームから心拍信号を作る

赤チャンネルの列を、タイムスタンプ、トレンド除去、軽い平滑化、バッファリングで PPG 波形に変える流れです。

信号処理PPGSwiftカメラフレーム
【TECH】カメラフレームから心拍信号を作る

指の覆いが安定すると、すぐ BPM を計算したくなります。私も最初はそうしました。数字は出ます。ただし、数字が出ることと測る価値があることは別です。

赤いカメラフレームの列が脈波に変わっていく様子
採用された各フレームは、時刻付きの赤強度サンプルを 1 つ提供します。

採用された各フレームは、赤の強度値とタイムスタンプを 1 つずつ提供します。この段階の処理は、その列を正直な信号に近づけるためのものです。

Flow diagram Preparing diagram
View diagram source
flowchart LR
    A[採用されたカメラフレーム] --> B[赤強度サンプル]
    B --> C[タイムスタンプ付きバッファ]
    C --> D[ベースラインドリフトを除去]
    D --> E[高周波ノイズを軽く平滑化]
    E --> F[正規化波形]
    F --> G[ピーク検出]

生の赤値だけでは足りない

指先は実験器具で固定されていません。ユーザーは少し強く押し、またゆるめます。フラッシュで皮膚が温まり、露出が落ち着き、手が少し動きます。これらは赤値にゆっくりした変化を作ります。

30 fps を信じすぎない

30 fps と仮定してインデックスを時間に変換するのは簡単です。しかし実機ではフレーム落ちがあり、遅れたフレームは捨てられることもあります。MonoPump は各サンプルの presentation timestamp を保存します。

Sequence diagram Preparing diagram
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)
Flow diagram Preparing diagram
View diagram source
flowchart TD
    R[生の赤系列] --> D[局所基線を引く]
    D --> S[3 点移動平均]
    S --> N[正規化]
    N --> W[UI に表示する波形]
    N --> P[ピーク検出入力]

見た目のきれいな波形を信用しすぎない。目的は美しいアニメーションではなく、タイミングを守ることです。

MonoWare より

MonoPump にはこのノートの背景があります。

製品サイトを開くか、MonoPump のノートを続けて読めます。

ニュースレター

プライバシーと製品技術ノートを、ときどき送信します。