pulsecam / tests /test_extraction_methods.py
volfiros
feat: migrate rPPG pipeline to FaceLandmarker and 5-method adaptive extraction
e3615a2
Raw History Blame Contribute Delete
3.04 kB
import sys
import os
import numpy as np
import pytest
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "backend"))
from signal_processor import (
extract_green_signal,
extract_chrom_signal,
extract_pos_signal,
extract_gr_signal,
extract_grgb_signal,
)
@pytest.fixture
def clean_72bpm_rgb():
fps = 30
duration = 15
t = np.linspace(0, duration, fps * duration)
freq = 72.0 / 60.0
noise = np.random.normal(0, 0.3, len(t))
r = 140.0 + 2.0 * np.sin(2 * np.pi * freq * t) + noise
g = 142.0 + 4.0 * np.sin(2 * np.pi * freq * t + 0.3) + noise * 0.8
b = 138.0 + 1.0 * np.sin(2 * np.pi * freq * t + 0.6) + noise * 1.2
return r, g, b
def test_extract_green_signal_returns_array_of_same_length(clean_72bpm_rgb):
r, g, b = clean_72bpm_rgb
result = extract_green_signal(g)
assert isinstance(result, np.ndarray)
assert len(result) == len(g)
def test_extract_green_signal_nonzero_with_varying_input(clean_72bpm_rgb):
_, g, _ = clean_72bpm_rgb
result = extract_green_signal(g)
assert np.std(result) > 0
def test_extract_chrom_signal_returns_array(clean_72bpm_rgb):
r, g, b = clean_72bpm_rgb
result = extract_chrom_signal(r, g, b)
assert isinstance(result, np.ndarray)
assert len(result) == len(r)
def test_extract_chrom_signal_nonzero_with_varying_input(clean_72bpm_rgb):
r, g, b = clean_72bpm_rgb
result = extract_chrom_signal(r, g, b)
assert np.std(result) > 0
def test_extract_pos_signal_returns_array(clean_72bpm_rgb):
r, g, b = clean_72bpm_rgb
result = extract_pos_signal(r, g, b)
assert isinstance(result, np.ndarray)
assert len(result) == len(r)
def test_extract_pos_signal_nonzero_with_varying_input(clean_72bpm_rgb):
r, g, b = clean_72bpm_rgb
result = extract_pos_signal(r, g, b)
assert np.std(result) > 0
def test_extract_gr_signal_returns_array(clean_72bpm_rgb):
r, g, _ = clean_72bpm_rgb
result = extract_gr_signal(r, g)
assert isinstance(result, np.ndarray)
assert len(result) == len(r)
def test_extract_gr_signal_nonzero_with_varying_input(clean_72bpm_rgb):
r, g, _ = clean_72bpm_rgb
result = extract_gr_signal(r, g)
assert np.std(result) > 0
def test_extract_grgb_signal_returns_array(clean_72bpm_rgb):
r, g, b = clean_72bpm_rgb
result = extract_grgb_signal(r, g, b)
assert isinstance(result, np.ndarray)
assert len(result) == len(r)
def test_extract_grgb_signal_nonzero_with_varying_input(clean_72bpm_rgb):
r, g, b = clean_72bpm_rgb
result = extract_grgb_signal(r, g, b)
assert np.std(result) > 0
def test_all_methods_zero_on_constant_input():
n = 300
r = np.full(n, 140.0)
g = np.full(n, 142.0)
b = np.full(n, 138.0)
assert np.std(extract_green_signal(g)) < 1e-6
assert np.std(extract_chrom_signal(r, g, b)) < 1e-6
assert np.std(extract_pos_signal(r, g, b)) < 1e-6
assert np.std(extract_gr_signal(r, g)) < 1e-6
assert np.std(extract_grgb_signal(r, g, b)) < 1e-6