Results

The SDK produces final results once the required success conditions have been met for the chosen measurement duration. By default (if you don’t change any settings), the SDK uses a 1-minute measurement. However, you can configure shorter or custom durations (see Measurement Preset).

Success conditions

Regardless of measurement length, two key conditions must be met for a successful result:

  • The extracted photoplethysmographic signal must remain above a required quality threshold.
  • The user’s face must be stable and properly positioned within the camera frame.

If these conditions aren’t consistently satisfied, the measurement may take longer (for example, if the user moves out of view or is in a dark environment).


Final metrics

Below are the metrics the SDK computes from the detected heart cycles once the measurement finishes:

  • IBI (Interbeat Intervals) are computed via advanced filtering and analysis of the extracted dense photoplethysmographic signal. For each detected heartbeat, the SDK provides a start time, end time, and duration (in milliseconds).

  • HR (Heart Rate) is computed from the average duration of observed heart cycles.

  • HRV (Heart Rate Variability) metrics (SDNN, lnRMSSD) are derived from how the durations of consecutive heart cycles vary.

  • SI (cardiac stress index) is computed based on the statistical distribution of time intervals between successive heartbeats during the video measurement. It is similar to the Baevsky stress index but has been adapted for shorter measurements.

    Our cardiac stress index is an indirect measure of the physiological stress experienced by the body as assessed by the way the heart beats. Its values are usually in the range 0–10, although higher values, corresponding to particularly high levels of physiological stress, are also possible.

    Cardiac stress mainly reflects the state of the autonomic nervous system (ANS), which controls the heart rhythm as well as various other involuntary physiological processes. It is determined based on the analysis of heart rate during our video-based measurement. In general, the lower the cardiac stress, the better, as it suggests a relaxed state of a well-rested body, a good level of fitness, overall health, and/or young biological age.

  • Parasympathetic Activity is derived from analyzing the variability in heart rate, indicating how actively the parasympathetic nervous system is functioning (promoting relaxation and recovery).

  • BR (Breathing Rate) is computed via advanced analysis of the observed heart cycles.

    💡

    Breathing rate might be omitted if confidence is low (for example, in cases of extremely slow, fast, or highly irregular breathing). In Relaxed precision mode, the SDK will still return a breathing rate, even if confidence is low.

  • BP (Blood Pressure) is computed using a specialized deep-learning AI model.

  • Cardiac Workload is calculated as the product of heart rate and systolic blood pressure, indicating total effort by the heart.

  • Age is estimated using a custom-trained deep-learning AI model that analyzes the user’s face.

  • BMI is similarly estimated via facial analysis.


Accessing the results

Call getMeasurementResults() to retrieve final metrics from the most recently completed measurement. If no measurement has finished successfully yet, a null value will be returned. Below is a summary of the returned structure:

class MeasurementResults {
  double heart_rate_bpm;                 // Heart rate, rounded to 1 BPM
  double? hrv_sdnn_ms;                   // HRV, SDNN metric, rounded to 1 ms
  double? hrv_lnrmssd_ms;                // HRV, lnRMSSD metric, rounded to 0.1 ms
  double? stress_index;                  // Cardiac stress index, rounded to 0.1
  double? parasympathetic_activity;      // Parasympathetic activity, rounded to 1%
  double? breathing_rate_bpm;            // Breathing rate, rounded to 1 BPM
  double? systolic_blood_pressure_mmhg;  // Systolic blood pressure, rounded to 1 mmHg
  double? diastolic_blood_pressure_mmhg; // Diastolic blood pressure, rounded to 1 mmHg
  double? cardiac_workload_mmhg_per_sec; // Cardiac workload, rounded to 1 mmHg/s
  double? age_years;                     // Estimated age, rounded to 1 year
  double? bmi_kg_per_m2;                 // Estimated BMI, rounded to 0.01
  List<Heartbeat?> heartbeats;           // List of detected heartbeats
  double average_signal_quality;         // Average signal quality metric
}
 
class Heartbeat {
  double start_location_sec;  // exact start time in seconds
  double end_location_sec;    // exact end time in seconds
  double duration_ms;         // heartbeat duration, rounded to 1 ms
}
 
var results = await ShenaiSDK.getMeasurementResults();


Additional outputs

Some additional outputs are provided, which may be used to better instruct the user about how the measurement process works. Note that the outputs will only be available after a successful measurement.

rPPG signal

You can access the final rPPG signal from the measurement by calling the getFullPpgSignal() method:

var ppgSignal = await ShenaiSDK.getFullPpgSignal();

The signal will be returned as a list of floating point values, where each value represents the intensity of the signal at a given point in time. The signal is sampled at the camera frame rate, which is usually 30 FPS.

Facial regions visualizations

You can access an image of the region of the face which was used to extract the rPPG signal, as well as the signal intensity map.

var faceImage = await ShenaiSDK.getFaceTexturePng();
var signalImage = await ShenaiSDK.getSignalQualityMapPng();

The images will be returned as PNG-encoded byte arrays which you can decode and display as you wish, for example along with explaining the measurement results.

💡

The facial texture image may be personally identifiable, so you should not save/upload it without permission from the user. No personally identifiable data leaves the SDK by itself as all processing is done locally on the device.

;