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 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
| """ Aptiv AOC 摄像头乘员分类模型架构
核心技术: 1. 目标检测:YOLO/MediaPipe 人体关键点 2. 分类模型:CNN + 规则融合 3. 多模型融合:提升稳定性 """
import numpy as np from typing import Tuple, List from dataclasses import dataclass
@dataclass class OccupantInfo: """乘员信息""" classification: str posture: str seating_position: str orientation: str confidence: float
def classify_occupant_with_camera( image: np.ndarray, model_outputs: dict ) -> OccupantInfo: """ 基于摄像头图像进行乘员分类 Args: image: 座舱图像, shape=(H, W, 3) model_outputs: AI模型输出 { 'body_keypoints': 身体关键点, 'height_estimate': 身高估计, 'body_shape': 体型特征 } Returns: occupant_info: 乘员信息 Aptiv AOC 方法: 1. 身体关键点检测(身高/体型) 2. 规则层判定(FMVSS 208 法规) 3. 多模型融合(稳定性) """ keypoints = model_outputs['body_keypoints'] height_estimate = model_outputs['height_estimate'] if keypoints is None: classification = "empty" posture = "na" elif height_estimate < 1.2: classification = "child" posture = detect_posture(keypoints) elif height_estimate < 0.7: classification = "infant" posture = "na" else: classification = "adult" posture = detect_posture(keypoints) seating_position = detect_seating_position(keypoints) orientation = detect_orientation(keypoints) return OccupantInfo( classification=classification, posture=posture, seating_position=seating_position, orientation=orientation, confidence=0.95 )
def detect_posture(keypoints: np.ndarray) -> str: """ 检测坐姿 Args: keypoints: 身体关键点, shape=(17, 3) [x, y, confidence] Returns: posture: normal/forward/side Aptiv方法: 正常坐姿:肩部关键点水平,脊柱垂直 前倾:肩部前移,脊柱弯曲 侧倾:肩部倾斜,脊柱侧弯 """ left_shoulder = keypoints[5] right_shoulder = keypoints[6] shoulder_tilt = abs(left_shoulder[1] - right_shoulder[1]) hip = keypoints[11] spine_angle = calculate_spine_angle(hip, left_shoulder, right_shoulder) if spine_angle < 70: return "forward" if shoulder_tilt > 30: return "side" return "normal"
def detect_seating_position(keypoints: np.ndarray) -> str: """ 检测座椅位置(前后位置) Args: keypoints: 身体关键点 Returns: seating_position: front/middle/back Aptiv方法: 根据膝关键点位置判断座椅前后位置 """ left_knee = keypoints[13] right_knee = keypoints[14] knee_y = (left_knee[1] + right_knee[1]) / 2 if knee_y < 400: return "front" elif knee_y < 600: return "middle" else: return "back"
def detect_orientation(keypoints: np.ndarray) -> str: """ 检测朝向 Args: keypoints: 身体关键点 Returns: orientation: forward/sideways/rearward Aptiv方法: 根据肩部和臀部关键点朝向判断 """ left_shoulder = keypoints[5] right_shoulder = keypoints[6] left_hip = keypoints[11] right_hip = keypoints[12] shoulder_width = abs(right_shoulder[0] - left_shoulder[0]) if shoulder_width > 100: return "forward" elif shoulder_width > 50: return "sideways" else: return "rearward"
def calculate_spine_angle(hip: np.ndarray, left_shoulder: np.ndarray, right_shoulder: np.ndarray) -> float: """ 计算脊柱角度 Returns: angle: 脊柱与垂直方向夹角(度) """ spine_mid = (left_shoulder + right_shoulder) / 2 spine_vector = spine_mid - hip vertical = np.array([0, -1]) angle = np.arccos(np.dot(spine_vector[:2], vertical) / (np.linalg.norm(spine_vector[:2]) + 1e-6)) return np.degrees(angle)
|