Source code for pyVHR.BVP.BVP

import numpy as np
import torch

"""
This module contains methods for trasforming an input signal
in a BVP signal using a rPPG method (see pyVHR.BVP.methods).
"""

[docs]def signals_to_bvps_torch(sig, torch_method, params={}): """ Transform an input RGB signal in a BVP signal using a rPPG method (see pyVHR.BVP.methods). This method must use Torch and execute on GPU/CPU. You can pass also non-RGB signal but the method used must handle its shape. Args: sig (float32 ndarray): RGB Signal as float32 ndarray with shape [num_estimators, rgb_channels, num_frames]. You can pass also a generic signal but the method used must handle its shape and type. torch_method: a method that comply with the fucntion signature documented in pyVHR.BVP.methods. This method must use Torch. params (dict): dictionary of usefull parameters that will be passed to the method. Returns: float32 ndarray: BVP signal as float32 ndarray with shape [num_estimators, num_frames]. """ if sig.shape[0] == 0: return np.zeros((0, sig.shape[2]), dtype=sig.dtype) cpu_sig = torch.from_numpy(sig) if len(params) > 0: bvps = torch_method(cpu_sig, **params) else: bvps = torch_method(cpu_sig) return bvps.numpy()
[docs]def signals_to_bvps_cpu(sig, cpu_method, params={}): """ Transform an input RGB signal in a BVP signal using a rPPG method (see pyVHR.BVP.methods). This method must use and execute on CPU. You can pass also non-RGB signal but the method used must handle its shape. Args: sig (float32 ndarray): RGB Signal as float32 ndarray with shape [num_estimators, rgb_channels, num_frames]. You can pass also a generic signal but the method used must handle its shape and type. cpu_method: a method that comply with the fucntion signature documented in pyVHR.BVP.methods. This method must use Numpy. params (dict): dictionary of usefull parameters that will be passed to the method. Returns: float32 ndarray: BVP signal as float32 ndarray with shape [num_estimators, num_frames]. """ if sig.shape[0] == 0: return np.zeros((0, sig.shape[2]), dtype=sig.dtype) cpu_sig = np.array(sig) if len(params) > 0: bvps = cpu_method(cpu_sig, **params) else: bvps = cpu_method(cpu_sig) return bvps
[docs]def RGB_sig_to_BVP(windowed_sig, fps, device_type=None, method=None, params={}): """ Transform an input RGB windowed signal in a BVP windowed signal using a rPPG method (see pyVHR.BVP.methods). You can pass also non-RGB signal but the method used must handle its shape. Args: windowed_sig (list): RGB windowed signal as a list of length num_windows of np.ndarray with shape [num_estimators, rgb_channels, num_frames]. fps (float): frames per seconds. You can pass also a generic signal but the method used must handle its shape and type. device_type (str): the chosen rPPG method run on CPU ('cpu', 'torch'). method: a method that comply with the fucntion signature documented in pyVHR.BVP.methods. This method must use Numpy if the 'device_type' is 'cpu', Torch if the 'device_type' is 'torch', and Cupy if the 'device_type' is 'cuda'. params(dict): dictionary of usefull parameters that will be passed to the method. If the method needs fps you can set {'fps':'adaptive'} in the dictionary to use the 'fps' input variable. Returns: a list of lenght num_windows of BVP signals as np.ndarray with shape [num_estimators, num_frames]; if no BVP can be found in a window, then the np.ndarray has num_estimators == 0. """ if device_type != 'cpu' and device_type != 'torch': print("[ERROR]: invalid device_type!") return [] if 'fps' in params and params['fps'] == 'adaptive': params['fps'] = np.float32(fps) bvps = [] for sig in windowed_sig: copy_signal = np.copy(sig) bvp = np.zeros((0, 1), dtype=np.float32) if device_type == 'cpu': bvp = signals_to_bvps_cpu( copy_signal, method, params) elif device_type == 'torch': bvp = signals_to_bvps_torch( copy_signal, method, params) bvps.append(bvp) return bvps
[docs]def concatenate_BVPs(list_of_BVPs): """ Join a list of windowed BVPs. There must be the same number of windows, and each one must have the same number of frames. Args: list_of_BVPs (list): a list of windowed BVPs each one defined as a list of lenght num_windows of BVP signals as np.ndarray with shape [num_estimators, num_frames]. Remember that concatenation is possible only if 'num_frames' is the same for each BVP of the nth window. Returns: a list of lenght num_windows of BVP signals as np.ndarray with shape [total_num_estimators, num_frames]; if no BVP can be found in a window, then the np.ndarray has total_num_estimators == 0. For example: given the BVP windows of shape [10, 200] and [20,200], the concatenated window will have shape [30,200]; If an exception is thrown for any reason, the function returns 0. """ if len(list_of_BVPs) <= 1: return 0 first_window_len = len(list_of_BVPs[0]) for item in list_of_BVPs: if first_window_len != len(item): return 0 try: concatenated_BVPs = [] for i in range(first_window_len): concatenated_BVPs.append(np.concatenate(tuple([e[i] for e in list_of_BVPs]), axis=0)) return concatenated_BVPs except ValueError as e: print(e) return 0