1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
| """ 微动检测原理对比 """
import numpy as np from typing import Tuple
class FMCWMicromovementDetector: """ FMCW 雷达微动检测 通过相位变化检测呼吸和心跳 """ def __init__(self, fs: int = 100, wavelength: float = 0.005): self.fs = fs self.wavelength = wavelength def extract_phase(self, adc_data: np.ndarray) -> np.ndarray: """ 从 ADC 数据提取相位 Args: adc_data: 雷达 ADC 数据 (N_samples,) Returns: phase: 相位序列 (弧度) """ range_fft = np.fft.fft(adc_data) target_bin = np.argmax(np.abs(range_fft)) phase = np.angle(range_fft[target_bin]) return phase def detect_breathing(self, phase_sequence: np.ndarray) -> Tuple[bool, float]: """ 检测呼吸 Args: phase_sequence: 相位序列 Returns: (detected, rate) - rate 单位:次/分钟 """ phase_unwrapped = np.unwrap(phase_sequence) displacement = phase_unwrapped * self.wavelength / (4 * np.pi) from scipy.signal import butter, filtfilt b, a = butter(4, [0.1, 0.7], btype='band', fs=self.fs) breathing_signal = filtfilt(b, a, displacement) fft_result = np.fft.rfft(breathing_signal) freqs = np.fft.rfftfreq(len(breathing_signal), 1.0/self.fs) mask = (freqs >= 0.1) & (freqs <= 0.7) if not np.any(mask): return False, 0.0 peak_idx = np.argmax(np.abs(fft_result[mask])) peak_freq = freqs[mask][peak_idx] snr = np.abs(fft_result[mask][peak_idx]) / np.mean(np.abs(fft_result[mask])) detected = snr > 3.0 rate = peak_freq * 60.0 return detected, rate
class UWBMicromovementDetector: """ UWB 微动检测 通过距离变化检测呼吸(精度较低) """ def __init__(self, accuracy: float = 0.1): self.accuracy = accuracy def detect_breathing(self, distance_sequence: np.ndarray) -> Tuple[bool, float]: """ 检测呼吸 Args: distance_sequence: 距离序列 (m) Returns: (detected, rate) """ variance = np.var(distance_sequence) detected = variance > (self.accuracy / 3) ** 2 return detected, 0.0
|