Skip to main content

Vital sign estimation from facial video

Project description

VitalLens API Logo

vitallens-python

Estimate vital signs such as heart rate and respiratory rate from video in Python.

Tests PyPI Downloads Website Documentation

vitallens is a Python client for the VitalLens API, using the same inference engine as our free iOS app VitalLens. Furthermore, it includes fast implementations of several other heart rate estimation methods from video such as G, CHROM, and POS.

  • Accepts as input either a video filepath or an in-memory video as np.ndarray
  • Performs fast face detection if required - you can also pass existing detections
  • vitallens.Method.VITALLENS supports heart rate, respiratory rate, pulse waveform, and respiratory waveform estimation. In addition, it returns an estimation confidence for each vital. We are working to support more vital signs in the future.
  • vitallens.Method.{G/CHROM/POS} support faster, but less accurate heart rate and pulse waveform estimation.
  • While VITALLENS requires an API Key, G, CHROM, and POS do not. Register on our website to get a free API Key.

Estimate vitals in a few lines of code:

from vitallens import VitalLens, Method

vl = VitalLens(method=Method.VITALLENS, api_key="YOUR_API_KEY")
result = vl("video.mp4")
print(result)

Using a different language or platform? We also have a JavaScript client.

Disclaimer

vitallens provides vital sign estimates for general wellness purposes only. It is not intended for medical use. Always consult with your doctor for any health concerns or for medically precise measurement.

See also our Terms of Service for the VitalLens API and our Privacy Policy.

Installation

General prerequisites are python>=3.8 and ffmpeg installed and accessible via the $PATH environment variable.

The easiest way to install the latest version of vitallens and its Python dependencies:

pip install vitallens

Alternatively, it can be done by cloning the source:

git clone https://github.com/Rouast-Labs/vitallens-python.git
pip install ./vitallens-python

How to use

To start using vitallens, first create an instance of vitallens.VitalLens. It can be configured using the following parameters:

Parameter Description Default
method Inference method. {Method.VITALLENS, Method.POS, Method.CHROM or Method.G} Method.VITALLENS
mode Operation mode. {Mode.BATCH for indep. videos or Mode.BURST for video stream} Mode.BATCH
api_key Usage key for the VitalLens API (required for Method.VITALLENS) None
detect_faces True if faces need to be detected, otherwise False. True
estimate_rolling_vitals Set True to compute rolling vitals (e.g., rolling_heart_rate). True
fdet_max_faces The maximum number of faces to detect (if necessary). 1
fdet_fs Frequency [Hz] at which faces should be scanned - otherwise linearly interpolated. 1.0
export_to_json If True, write results to a json file. True
export_dir The directory to which json files are written. .

Once instantiated, vitallens.VitalLens can be called to estimate vitals. In Mode.BATCH calls are assumed to be working on independent videos, whereas in Mode.BURST we expect the subsequent calls to pass the next frames of the same video (stream) as np.ndarray. Calls are configured using the following parameters:

Parameter Description Default
video The video to analyze. Either a path to a video file or np.ndarray. More info here.
faces Face detections. Ignored unless detect_faces=False. More info here. None
fps Sampling frequency of the input video. Required if video is np.ndarray. None
override_fps_target Target frequency for inference (optional - use methods's default otherwise). None
export_filename Filename for json export if applicable. None

vitallens returns estimates of the following vital signs if using Mode.BATCH with a minimum of 16 frames:

Name Type Returned if
heart_rate Global value Video at least 2 seconds long and using Method.VITALLENS, Method.POS, Method.CHROM or Method.G
rolling_heart_rate Continuous values Video more than 10 seconds long and using Method.VITALLENS, Method.POS, Method.CHROM or Method.G and estimate_rolling_vitals=True
ppg_waveform Continuous waveform Using Method.VITALLENS, Method.POS, Method.CHROM or Method.G
respiratory_rate Global value Video at least 4 seconds long and using Method.VITALLENS
rolling_respiratory_rate Continuous values Video more than 30 seconds long and using Method.VITALLENS and estimate_rolling_vitals=True
respiratory_waveform Continuous waveform Using Method.VITALLENS

The estimation results are returned as a list. It contains a dict for each distinct face, with the following structure:

[
  {
    'face': {
      'coordinates': <Face coordinates for each frame as np.ndarray of shape (n_frames, 4)>,
      'confidence': <Face live confidence for each frame as np.ndarray of shape (n_frames,)>,
      'note': <Explanatory note>
    },
    'vital_signs': {
      'heart_rate': {
        'value': <Estimated global value as float scalar>,
        'unit': <Value unit>,
        'confidence': <Estimation confidence as float scalar>,
        'note': <Explanatory note>
      },
      'respiratory_rate': {
        'value': <Estimated global value as float scalar>,
        'unit': <Value unit>,
        'confidence': <Estimation confidence as float scalar>,
        'note': <Explanatory note>
      },
      'ppg_waveform': {
        'data': <Estimated waveform value for each frame as np.ndarray of shape (n_frames,)>,
        'unit': <Data unit>,
        'confidence': <Estimation confidence for each frame as np.ndarray of shape (n_frames,)>,
        'note': <Explanatory note>
      },
      'respiratory_waveform': {
        'data': <Estimated waveform value for each frame as np.ndarray of shape (n_frames,)>,
        'unit': <Data unit>,
        'confidence': <Estimation confidence for each frame as np.ndarray of shape (n_frames,)>,
        'note': <Explanatory note>
      },
      'rolling_heart_rate': {
        'data': <Estimated value for each frame as np.ndarray of shape (n_frames,)>,
        'unit': <Value unit>,
        'confidence': <Estimation confidence for each frame as np.ndarray of shape (n_frames,)>,
        'note': <Explanatory note>
      },
      'rolling_respiratory_rate': {
        'data': <Estimated value for each frame as np.ndarray of shape (n_frames,)>,
        'unit': <Value unit>,
        'confidence': <Estimation confidence for each frame as np.ndarray of shape (n_frames,)>,
        'note': <Explanatory note>
      }
    },
    "message": <Message about estimates>
  },
  { 
    <same structure for face 2 if present>
  },
  ...
]

Examples to get started

Live test with webcam in real-time

Test vitallens in real-time with your webcam using the script examples/live.py. This uses Mode.BURST to update results continuously (approx. every 2 seconds for Method.VITALLENS). Some options are available:

  • method: Choose from [VITALLENS, POS, G, CHROM] (Default: VITALLENS)
  • api_key: Pass your API Key. Required if using method=VITALLENS.

May need to install requirements first: pip install opencv-python

python examples/live.py --method=VITALLENS --api_key=YOUR_API_KEY

Compare results with gold-standard labels using our example script

There is an example Python script in examples/test.py which uses Mode.BATCH to run vitals estimation and plot the predictions against ground truth labels recorded with gold-standard medical equipment. Some options are available:

  • method: Choose from [VITALLENS, POS, G, CHROM] (Default: VITALLENS)
  • video_path: Path to video (Default: examples/sample_video_1.mp4)
  • vitals_path: Path to gold-standard vitals (Default: examples/sample_vitals_1.csv)
  • api_key: Pass your API Key. Required if using method=VITALLENS.

May need to install requirements first: pip install matplotlib pandas

For example, to reproduce the results from the banner image on the VitalLens API Webpage:

python examples/test.py --method=VITALLENS --video_path=examples/sample_video_2.mp4 --vitals_path=examples/sample_vitals_2.csv --api_key=YOUR_API_KEY

This sample is kindly provided by the VitalVideos dataset.

Use VitalLens API to estimate vitals from a video file

from vitallens import VitalLens, Method

vl = VitalLens(method=Method.VITALLENS, api_key="YOUR_API_KEY")
result = vl("video.mp4")

Use POS method on an np.ndarray of video frames

from vitallens import VitalLens, Method

my_video_arr = ...
my_video_fps = 30
vl = VitalLens(method=Method.POS)
result = vl(my_video_arr, fps=my_video_fps)

Run example script with Docker

If you encounter issues installing vitallens dependencies directly, you can use our Docker image, which contains all necessary tools and libraries. This docker image is set up to execute the example Python script in examples/test.py for you.

Prerequisites

  • Docker installed on your system.

Usage

  1. Clone the repository
git clone https://github.com/Rouast-Labs/vitallens-python.git && cd vitallens-python
  1. Build the Docker image
docker build -t vitallens .
  1. Run the Docker container

To run the example script on the sample video:

docker run vitallens \          
  --api_key "your_api_key_here" \
  --vitals_path "examples/sample_vitals_2.csv" \
  --video_path "examples/sample_video_2.mp4" \
  --method "VITALLENS"

You can also run it on your own video:

docker run vitallens \          
  --api_key "your_api_key_here" \
  --video_path "path/to/your/video.mp4" \
  --method "VITALLENS"
  1. View the results

The results will print to the console in text form.

Please note that the example script plots won't work when running them through Docker. To to get the plot as an image file, run:

docker cp <container_id>:/app/results.png .

Linting and tests

Before running tests, please make sure that you have an environment variable VITALLENS_DEV_API_KEY set to a valid API Key. To lint and run tests:

flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
pytest

Build

To build:

python -m build

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

vitallens-0.4.4.tar.gz (1.1 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

vitallens-0.4.4-py3-none-any.whl (1.1 MB view details)

Uploaded Python 3

File details

Details for the file vitallens-0.4.4.tar.gz.

File metadata

  • Download URL: vitallens-0.4.4.tar.gz
  • Upload date:
  • Size: 1.1 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.0.0 CPython/3.10.13

File hashes

Hashes for vitallens-0.4.4.tar.gz
Algorithm Hash digest
SHA256 cc9e4938e1f99e70692a60f7ca1c7a65f6a67b20b8310f9a94de7a521340877b
MD5 593bf0a7639645a507421785574f4d6d
BLAKE2b-256 cc1a382a63dea20dfb1177d6d355a996a6d4b8acbd30cfabab50c05cdebc9776

See more details on using hashes here.

File details

Details for the file vitallens-0.4.4-py3-none-any.whl.

File metadata

  • Download URL: vitallens-0.4.4-py3-none-any.whl
  • Upload date:
  • Size: 1.1 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.0.0 CPython/3.10.13

File hashes

Hashes for vitallens-0.4.4-py3-none-any.whl
Algorithm Hash digest
SHA256 e0e1b108ba89dc113d6f30d8648476e0bff2055b592347be1aa957c2bdbee48e
MD5 6e03e7b18a22b2c93eba782e16b1a677
BLAKE2b-256 21b3e78abbe203894535b3d6454f6c499c9644315e5b18416245ae1a2bb0dec9

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page