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 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
| import numpy as np from scipy.signal import find_peaks
class MultiTargetSeparation: """ 多目标分离算法 论文方法: 使用距离-角度聚类分离多个乘员 应用场景: - 多儿童检测 - 成人+儿童混合 - 宠物区分 """ def __init__(self, range_resolution: float = 0.04, angle_resolution: float = 2.0): self.range_res = range_resolution self.angle_res = angle_resolution def separate_targets(self, range_profile: np.ndarray, angle_profile: np.ndarray, doppler_profile: np.ndarray) -> list: """ 分离多个目标 Args: range_profile: 距离剖面, shape=(num_range_bins,) angle_profile: 角度剖面, shape=(num_angle_bins,) doppler_profile: 多普勒剖面, shape=(num_range_bins, num_angle_bins) Returns: targets: 目标列表 [{range, angle, velocity, intensity}] """ range_peaks, _ = find_peaks(range_profile, height=np.mean(range_profile) * 2, distance=3) targets = [] for range_idx in range_peaks: angle_slice = doppler_profile[range_idx, :] angle_peaks, _ = find_peaks(angle_slice, height=np.mean(angle_slice) * 1.5) for angle_idx in angle_peaks: velocity_slice = doppler_profile[range_idx, angle_idx] target = { "range_m": range_idx * self.range_res, "angle_deg": angle_idx * self.angle_res, "intensity": range_profile[range_idx], "velocity_mps": self._estimate_velocity(velocity_slice) } targets.append(target) return targets def classify_target(self, target: dict, vital_signs: dict) -> str: """ 分类目标类型 Args: target: 目标信息 vital_signs: 生命体征信息 Returns: target_type: "child", "adult", "pet", "static_object" """ if not vital_signs.get("presence_detected", False): return "static_object" breathing_rate = vital_signs.get("breathing_rate", 0) heart_rate = vital_signs.get("heart_rate", 0) if breathing_rate > 20 and heart_rate > 90: return "child" if 12 <= breathing_rate <= 20 and 60 <= heart_rate <= 100: return "adult" if breathing_rate > 25 and heart_rate > 100: return "pet" return "unknown" def _estimate_velocity(self, velocity_slice: np.ndarray) -> float: """估计速度""" peak_idx = np.argmax(np.abs(velocity_slice)) velocity = peak_idx * 0.1 return velocity
if __name__ == "__main__": separator = MultiTargetSeparation() num_range_bins = 256 num_angle_bins = 64 range_profile = np.random.randn(num_range_bins) range_profile[50] = 5.0 range_profile[100] = 4.0 angle_profile = np.random.randn(num_angle_bins) doppler_profile = np.random.randn(num_range_bins, num_angle_bins) doppler_profile[50, 30] = 3.0 doppler_profile[100, 20] = 2.5 targets = separator.separate_targets(range_profile, angle_profile, doppler_profile) print(f"检测到 {len(targets)} 个目标:") for i, target in enumerate(targets): print(f"目标{i+1}: 距离 {target['range_m']:.2f}m, 角度 {target['angle_deg']:.1f}°")
|