Skip to content

Panoptic 估算器

NOTE

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

概述

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

IMPORTANT

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

主要特點

  • 醫療級:Panoptic 級準確度
  • 即時初始化:無需模型載入
  • 零依賴:無需外部檔案
  • 確定性:相同輸入 → 相同輸出
  • 輕量級:< 200 KB 記憶體佔用
  • 自適應:~8 秒內首次估算,~15 秒內最佳

基本用法

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

const camera = createVitalSignCamera({
  realtimeEstimationConfig: {
    estimatorType: RealtimeEstimatorType.Panoptic
  }
});

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

TIP

最簡設定:使用 enableRealtimeEstimation: true 即可啟用 Panoptic 估算器預設值 — 無需額外配置。

配置

適用於消費者應用程式

typescript
{
  estimatorType: RealtimeEstimatorType.Panoptic,
  debug: false
}

適用於醫療應用程式

typescript
{
  estimatorType: RealtimeEstimatorType.Panoptic,
  signalQualityDelay: 10,  // 延長品質計算等待時間
  debug: false
}

SDK 行為

初始化

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

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

處理時間軸

0秒 ────► 5秒 ────► 8秒 ────► 15秒 ────► 30秒
│        │        │        │         │
│        │        │        │         └─ 掃描完成
│        │        │        └─ 最佳準確度(15秒視窗)
│        │        └─ 首次估算(暖機完成,3+ 估算)
│        └─ 訊號品質延遲(5秒)
└─ 掃描開始(即時初始化)

暖機與平滑化

Panoptic 估算器應用內建暖機和平滑化機制,以確保穩定可靠的讀數。

暖機閘門

在估算器收集到 150 個 RGB 樣本(30fps 下約 5 秒)並累積至少 3 次估算之前,不會發出任何心率估算值。這可防止緩衝區填滿期間出現早期無效值。

  • 典型首次估算時間:~8 秒(5 秒緩衝 + 3 次估算週期,以 1Hz 執行)
  • 暖機期間,onVideoFrameProcessed 事件的 realtimeEstimationnull

1Hz 節流

訊號處理以 1 Hz(每秒一次)而非每幀執行。這確保每次估算都基於有意義的時間視窗,並使 EWMA 平滑化以自然速率調節。

EWMA 平滑化

指數加權移動平均平滑心率輸出:

typescript
// EWMA formulation used by the estimator
HR_smooth[t] = 0.4 * HR_raw[t] + 0.6 * HR_smooth[t-1]
  • α = 0.4 — 平衡反應速度與雜訊抑制(~2 秒時間常數)
  • 種子值:所有暖機期間估算的中位數(抗離群值)
  • 在不隱藏真實心率變化的情況下穩定顯示

變化率限制

連續估算之間的最大心率變化:±5 BPM/秒。這可防止動作偽影造成的突然跳動,同時仍追蹤真實趨勢。

typescript
// Clamp prevents artifactual jumps
if (Math.abs(delta) > 5) {
  HR_output = HR_previous + sign(delta) * 5;
}

自適應時間視窗

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

經過時間視窗大小準確度狀態
< 5 秒暖機中(尚無估算)
8 秒8秒±5-8 BPM首次估算
15+ 秒15秒±2-3 BPM最佳 ✓
typescript
camera.onVideoFrameProcessed = (event) => {
  const estimation = event.realtimeEstimation;
  if (!estimation) {
    showMessage('分析中... 請保持靜止');
    return;
  }
  
  if (getCurrentScanTime() < 15) {
    showHeartRate(estimation.heartRate, '精煉中...');
  } else {
    showHeartRate(estimation.heartRate, '穩定 ✓');
  }
};

效能特性

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

品質指標

訊噪比(SNR)

Panoptic 估算器提供 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('改善光線或減少移動');
  }
};

優勢

🏥 醫療級品質

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

📦 零依賴

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

⚡ 快速初始化

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

🔒 智慧財產權保護

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

🎯 確定性

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

何時使用

✅ 最適合

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

❌ 避免使用

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

疑難排解

低信心度分數

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

解決方案

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

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

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

不穩定讀數

症狀:心率跳動

解決方案

typescript
// 引導使用者
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) {
    showMessage("分析中... 請保持靜止");
    return;
  }
  
  if (getCurrentScanTime() < 15) {
    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 估算器比較

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

範例:完整實作

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

// 使用 Panoptic 估算器建立相機
const camera = createVitalSignCamera({
  realtimeEstimationConfig: {
    estimatorType: RealtimeEstimatorType.Panoptic,
    debug: false
  }
});

// Panoptic 立即就緒(無非同步載入)
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.Panoptic,
    signalQualityDelay: 10,  // 延長品質計算等待時間
    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('測量品質低於醫療閾值');
    }
  }
};

下一步