Skip to content

Heatmap

The heatmap visualization displays a PPG (photoplethysmography) amplitude overlay on the face region, showing which areas of the face provide the strongest blood volume pulse signal. This helps users position their face optimally for accurate measurements.

How It Works

The heatmap analyzes video frames in real-time, measuring PPG signal amplitude across different facial regions. Areas with stronger pulse signals appear highlighted, while weaker areas are dimmer or transparent. The visualization adapts dynamically as lighting and face position change.

Available Presets

The heatmap includes 10 visual presets ranging from subtle to vibrant:

PresetDescriptionVisual Style
fieldSubtle field overlaySoft, semi-transparent green field
thermalFieldThermal-style fieldWarm color gradient (blue→red)
maskSemi-transparent maskSoft overlay on detected face area
lut1Look-up table 1 (Magma)Dark purple to bright yellow
lut2Look-up table 2 (Plasma)Deep purple to bright yellow
lut3Look-up table 3 (Viridis)Dark blue to bright yellow
lut4Look-up table 4 (Inferno)Dark black-purple to bright yellow
neonNeon glow effectBright, high-contrast glow
surfaceSurface heat patternTopographic-style contour display
lightMinimal light overlayVery subtle, minimal overlay

Configuration

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

const camera = createVitalSignCamera({
  userId: 'user-123',
  apiKey: 'your-api-key',
  visualizationOptions: {
    heatmap: {
      enabled: true,
      mode: 'field',           // Visual preset (default: 'field')
      opacity: 0.6,            // 0.0 - 1.0 (default: 0.6)
      blurRadius: 0,           // Gaussian blur radius (default: 0, no blur)
      brightness: 1.0,         // Brightness multiplier (default: 1.0)
      contrast: 1.0,           // Contrast multiplier (default: 1.0)
      saturation: 1.0,         // Color saturation (default: 1.0)
      smoothingFactor: 1.0,    // Temporal smoothing (0.0 - 1.0, default: 1.0)
      scale: 1.0,              // Overlay scale factor (default: 1.0)
      showOnlyFaceArea: false, // Restrict to face region only (default: false)
      enableAutoFit: true,     // Auto-fit to face bounding box (default: true)
      customColormap: undefined // Custom RGBA color stops for advanced users
    }
  }
});
tsx
import { VitalSignCamera } from 'react-vital-sign-camera';

const App = () => (
  <VitalSignCamera
    visualizationOptions={{
      heatmap: {
        enabled: true,
        mode: 'neon',
        opacity: 0.7,
        blurRadius: 2
      }
    }}
  />
);
vue
<template>
  <VitalSignCamera
    :visualizationOptions="visualizationOptions"
  />
</template>

<script setup>
const visualizationOptions = {
  heatmap: {
    enabled: true,
    mode: 'thermalField',
    opacity: 0.65,
    showOnlyFaceArea: true
  }
};
</script>

Dynamic Configuration

You can change heatmap preset and settings at runtime using the visualizationOptions setter. The heatmap reconfigures immediately without restarting the camera:

typescript
// Switch between presets
camera.visualizationOptions = {
  ...camera.visualizationOptions,
  heatmap: { mode: 'neon', opacity: 0.8 }
};

// Disable heatmap
camera.visualizationOptions = {
  ...camera.visualizationOptions,
  heatmap: { enabled: false }
};

// Enable with default settings
camera.visualizationOptions = {
  ...camera.visualizationOptions,
  heatmap: { enabled: true }
};

Custom Colormap

For advanced use cases, you can provide a custom colormap using RGBA color stops:

typescript
camera.visualizationOptions = {
  heatmap: {
    enabled: true,
    mode: 'field',
    customColormap: [
      { pos: 0.0, color: [0, 0, 0, 0] },       // Fully transparent at minimum
      { pos: 0.3, color: [0, 0, 255, 100] },    // Blue at 30%
      { pos: 0.6, color: [0, 255, 255, 150] },  // Cyan at 60%
      { pos: 0.9, color: [0, 255, 0, 200] },    // Green at 90%
      { pos: 1.0, color: [255, 0, 0, 255] }     // Red at maximum
    ]
  }
};

HeatmapOptions Interface

typescript
interface HeatmapOptions {
  enabled?: boolean;
  mode?: HeatmapVariantMode;       // Default: 'field'
  opacity?: number;                // 0.0 - 1.0
  blurRadius?: number;             // 0 = no blur
  brightness?: number;
  contrast?: number;
  saturation?: number;
  smoothingFactor?: number;        // 0.0 - 1.0
  scale?: number;
  showOnlyFaceArea?: boolean;
  enableAutoFit?: boolean;
  customColormap?: ColormapStop[];
}

type HeatmapVariantMode =
  | 'field'
  | 'thermalField'
  | 'mask'
  | 'lut1'
  | 'lut2'
  | 'lut3'
  | 'lut4'
  | 'neon'
  | 'surface'
  | 'light';

interface ColormapStop {
  pos: number;        // 0.0 - 1.0
  color: [number, number, number, number];  // [R, G, B, A] 0-255
}