Skip to content

austindarian/realtime-cpr-assessment

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🫀 Real-Time CPR Quality Assessment System

A webcam-based CPR coaching system that provides live feedback on elbow form, compression frequency, and compression depth — grounded in AHA guidelines (100–120 BPM, 5–6 cm depth).

Built with MMPose pose estimation + a Random Forest classifier, running at 30 FPS on consumer-grade hardware.


📽️ Demo

CPR Demo


🧠 System Overview

This is a hybrid assessment system — combining a trained ML classifier for form detection with rule-based physics calculations for frequency and depth.

─────────────────────────────────────────────────────────────
 OFFLINE: Training Pipeline (run once)
─────────────────────────────────────────────────────────────

 Labelled Videos (Good / Bad CPR)
         │
         ▼
 extract_keypoints.py
 → Runs person detection (Faster R-CNN) + pose estimation (HRNet)
 → Saves raw keypoint sequences as .npy per video
         │
         ▼
 Feature_extraction.py
 → Computes elbow angle per frame (shoulder → elbow → wrist)
 → Aggregates: mean, min, std across each video
 → Saves features.npy and labels.npy
         │
         ▼
 train_model.py
 → Trains a Random Forest classifier (scikit-learn)
 → Saves cpr_model.pkl

─────────────────────────────────────────────────────────────
 ONLINE: Real-Time Assessment Pipeline (webcam)
─────────────────────────────────────────────────────────────

 Webcam Feed
         │
         ▼
 realtime_pose.py  (development/test script)
 → Validates pose estimation is working live
         │
         ▼
 realtime_cpr_detection_freq_depth.py  ← MAIN SCRIPT
         │
         ├─► Elbow Angle (live, per frame)
         │       └─► 90-frame rolling buffer → Random Forest → PASS / FAIL
         │           [ML-based classification]
         │
         ├─► Wrist Y-position (live, per frame)
         │       └─► Peak detection → Compression count → BPM → PASS / WARN / FAIL
         │           [Rule-based, AHA: 100–120 BPM]
         │
         └─► Peak-to-Trough displacement (pixels → cm)
                 └─► Mean depth per cycle → PASS / WARN / FAIL
                     [Rule-based, AHA: 5–6 cm]
                              │
                              ▼
                    Live HUD Overlay on Screen

📊 Assessment Metrics

Metric Method PASS WARN FAIL
Elbow Form Random Forest (ML) Straight arms Bent elbows
Frequency Rule-based 100–120 BPM 90–99 or 121–130 BPM < 90 or > 130 BPM
Depth Rule-based 5.0–6.0 cm 4.0–4.9 or 6.1–7.0 cm < 4.0 or > 7.0 cm

🗂️ Project Structure

realtime-cpr-assessment/
│
├── README.md
├── requirements.txt
│
├── src/
│   ├── realtime_cpr_detection_freq_depth.py   # Main real-time assessment script
│   ├── realtime_pose.py                       # Pose estimation test/dev script
│   ├── extract_keypoints.py                   # Step 1: Extract keypoints from labelled videos
│   ├── Feature_extraction.py                  # Step 2: Compute angle features + save .npy
│   └── train_model.py                         # Step 3: Train Random Forest classifier
│
├── models/
│   └── cpr_model.pkl                          # Trained classifier
│
└── assets/
    └── demo_1.gif                             # Demo recording

⚙️ Installation

Prerequisites

  • Python 3.11
  • CUDA-capable GPU recommended (CPU works but slower)
  • Conda environment recommended

1. Clone the repo

git clone https://github.com/austindarian/realtime-cpr-assessment.git
cd realtime-cpr-assessment

2. Install dependencies

pip install -r requirements.txt

⚠️ MMPose and MMDetection require specific installation steps.
Follow the MMPose installation guide if you run into issues.

3. Download model checkpoints

Download the following pretrained checkpoints and place them in a checkpoints/ folder:

Model Purpose File
Faster R-CNN Person detection faster_rcnn_r50_fpn_1x_coco_20200130-047c8118.pth
HRNet-W32 Pose estimation hrnet_w32_coco_256x192-c78dce93_20200708.pth

Update the checkpoint paths in src/extract_keypoints.py and src/realtime_pose.py to point to your local checkpoints/ folder.


🚀 Usage

Option A — Use the pretrained model (quick start)

The trained cpr_model.pkl is included. Just run the main script:

python src/realtime_cpr_detection_freq_depth.py

Press q to quit.

Option B — Retrain on your own data

Step 1: Organise your labelled videos:

Dataset/
├── Good/   ← videos of correct CPR form
└── Bad/    ← videos of incorrect CPR form

Step 2: Extract keypoints from each video:

python src/extract_keypoints.py

→ Saves per-video .npy keypoint sequences to a Features/ folder.

Step 3: Compute angle features:

python src/Feature_extraction.py

→ Saves features.npy and labels.npy.

Step 4: Train the classifier:

python src/train_model.py

→ Saves cpr_model.pkl.

Step 5: Run the assessment:

python src/realtime_cpr_detection_freq_depth.py

📏 Depth Calibration

Depth estimation relies on PIXELS_PER_CM in realtime_cpr_detection_freq_depth.py (default: 10.0).

To calibrate for your setup:

  1. Place a ruler or known-size object in front of the camera
  2. Measure how many pixels correspond to 1 cm in the frame
  3. Update PIXELS_PER_CM accordingly

🛠️ Tech Stack

Tool Purpose
Python 3.11 Core language
MMPose 1.3.2 Pose estimation (HRNet-W32)
MMDetection Person detection (Faster R-CNN)
OpenCV Webcam capture & HUD rendering
scikit-learn Random Forest classifier
SciPy Peak detection (find_peaks)
NumPy Signal processing
Matplotlib Live wrist Y-signal plot
joblib Model serialisation

📚 References


👤 Author

Austin Darian Pratama
Master of Data Science — Western Sydney University
LinkedIn · GitHub

About

Webcam-based real-time CPR coaching system using MMPose pose estimation + Random Forest classifier to assess elbow form, compression frequency and depth against AHA guidelines — running at 30 FPS on consumer hardware.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages