Skip to content

FDA Estimator

NOTE

Web SDKs Only Realtime estimation is currently available for web-based SDKs only (JavaScript, React, Vue). It is not available for mobile SDKs (iOS, Android, Flutter, React Native).

Overview

The FDA Estimator is a medical-grade heart rate measurement system that uses advanced signal processing to analyze photoplethysmography (PPG) signals from facial video. It provides FDA-level accuracy without requiring external AI models, making it ideal for medical applications and instant initialization.

IMPORTANT

Proprietary Technology The FDA Estimator is proprietary software developed by PanopticAI. The core algorithm runs in WebAssembly for intellectual property protection.

Key Features

  • Medical-Grade: FDA-level accuracy
  • Instant Init: No model loading required
  • Zero Dependencies: No external files needed
  • Deterministic: Same input → same output
  • Lightweight: < 200 KB memory footprint
  • Adaptive: Early results in 5 seconds, optimal in 10

Basic Usage

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(`HR: ${estimation.heartRate} BPM`);
  console.log(`Confidence: ${estimation.confidence}`);
  console.log(`SNR: ${estimation.snr}`);
});

Configuration

For Consumer Applications

typescript
{
  estimatorType: RealtimeEstimatorType.Fda,
  earlyEstimation: true,   // Show early results
  minDuration: 5,          // Faster feedback
  minConfidence: 0.4,      // Lower threshold
  debug: false
}

For Medical Applications

typescript
{
  estimatorType: RealtimeEstimatorType.Fda,
  earlyEstimation: false,  // Wait for full accuracy
  minDuration: 10,         // Full 10 seconds
  minConfidence: 0.7,      // High confidence threshold
  debug: false
}

SDK Behavior

Initialization

typescript
// FDA estimator initializes instantly (no async loading)
const camera = createVitalSignCamera({
  realtimeEstimationConfig: {
    estimatorType: RealtimeEstimatorType.Fda
  }
});

// Ready immediately - no waiting required
camera.startScan();

Processing Timeline

0s ────► 5s ────► 10s ────► 30s
│        │        │         │
│        │        │         └─ Scan complete
│        │        └─ Optimal accuracy (10s window)
│        └─ First estimate (5s window)
└─ Scan starts (instant init)

Adaptive Time Window

The FDA estimator uses an adaptive time window that grows as more data arrives:

Time ElapsedWindow SizeAccuracyStatus
5 seconds5s±5-8 BPMEarly estimate
7 seconds7s±3-5 BPMImproving
10+ seconds10s±2-3 BPMOptimal ✓
typescript
camera.onVideoFrameProcessed = (event) => {
  const elapsed = getCurrentScanTime();
  
  if (elapsed < 7) {
    showHeartRate(estimation.heartRate, 'Early estimate');
  } else if (elapsed < 10) {
    showHeartRate(estimation.heartRate, 'Refining...');
  } else {
    showHeartRate(estimation.heartRate, 'Stable ✓');
  }
});

Performance Characteristics

MetricValue
InitializationInstant (< 10ms)
First Result~5 seconds
Optimal Accuracy~10 seconds
Processing Speed5-10ms per frame
Memory Usage< 200 KB
Bundle Size~100 KB (WASM)
Typical Error±2-3 BPM
Heart Rate Range50-140 BPM

Quality Metrics

Signal-to-Noise Ratio (SNR)

The FDA estimator provides SNR values to indicate signal quality:

SNRConfidenceQualityInterpretation
10+1.0ExcellentTrust completely ✓
8-100.8-1.0Very GoodHighly reliable ✓
6-80.6-0.8GoodReliable
4-60.4-0.6FairAcceptable
2-40.2-0.4PoorConsider retrying
< 20.0-0.2Very PoorRetry required
typescript
camera.onVideoFrameProcessed = (event) => {
  const estimation = event.realtimeEstimation;
  if (!estimation) return;
  
  if (estimation.snr && estimation.snr > 6) {
    showQualityIndicator('excellent');
  } else if (estimation.snr && estimation.snr > 4) {
    showQualityIndicator('good');
  } else {
    showQualityIndicator('poor');
    showTip('Improve lighting or reduce movement');
  }
});

Advantages

🏥 Medical-Grade Quality

  • FDA-level accuracy
  • Matches validated server implementation
  • Suitable for medical applications
  • Regulatory compliance friendly

📦 Zero Dependencies

  • No model files to download
  • Instant initialization
  • Works offline immediately
  • Smaller bundle size

⚡ Fast Initialization

  • No async loading required
  • Ready to use immediately
  • No waiting for models
  • Simpler error handling

🔒 IP Protection

  • Core algorithm in WebAssembly
  • Proprietary implementation protected
  • Binary format prevents reverse engineering

🎯 Deterministic

  • Same input → same output
  • No AI randomness
  • Reproducible results
  • Easier to debug

When to Use

✅ Best For

  • Medical and healthcare applications
  • Regulatory compliance requirements
  • Instant initialization needed
  • Minimal bundle size required
  • Offline-first applications
  • Embedded systems and IoT devices

❌ Avoid If

  • Users will be moving significantly
  • Lighting conditions are uncontrolled
  • Maximum motion tolerance needed
  • Open-source licensing required
  • AI-powered features preferred

Troubleshooting

Low Confidence Scores

Symptoms: Confidence < 0.6, unstable readings

Solutions:

typescript
// 1. Improve environmental conditions
const instructions = [
  "Use natural daylight",
  "Avoid backlighting",
  "Ensure even illumination",
  "Remove shadows from face"
];

// 2. Reduce motion
const motionTips = [
  "Stay completely still",
  "Don't talk during measurement",
  "Use phone stand if possible",
  "Maintain steady distance"
];

// 3. Wait longer
{
  minDuration: 10,  // Allow full 10-second window
  minConfidence: 0.6
}

// 4. Check face detection - note: face detection events vary by SDK
// For web SDKs, check scanConditions in VideoFrameProcessedEvent
camera.onVideoFrameProcessed = (event) => {
  if (event.scanConditions && !event.scanConditions.centered) {
    showWarning('Keep face centered and stable');
  }
});

Unstable Readings

Symptoms: Heart rate jumps around

Solutions:

typescript
// Increase minimum confidence threshold
{
  minConfidence: 0.7  // Higher threshold for stability
}

// Wait for full window
{
  earlyEstimation: false,  // Disable early results
  minDuration: 10
}

// Guide user
camera.onVideoFrameProcessed = (event) => {
  const estimation = event.realtimeEstimation;
  if (!estimation) return;
  
  if (estimation.confidence < 0.6) {
    showTip('Please stay still and improve lighting');
  }
});

Best Practices

1. Progressive Feedback

typescript
camera.onVideoFrameProcessed = (event) => {
  const estimation = event.realtimeEstimation;
  if (!estimation) return;
  
  const elapsed = getCurrentScanTime();
  
  if (elapsed < 5) {
    showMessage("Analyzing... Please stay still");
  } else if (elapsed < 10) {
    if (estimation.confidence > 0.4) {
      showHeartRate(estimation.heartRate, "Refining...");
    } else {
      showMessage("Adjusting... Improve lighting if possible");
    }
  } else {
    if (estimation.isStable) {
      showHeartRate(estimation.heartRate, "Stable ✓");
    } else {
      showMessage("Low confidence. Try again with better conditions.");
    }
  }
});

2. Quality Indicators

typescript
function getQualityIndicator(estimation: RealtimeEstimation): string {
  if (estimation.confidence >= 0.8) return "Excellent ⭐⭐⭐⭐⭐";
  if (estimation.confidence >= 0.6) return "Very Good ⭐⭐⭐⭐";
  if (estimation.confidence >= 0.4) return "Good ⭐⭐⭐";
  if (estimation.confidence >= 0.2) return "Fair ⭐⭐";
  return "Poor ⭐";
}

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

3. Retry Logic

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(`Low confidence. Retrying (${retryCount}/${MAX_RETRIES})...`);
    camera.reset();
    camera.startScan();
  } else {
    retryCount = 0;
    displayFinalResult(result);
  }
});

4. User Guidance

typescript
const guidanceMessages = {
  lowConfidence: "Improve lighting or stay still",
  noFace: "Position your face in the center",
  unstable: "Keep your face steady",
  success: "Measurement complete ✓"
};

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

Comparison with ME-rPPG Estimator

FeatureFDAME-rPPG
Accuracy⭐⭐⭐⭐⭐ Medical-grade⭐⭐⭐⭐⭐ State-of-the-art
Motion Tolerance⭐⭐⭐⭐ Good⭐⭐⭐⭐⭐ Excellent
Lighting Tolerance⭐⭐⭐⭐ Good⭐⭐⭐⭐⭐ Excellent
Initialization⭐⭐⭐⭐⭐ Instant⭐⭐⭐ (1-2s)
Bundle Size⭐⭐⭐⭐⭐ ~100 KB⭐⭐⭐ ~10 MB
Memory Usage⭐⭐⭐⭐⭐ < 200 KB⭐⭐⭐ ~4 MB
LicensingProprietaryOpen-source
First Result~5 seconds~3 seconds
Best ForMedical apps, embeddedConsumer apps, challenging conditions

Example: Complete Implementation

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

// Create camera with FDA estimator
const camera = createVitalSignCamera({
  realtimeEstimationConfig: {
    estimatorType: RealtimeEstimatorType.Fda,
    earlyEstimation: true,
    minDuration: 10,
    minConfidence: 0.6,
    debug: false
  }
});

// FDA is ready immediately (no async loading)
document.getElementById('start-btn').disabled = false;

// Handle realtime updates
camera.onVideoFrameProcessed = (event) => {
  const estimation = event.realtimeEstimation;
  if (!estimation) return;
  
  updateHeartRateDisplay(estimation.heartRate);
  updateConfidenceBar(estimation.confidence);
  
  // Show SNR if available
  if (estimation.snr) {
    updateSNRDisplay(estimation.snr);
  }
  
  // Quality indicator
  if (estimation.isStable && estimation.confidence > 0.7) {
    showQualityIndicator('excellent');
  } else if (estimation.confidence > 0.5) {
    showQualityIndicator('good');
  } else {
    showQualityIndicator('poor');
    showTip('Improve lighting or reduce movement');
  }
});

// Handle scan completion
// Check for final results
let scanCompleted = false;
camera.onVideoFrameProcessed = (event) => {
  const results = event.healthResult;
  if (results && !scanCompleted) {
    scanCompleted = true;
    if (results.confidence > 0.7) {
      displayFinalResults(results);
    } else {
      showRetryOption();
    }
  }
});

// Start scan
document.getElementById('start-btn').onclick = () => {
  camera.startScan();
};

Example: Medical Application

typescript
// Medical-grade configuration
const camera = createVitalSignCamera({
  realtimeEstimationConfig: {
    estimatorType: RealtimeEstimatorType.Fda,
    earlyEstimation: false,  // Wait for full accuracy
    minDuration: 10,         // Full 10 seconds
    minConfidence: 0.7,      // High threshold
    debug: false
  }
});

// Only record high-confidence measurements
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()
    });
  }
});

// Validate before saving
// Validate before saving
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('Measurement quality below medical threshold');
    }
  }
});

Next Steps