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 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
| class OOPDetector: """ 基于 Fast SAM 3D Body 的OOP检测器 优势: 1. 全身3D网格 → 精确关节角度 2. 实时65ms → 可用于安全气囊预判 3. 单RGB摄像头 → 低成本 4. 多人支持 → 适用于全座舱 局限: 1. 需要GPU(RTX级别) 2. 光照敏感(但可配合IR摄像头) 3. 未在车内场景训练(需迁移学习) """ JOINT_NAMES = [ 'pelvis', 'left_hip', 'right_hip', 'spine1', 'left_knee', 'right_knee', 'spine2', 'left_ankle', 'right_ankle', 'spine3', 'left_foot', 'right_foot', 'neck', 'left_collar', 'right_collar', 'head', 'left_shoulder', 'right_shoulder', 'left_elbow', 'right_elbow', 'left_wrist', 'right_wrist', 'left_hand', 'right_hand' ] def __init__(self, reference_pose: dict = None): self.reference_pose = reference_pose or self._default_reference() def _default_reference(self) -> dict: """默认正常坐姿参考""" return { 'torso_forward_angle': 15.0, 'torso_side_angle': 5.0, 'head_height': 1.2, 'knee_height': 0.5, 'foot_height': 0.1, } def detect_oop(self, smpl_pose: dict, seat_position: tuple = None) -> dict: """ 检测OOP异常姿态 Args: smpl_pose: SMPL参数 {'pose': (72,), 'shape': (10,), 'translation': (3,)} seat_position: 座椅位置参考 Returns: {'is_oop': bool, 'oop_type': str, 'severity': float, 'joint_angles': dict} """ pose = smpl_pose['pose'] joints = self._smpl_to_joints(pose) torso_angle = self._compute_torso_forward(joints) side_angle = self._compute_torso_side(joints) head_height = joints['head'][1] knee_height = min(joints['left_knee'][1], joints['right_knee'][1]) foot_height = max(joints['left_foot'][1], joints['right_foot'][1]) results = {} ref_forward = self.reference_pose['torso_forward_angle'] if torso_angle > ref_forward + 15: results['forward_lean'] = { 'detected': True, 'angle': float(torso_angle), 'severity': min((torso_angle - ref_forward) / 30, 1.0) } ref_side = self.reference_pose['torso_side_angle'] if abs(side_angle) > ref_side + 10: results['side_lean'] = { 'detected': True, 'angle': float(side_angle), 'direction': 'left' if side_angle < 0 else 'right', 'severity': min(abs(side_angle) / 30, 1.0) } if knee_height > 0.8: results['kneeling'] = { 'detected': True, 'knee_height': float(knee_height), 'severity': min(knee_height / 1.0, 1.0) } if foot_height > 0.6: results['feet_on_dash'] = { 'detected': True, 'foot_height': float(foot_height), 'severity': min(foot_height / 1.0, 1.0) } is_oop = len(results) > 0 max_severity = max([r['severity'] for r in results.values()], default=0) return { 'is_oop': is_oop, 'oop_types': list(results.keys()), 'severity': float(max_severity), 'details': results, 'joint_angles': { 'torso_forward': float(torso_angle), 'torso_side': float(side_angle), 'head_height': float(head_height), 'knee_height': float(knee_height), 'foot_height': float(foot_height), } } def _smpl_to_joints(self, pose_params: torch.Tensor) -> dict: """SMPL参数 → 3D关节坐标(简化版)""" np.random.seed(42) joints = {} for name in self.JOINT_NAMES: joints[name] = np.random.randn(3) return joints def _compute_torso_forward(self, joints: dict) -> float: """计算躯干前倾角度""" pelvis = joints['pelvis'] neck = joints['neck'] torso_vec = neck - pelvis forward_angle = np.degrees(np.arctan2( torso_vec[2], max(torso_vec[1], 0.01) )) return abs(forward_angle) def _compute_torso_side(self, joints: dict) -> float: """计算躯干侧倾角度""" pelvis = joints['pelvis'] neck = joints['neck'] torso_vec = neck - pelvis side_angle = np.degrees(np.arctan2( torso_vec[0], max(torso_vec[1], 0.01) )) return side_angle
if __name__ == "__main__": detector = OOPDetector() normal_pose = { 'pose': torch.randn(72), 'shape': torch.randn(10), 'translation': torch.randn(3) } result = detector.detect_oop(normal_pose) print("=== OOP检测结果 ===") print(f"OOP检测: {result['is_oop']}") print(f"OOP类型: {result['oop_types']}") print(f"严重度: {result['severity']:.2f}") print(f"关节角度: {result['joint_angles']}")
|