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
| import numpy as np from scipy import signal
def extract_breathing_signal( radar_data: np.ndarray, range_bin: int, sample_rate: float = 50.0 ) -> np.ndarray: """ 从雷达数据中提取呼吸信号 Args: radar_data: 雷达ADC数据 (frames, chirps, samples) range_bin: 目标距离bin sample_rate: 帧率 (Hz) Returns: breathing_signal: 呼吸信号序列 """ range_fft = np.fft.fft(radar_data, axis=2) target_phase = np.angle(range_fft[:, :, range_bin]) phase_diff = np.diff(target_phase.mean(axis=1)) nyquist = sample_rate / 2 low = 0.1 / nyquist high = 0.5 / nyquist b, a = signal.butter(4, [low, high], btype='band') breathing_signal = signal.filtfilt(b, a, phase_diff) return breathing_signal
def detect_child_presence( breathing_signal: np.ndarray, threshold: float = 0.02 ) -> dict: """ 检测儿童存在 Args: breathing_signal: 呼吸信号 threshold: 能量阈值 Returns: result: {detected: bool, breathing_rate: float, confidence: float} """ energy = np.sum(breathing_signal ** 2) / len(breathing_signal) fft_result = np.abs(np.fft.fft(breathing_signal)) freqs = np.fft.fftfreq(len(breathing_signal), 1/50.0) valid_idx = (freqs >= 0.1) & (freqs <= 0.5) peak_idx = np.argmax(fft_result[valid_idx]) breathing_rate = freqs[valid_idx][peak_idx] * 60 detected = energy > threshold confidence = min(energy / threshold, 1.0) if detected else 0.0 return { 'detected': detected, 'breathing_rate': breathing_rate, 'confidence': confidence, 'energy': energy }
if __name__ == "__main__": radar_data = np.random.randn(100, 16, 64) * 0.01 t = np.linspace(0, 2, 100) breathing = 0.05 * np.sin(2 * np.pi * 0.3 * t) radar_data[:, 0, 20] += breathing breathing_signal = extract_breathing_signal(radar_data, range_bin=20) result = detect_child_presence(breathing_signal) print(f"检测结果: {result}")
|