Skip to content

ME-rPPG 估算器

NOTE

僅限網頁 SDK 即時估算功能目前僅適用於網頁版 SDK(JavaScript、React、Vue)。不適用於行動裝置 SDK(iOS、Android、Flutter、React Native)。

概述

ME-rPPG(記憶體高效遠端光體積描記)估算器是一個 AI 驅動的心率測量系統,使用深度學習分析面部影片。它提供最先進的準確度,對動作和光線變化具有優秀的容忍度。

NOTE

開源技術 ME-rPPG 是開源軟體,可免費用於研究、開發和商業用途。

主要特點

  • AI 驅動:神經網路學習最佳訊號提取
  • 快速結果:約 3 秒內首次估算
  • 動作容忍:即使有輕微移動也能運作
  • 光線穩健:處理變化的光線條件
  • 記憶體高效:僅 3.6 MB 執行時記憶體
  • 開源:可自由使用和修改

基本用法

typescript
import { createVitalSignCamera, RealtimeEstimatorType } from 'ts-vital-sign-camera';

const camera = createVitalSignCamera({
  realtimeEstimationConfig: {
    estimatorType: RealtimeEstimatorType.MeRppg,
    earlyEstimation: true,
    minDuration: 3,
    minConfidence: 0.3
  }
});

camera.onVideoFrameProcessed = (event) => {
  const estimation = event.realtimeEstimation;
  if (estimation) {
    console.log(`心率:${estimation.heartRate} BPM`);
    console.log(`信心度:${estimation.confidence}`);
  }
};

配置

基本配置

typescript
{
  estimatorType: RealtimeEstimatorType.MeRppg,
  earlyEstimation: true,    // 提早顯示結果
  minDuration: 3,           // 最少 3 秒
  minConfidence: 0.3,       // 早期結果的較低閾值
  debug: false              // 啟用以進行疑難排解
}

進階配置

typescript
{
  estimatorType: RealtimeEstimatorType.MeRppg,
  earlyEstimation: true,
  minDuration: 3,
  minConfidence: 0.3,
  
  // 自訂模型路徑(可選)
  modelPath: '/models/me-rppg/model.onnx',
  statePath: '/models/me-rppg/state.json',
  welchPath: '/models/me-rppg/welch_psd.onnx',
  hrPath: '/models/me-rppg/get_hr.onnx',
  
  // 時間正規化的 Lambda 參數
  lambda: 1.0  // 預設:1.0 秒半衰期
}

Lambda 參數

控制估算器適應變化的速度:

行為使用案例
0.33快速適應快速回應心率變化
1.0預設平衡效能
3.0慢速適應最大穩定性
typescript
// 適用於健身應用程式(快速回應)
{ lambda: 0.33 }

// 適用於醫療應用程式(最大穩定性)
{ lambda: 3.0 }

模型設定

1. 模型檔案

確保以下檔案可用:

/public/models/me-rppg/
├── model.onnx        (2.5 MB)  - 主要 ME-rPPG 模型
├── state.json        (7 MB)    - 初始時間狀態
├── welch_psd.onnx    (93 KB)   - Welch PSD 模型
└── get_hr.onnx       (1.5 KB)  - 心率提取模型

2. 伺服器配置

確保您的網頁伺服器正確提供 ONNX 檔案:

nginx
# Nginx 範例
location /models/ {
    types {
        application/octet-stream onnx;
    }
    add_header Access-Control-Allow-Origin *;
}

3. 驗證載入

啟用除錯模式以檢查模型載入:

typescript
const camera = createVitalSignCamera({
  realtimeEstimationConfig: {
    estimatorType: RealtimeEstimatorType.MeRppg,
    debug: true  // 檢查控制台的載入訊息
  }
});

SDK 行為

初始化

typescript
// 模型非同步載入(1-2 秒)
const camera = createVitalSignCamera({
  realtimeEstimationConfig: {
    estimatorType: RealtimeEstimatorType.MeRppg
  }
});

// 等待就緒事件
camera.onInitialized = () => {
  console.log('ME-rPPG 模型已載入');
  enableStartButton();
};

處理時間軸

0秒 ────► 1-2秒 ────► 3秒 ────► 10秒 ────► 30秒
│        │          │        │         │
│        │          │        │         └─ 掃描完成
│        │          │        └─ 最佳準確度
│        │          └─ 首次估算
│        └─ 模型已載入
└─ 掃描開始

估算更新

typescript
camera.onVideoFrameProcessed = (event) => {
  const estimation = event.realtimeEstimation;
  if (!estimation) return;
  
  const elapsed = getCurrentScanTime();
  
  if (elapsed < 5) {
    // 早期估算(較低信心度)
    showHeartRate(estimation.heartRate, '分析中...');
  } else if (elapsed < 10) {
    // 改善估算
    showHeartRate(estimation.heartRate, '精煉中...');
  } else {
    // 穩定估算
    showHeartRate(estimation.heartRate, '穩定 ✓');
  }
};

效能特性

指標
首次結果約 3 秒
最佳準確度約 10 秒
處理速度每幀 10-30 毫秒
記憶體使用約 4 MB 執行時
模型大小總共約 10 MB
典型誤差±2-3 BPM
心率範圍40-180 BPM

優勢

🎯 卓越準確度

  • 最先進的神經網路
  • 學習最佳訊號提取
  • 對個體變異穩健

🏃 動作容忍度

  • AI 學習忽略動作偽影
  • 對穩定區域的空間注意力
  • 時間記憶維持連續性

💡 光線穩健性

  • 在多樣光線條件下訓練
  • 自適應正規化
  • 在明亮和昏暗環境中運作

⚡ 低延遲

  • 以 30 FPS 即時處理
  • Web Worker 防止 UI 阻塞
  • 快速初始結果

何時使用

✅ 最適合

  • 消費者健身和健康應用程式
  • 具有變化光線的應用程式
  • 使用者移動的場景
  • 具有良好連線的現代裝置
  • 需要開源授權的專案

❌ 避免使用

  • 即時初始化至關重要
  • 套件大小必須最小(< 1 MB)
  • 立即需要離線優先
  • 目標裝置記憶體有限
  • 網路連線緩慢很常見

疑難排解

模型未載入

症狀:無心率估算,控制台錯誤

解決方案

typescript
// 1. 啟用除錯模式
const camera = createVitalSignCamera({
  realtimeEstimationConfig: {
    estimatorType: RealtimeEstimatorType.MeRppg,
    debug: true  // 檢查控制台
  }
});

// 2. 使用絕對路徑
{
  modelPath: '/models/me-rppg/model.onnx',  // 非相對路徑
  // ...
}

// 3. 檢查 CORS 標頭
// 確保伺服器允許跨來源請求

// 4. 驗證檔案可訪問性
// 在瀏覽器中直接開啟模型 URL

低信心度分數

症狀:信心度 < 0.3

解決方案

  1. 改善光線(自然光最佳)
  2. 確保人臉居中且穩定
  3. 等待完整 10 秒
  4. 減少動作和說話
  5. 檢查人臉偵測是否穩定

不穩定讀數

症狀:心率大幅跳動

解決方案

typescript
// 增加 lambda 以獲得更多穩定性
{
  lambda: 3.0  // 較慢適應,更穩定
}

// 增加最小信心度
{
  minConfidence: 0.5  // 更高閾值
}

最佳實踐

1. 漸進式回饋

typescript
camera.onVideoFrameProcessed = (event) => {
  const estimation = event.realtimeEstimation;
  if (!estimation) return;
  
  if (estimation.isStable && estimation.confidence > 0.6) {
    // 高信心度
    displayHeartRate(estimation.heartRate);
    showQualityIndicator('優秀');
  } else if (estimation.confidence > 0.3) {
    // 中等信心度
    displayHeartRate(estimation.heartRate, '精煉中...');
    showQualityIndicator('良好');
  } else {
    // 低信心度
    showMessage('調整中... 請保持靜止');
    showQualityIndicator('差');
  }
};

2. 錯誤處理

typescript
camera.onError = (error) => {
  if (error.message.includes('ONNX')) {
    showError('無法載入 AI 模型。請檢查您的連線。');
  } else {
    showError('發生錯誤。請重試。');
  }
};

3. 使用者指導

typescript
const instructions = [
  "將您的臉部置於中央",
  "保持靜止且不要說話",
  "確保良好光線",
  "等待穩定指示器"
];

showInstructions(instructions);

與 FDA 估算器比較

特點ME-rPPGFDA
準確度⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
動作容忍度⭐⭐⭐⭐⭐⭐⭐⭐⭐
光線容忍度⭐⭐⭐⭐⭐⭐⭐⭐⭐
初始化⭐⭐⭐ (1-2秒)⭐⭐⭐⭐⭐ (即時)
套件大小⭐⭐⭐ (約10 MB)⭐⭐⭐⭐⭐ (約100 KB)
授權⭐⭐⭐⭐⭐ (開源)⭐⭐⭐ (專有)
首次結果約 3 秒約 5 秒

範例:完整實作

typescript
import { createVitalSignCamera, RealtimeEstimatorType } from 'ts-vital-sign-camera';

// 使用 ME-rPPG 建立相機
const camera = createVitalSignCamera({
  realtimeEstimationConfig: {
    estimatorType: RealtimeEstimatorType.MeRppg,
    earlyEstimation: true,
    minDuration: 3,
    minConfidence: 0.3,
    lambda: 1.0,
    debug: false
  }
});

// 處理模型載入
camera.onInitialized = () => {
  console.log('ME-rPPG 就緒');
  document.getElementById('start-btn').disabled = false;
};

// 處理即時更新
camera.onVideoFrameProcessed = (event) => {
  const estimation = event.realtimeEstimation;
  if (!estimation) return;
  
  updateHeartRateDisplay(estimation.heartRate);
  updateConfidenceBar(estimation.confidence);
  
  if (estimation.isStable) {
    showStableIndicator();
  }
};

// 處理錯誤
camera.onError = (error) => {
  console.error('錯誤:', error);
  showErrorMessage(error.message);
};

// 開始掃描
document.getElementById('start-btn').onclick = () => {
  camera.startScan();
};

下一步