This repository contains code for estimating respiratory rate from video using different methods and datasets.
The main script run_all.py supports:
- Extracting respiratory signals from videos using different methods
- Evaluating the results with multiple metrics
- Printing the evaluation metrics
python run_all.py -a <action> -d <results_dir>
Arguments:
-a
: Action to perform0
: Extract respiratory signals1
: Evaluate results2
: Print metrics
-d
: Directory to save/load results (default:results/
)
The following methods are implemented:
- Deep Learning Methods:
- Motion-based Methods:
OF_Deep
: Deep Optical Flow estimationOF_Model
: Traditional Optical Flow (Farneback)DoF
: Difference of Framesprofile1D
: 1D Motion Profile
- rPPG-based Methods:
peak
: Peak detectionmorph
: Morphological analysisbss_ssa
: Blind Source Separation with SSAbss_emd
: Blind Source Separation with EMD
The code works with the following datasets:
- Extract respiratory signals using deep learning methods:
methods = [BigSmall(), MTTS_CAN()]
datasets = [BP4D(), COHFACE()]
extract_respiration(datasets, methods, "results/")
- Evaluate the results:
python run_all.py -a 1 -d results/
- Print metrics:
python run_all.py -a 2 -d results/
To add a new dataset, create a class that inherits from DatasetBase
and implement the required methods:
class NewDataset(DatasetBase):
def __init__(self):
super().__init__()
self.name = 'new_dataset' # Unique dataset identifier
self.path = self.data_dir + 'path/to/dataset/'
self.fs_gt = 1000 # Ground truth sampling frequency
self.data = []
def load_dataset(self):
# Load dataset metadata and populate self.data list
# Each item should be a dict with:
# - video_path: path to video file
# - subject: subject ID
# - chest_rois: [] (empty list, populated during processing)
# - face_rois: [] (empty list, populated during processing)
# - rppg_obj: [] (empty list, populated during processing)
# - gt: ground truth respiratory signal
def load_gt(self, trial_path):
# Load ground truth respiratory signal for a trial
pass
def extract_ROI(self, video_path, region='chest'):
# Extract ROIs from video for given region ('chest' or 'face')
pass
def extract_rppg(self, video_path, method='cpu_CHROM'):
# Extract rPPG signal from video
pass
To add a new respiratory rate estimation method, inherit from MethodBase
:
class NewMethod(MethodBase):
def __init__(self):
super().__init__()
self.name = 'new_method' # Unique method identifier
self.data_type = 'chest' # Input type: 'chest', 'face' or 'rppg'
def process(self, data):
# Implement respiratory signal extraction
# data contains:
# - chest_rois: list of chest ROI frames
# - face_rois: list of face ROI frames
# - rppg_obj: rPPG signal object
# - fps: video framerate
# Return the extracted respiratory signal
pass
After implementing the new classes, you can use them with the existing pipeline:
methods = [NewMethod()]
datasets = [NewDataset()]
extract_respiration(datasets, methods, "results/")
Required packages are listed in requirements.txt. Key dependencies include:
- TensorFlow 2.2-2.4
- OpenCV
- SciPy
- NumPy
- Matplotlib
This project is licensed under the GNU General Public License - see the LICENSE file for details.