Skip to content

FDA 估算器

NOTE

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

概述

FDA 估算器是一個醫療級心率測量系統,使用進階訊號處理分析面部影片的光體積描記(PPG)訊號。它提供 FDA 級準確度,無需外部 AI 模型,非常適合醫療應用程式和即時初始化。

IMPORTANT

專有技術 FDA 估算器是 PanopticAI 開發的專有軟體。核心演算法在 WebAssembly 中執行以保護智慧財產權。

主要特點

  • 醫療級:FDA 級準確度
  • 即時初始化:無需模型載入
  • 零依賴:無需外部檔案
  • 確定性:相同輸入 → 相同輸出
  • 輕量級:< 200 KB 記憶體佔用
  • 自適應:5 秒內早期結果,10 秒內最佳

基本用法

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

const camera = createVitalSignCamera({
  realtimeEstimationConfig: {
    estimatorType: RealtimeEstimatorType.Fda,
    earlyEstimation: true,
    minDuration: 10,
    minConfidence: 0.6
  }
});

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

配置

適用於消費者應用程式

typescript
{
  estimatorType: RealtimeEstimatorType.Fda,
  earlyEstimation: true,   // 顯示早期結果
  minDuration: 5,          // 更快回饋
  minConfidence: 0.4,      // 較低閾值
  debug: false
}

適用於醫療應用程式

typescript
{
  estimatorType: RealtimeEstimatorType.Fda,
  earlyEstimation: false,  // 等待完整準確度
  minDuration: 10,         // 完整 10 秒
  minConfidence: 0.7,      // 高信心度閾值
  debug: false
}

SDK 行為

初始化

typescript
// FDA 估算器即時初始化(無非同步載入)
const camera = createVitalSignCamera({
  realtimeEstimationConfig: {
    estimatorType: RealtimeEstimatorType.Fda
  }
});

// 立即就緒 - 無需等待
camera.startScan();

處理時間軸

0秒 ────► 5秒 ────► 10秒 ────► 30秒
│        │        │         │
│        │        │         └─ 掃描完成
│        │        └─ 最佳準確度(10秒視窗)
│        └─ 首次估算(5秒視窗)
└─ 掃描開始(即時初始化)

自適應時間視窗

FDA 估算器使用自適應時間視窗,隨著更多資料到達而增長:

經過時間視窗大小準確度狀態
5 秒5秒±5-8 BPM早期估算
7 秒7秒±3-5 BPM改善中
10+ 秒10秒±2-3 BPM最佳 ✓
typescript
camera.onVideoFrameProcessed = (event) => {
  const estimation = event.realtimeEstimation;
  if (!estimation) return;
  
  const elapsed = getCurrentScanTime();
  
  if (elapsed < 7) {
    showHeartRate(estimation.heartRate, '早期估算');
  } else if (elapsed < 10) {
    showHeartRate(estimation.heartRate, '精煉中...');
  } else {
    showHeartRate(estimation.heartRate, '穩定 ✓');
  }
};

效能特性

指標
初始化即時(< 10毫秒)
首次結果約 5 秒
最佳準確度約 10 秒
處理速度每幀 5-10 毫秒
記憶體使用< 200 KB
套件大小約 100 KB(WASM)
典型誤差±2-3 BPM
心率範圍50-140 BPM

品質指標

訊噪比(SNR)

FDA 估算器提供 SNR 值以指示訊號品質:

SNR信心度品質解釋
10+1.0優秀完全信任 ✓
8-100.8-1.0非常好高度可靠 ✓
6-80.6-0.8良好可靠
4-60.4-0.6尚可可接受
2-40.2-0.4考慮重試
< 20.0-0.2非常差需要重試
typescript
camera.onVideoFrameProcessed = (event) => {
  const estimation = event.realtimeEstimation;
  if (!estimation) return;
  
  if (estimation.snr && estimation.snr > 6) {
    showQualityIndicator('優秀');
  } else if (estimation.snr && estimation.snr > 4) {
    showQualityIndicator('良好');
  } else {
    showQualityIndicator('差');
    showTip('改善光線或減少移動');
  }
};

優勢

🏥 醫療級品質

  • FDA 級準確度
  • 符合已驗證的伺服器實作
  • 適合醫療應用程式
  • 有利於法規合規

📦 零依賴

  • 無需下載模型檔案
  • 即時初始化
  • 立即離線運作
  • 較小的套件大小

⚡ 快速初始化

  • 無需非同步載入
  • 立即可用
  • 無需等待模型
  • 更簡單的錯誤處理

🔒 智慧財產權保護

  • WebAssembly 中的核心演算法
  • 保護專有實作
  • 二進位格式防止逆向工程

🎯 確定性

  • 相同輸入 → 相同輸出
  • 無 AI 隨機性
  • 可重現結果
  • 更易於除錯

何時使用

✅ 最適合

  • 醫療和健康照護應用程式
  • 法規合規要求
  • 需要即時初始化
  • 需要最小套件大小
  • 離線優先應用程式
  • 嵌入式系統和物聯網裝置

❌ 避免使用

  • 使用者會大幅移動
  • 光線條件不受控制
  • 需要最大動作容忍度
  • 需要開源授權
  • 偏好 AI 驅動功能

疑難排解

低信心度分數

症狀:信心度 < 0.6,讀數不穩定

解決方案

typescript
// 1. 改善環境條件
const instructions = [
  "使用自然日光",
  "避免背光",
  "確保均勻照明",
  "移除臉部陰影"
];

// 2. 減少動作
const motionTips = [
  "保持完全靜止",
  "測量期間不要說話",
  "如果可能使用手機支架",
  "保持穩定距離"
];

// 3. 等待更長時間
{
  minDuration: 10,  // 允許完整 10 秒視窗
  minConfidence: 0.6
}

// 4. 檢查人臉偵測 - 注意:人臉偵測事件因 SDK 而異
// 對於網頁 SDK,檢查 VideoFrameProcessedEvent 中的 scanConditions
camera.onVideoFrameProcessed = (event) => {
  if (event.scanConditions && !event.scanConditions.centered) {
    showWarning('保持臉部居中且穩定');
  }
};

不穩定讀數

症狀:心率跳動

解決方案

typescript
// 增加最小信心度閾值
{
  minConfidence: 0.7  // 更高閾值以獲得穩定性
}

// 等待完整視窗
{
  earlyEstimation: false,  // 停用早期結果
  minDuration: 10
}

// 引導使用者
camera.onVideoFrameProcessed = (event) => {
  const estimation = event.realtimeEstimation;
  if (!estimation) return;
  
  if (estimation.confidence < 0.6) {
    showTip('請保持靜止並改善光線');
  }
};

最佳實踐

1. 漸進式回饋

typescript
camera.onVideoFrameProcessed = (event) => {
  const estimation = event.realtimeEstimation;
  if (!estimation) return;
  
  const elapsed = getCurrentScanTime();
  
  if (elapsed < 5) {
    showMessage("分析中... 請保持靜止");
  } else if (elapsed < 10) {
    if (estimation.confidence > 0.4) {
      showHeartRate(estimation.heartRate, "精煉中...");
    } else {
      showMessage("調整中... 如果可能請改善光線");
    }
  } else {
    if (estimation.isStable) {
      showHeartRate(estimation.heartRate, "穩定 ✓");
    } else {
      showMessage("信心度低。在更好的條件下重試。");
    }
  }
};

2. 品質指示器

typescript
function getQualityIndicator(estimation: RealtimeEstimation): string {
  if (estimation.confidence >= 0.8) return "優秀 ⭐⭐⭐⭐⭐";
  if (estimation.confidence >= 0.6) return "非常好 ⭐⭐⭐⭐";
  if (estimation.confidence >= 0.4) return "良好 ⭐⭐⭐";
  if (estimation.confidence >= 0.2) return "尚可 ⭐⭐";
  return "差 ⭐";
}

camera.onVideoFrameProcessed = (event) => {
  const estimation = event.realtimeEstimation;
  if (!estimation) return;
  
  updateQualityDisplay(getQualityIndicator(estimation));
};

3. 重試邏輯

typescript
let retryCount = 0;
const MAX_RETRIES = 3;

camera.onVideoFrameProcessed = (event) => {
  const result = event.healthResult;
  if (!result) return;
  
  if (result.confidence < 0.6 && retryCount < MAX_RETRIES) {
    retryCount++;
    showMessage(`信心度低。重試中(${retryCount}/${MAX_RETRIES})...`);
    camera.reset();
    camera.startScan();
  } else {
    retryCount = 0;
    displayFinalResult(result);
  }
};

4. 使用者指導

typescript
const guidanceMessages = {
  lowConfidence: "改善光線或保持靜止",
  noFace: "將您的臉部置於中央",
  unstable: "保持您的臉部穩定",
  success: "測量完成 ✓"
};

camera.onVideoFrameProcessed = (event) => {
  const estimation = event.realtimeEstimation;
  if (!estimation) return;
  
  if (estimation.confidence < 0.4) {
    showGuidance(guidanceMessages.lowConfidence);
  } else if (estimation.isStable) {
    showGuidance(guidanceMessages.success);
  }
};

與 ME-rPPG 估算器比較

特點FDAME-rPPG
準確度⭐⭐⭐⭐⭐ 醫療級⭐⭐⭐⭐⭐ 最先進
動作容忍度⭐⭐⭐⭐ 良好⭐⭐⭐⭐⭐ 優秀
光線容忍度⭐⭐⭐⭐ 良好⭐⭐⭐⭐⭐ 優秀
初始化⭐⭐⭐⭐⭐ 即時⭐⭐⭐ (1-2秒)
套件大小⭐⭐⭐⭐⭐ 約100 KB⭐⭐⭐ 約10 MB
記憶體使用⭐⭐⭐⭐⭐ < 200 KB⭐⭐⭐ 約4 MB
授權專有開源
首次結果約 5 秒約 3 秒
最適合醫療應用,嵌入式消費者應用,挑戰性條件

範例:完整實作

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

// 使用 FDA 估算器建立相機
const camera = createVitalSignCamera({
  realtimeEstimationConfig: {
    estimatorType: RealtimeEstimatorType.Fda,
    earlyEstimation: true,
    minDuration: 10,
    minConfidence: 0.6,
    debug: false
  }
});

// FDA 立即就緒(無非同步載入)
document.getElementById('start-btn').disabled = false;

// 處理即時更新
camera.onVideoFrameProcessed = (event) => {
  const estimation = event.realtimeEstimation;
  if (!estimation) return;
  
  updateHeartRateDisplay(estimation.heartRate);
  updateConfidenceBar(estimation.confidence);
  
  // 如果可用則顯示 SNR
  if (estimation.snr) {
    updateSNRDisplay(estimation.snr);
  }
  
  // 品質指示器
  if (estimation.isStable && estimation.confidence > 0.7) {
    showQualityIndicator('優秀');
  } else if (estimation.confidence > 0.5) {
    showQualityIndicator('良好');
  } else {
    showQualityIndicator('差');
    showTip('改善光線或減少移動');
  }
};

// 檢查最終結果
let scanCompleted = false;
camera.onVideoFrameProcessed = (event) => {
  const results = event.healthResult;
  if (results && !scanCompleted) {
    scanCompleted = true;
    if (results.confidence > 0.7) {
      displayFinalResults(results);
    } else {
      showRetryOption();
    }
  }
};

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

範例:醫療應用程式

typescript
// 醫療級配置
const camera = createVitalSignCamera({
  realtimeEstimationConfig: {
    estimatorType: RealtimeEstimatorType.Fda,
    earlyEstimation: false,  // 等待完整準確度
    minDuration: 10,         // 完整 10 秒
    minConfidence: 0.7,      // 高閾值
    debug: false
  }
});

// 僅記錄高信心度測量
camera.onVideoFrameProcessed = (event) => {
  const estimation = event.realtimeEstimation;
  if (!estimation) return;
  
  if (estimation.isStable && estimation.confidence > 0.7) {
    recordMeasurement({
      heartRate: estimation.heartRate,
      confidence: estimation.confidence,
      snr: estimation.snr,
      timestamp: new Date()
    });
  }
};

// 儲存前驗證
let validationCompleted = false;
camera.onVideoFrameProcessed = (event) => {
  const results = event.healthResult;
  if (results && !validationCompleted) {
    validationCompleted = true;
    if (results.confidence > 0.7 && results.snr > 5) {
      saveMedicalRecord(results);
    } else {
      requestRetry('測量品質低於醫療閾值');
    }
  }
};

下一步