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();
};

下一步