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事件中的realtimeEstimation为null。
1Hz 节流
信号处理以 1 Hz(每秒一次)运行,而非每帧运行。这确保每次估算基于有意义的時間窗口,并使 EWMA 平滑以自然速率进行调节。
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-10 | 0.8-1.0 | 非常好 | 高度可靠 ✓ |
| 6-8 | 0.6-0.8 | 良好 | 可靠 |
| 4-6 | 0.4-0.6 | 尚可 | 可接受 |
| 2-4 | 0.2-0.4 | 差 | 考慮重試 |
| < 2 | 0.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 估算器比較
| 特点 | Panoptic | ME-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('测量质量低于医疗阈值');
}
}
};下一步
- ME-rPPG 估算器 - 與 AI 方法比較
- 选择指南 - 选择正確的估算器
- 信号可视化器 - 可视化 PPG 信号
- API 参考 - 完整 API 文档