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
| """ 座椅压力分布乘员分类算法
核心方法: 1. 压力分布特征提取 2. 体型识别(成人/儿童) 3. 坐姿识别(正常/异常) """
import numpy as np from typing import Tuple, Dict
def classify_occupant_pressure( pressure_map: np.ndarray, seat_area: Tuple[int, int, int, int] = (50, 100, 150, 250) ) -> Dict: """ 根据压力分布分类乘员 Args: pressure_map: 压力分布矩阵, shape=(H, W), 单位:mmHg seat_area: 座椅区域 (x_min, y_min, x_max, y_max) Returns: classification: { 'occupant_type': 成人/儿童/空座, 'posture': 正常/前倾/侧倾, 'pressure_center': 压力中心, 'contact_area': 接触面积, 'pressure_concentration': 压力集中度 } XSENSOR 方法: 成人特征: - 接触面积大(>5000 cm²) - 压力分布均匀 - 压力中心在座椅中央 儿童特征: - 接触面积小(<3000 cm²) - 压力中心偏前 - 压力集中在臀部 """ x_min, y_min, x_max, y_max = seat_area seat_pressure = pressure_map[y_min:y_max, x_min:x_max] threshold = 10 contact_mask = seat_pressure > threshold contact_area = np.sum(contact_mask) total_pressure = np.sum(seat_pressure) if total_pressure > 0: y_center = np.sum(np.where(contact_mask)[0] * seat_pressure[contact_mask]) / total_pressure x_center = np.sum(np.where(contact_mask)[1] * seat_pressure[contact_mask]) / total_pressure pressure_center = (x_center, y_center) else: pressure_center = (0, 0) max_pressure = np.max(seat_pressure) mean_pressure = np.mean(seat_pressure[contact_mask]) if contact_area > 0 else 0 pressure_concentration = max_pressure / (mean_pressure + 1e-6) if contact_area < 1000: occupant_type = "empty" elif contact_area < 3000: occupant_type = "child" else: occupant_type = "adult" center_x = (x_max - x_min) / 2 center_y = (y_max - y_min) / 2 x_deviation = abs(pressure_center[0] - center_x) y_deviation = pressure_center[1] - center_y if y_deviation > 30: posture = "forward" elif x_deviation > 30: posture = "side" else: posture = "normal" return { 'occupant_type': occupant_type, 'posture': posture, 'pressure_center': pressure_center, 'contact_area': contact_area, 'pressure_concentration': pressure_concentration }
def detect_oop_posture( pressure_map: np.ndarray, normal_center: Tuple[float, float] = (100, 150) ) -> Tuple[bool, str]: """ 检测异常姿态(OOP) Args: pressure_map: 压力分布矩阵 normal_center: 正常坐姿压力中心 Returns: is_oop: 是否异常姿态 oop_type: 异常类型 Euro NCAP 2026 应用: OOP 检测: - 脚踩仪表板:压力分布异常前移 - 座椅后仰:压力中心后移 - 侧向躺卧:压力中心侧移 """ classification = classify_occupant_pressure(pressure_map) is_oop = False oop_type = "normal" center_deviation = np.sqrt( (classification['pressure_center'][0] - normal_center[0]) ** 2 + (classification['pressure_center'][1] - normal_center[1]) ** 2 ) if center_deviation > 50: is_oop = True if classification['posture'] == "forward": oop_type = "feet_on_dashboard" elif classification['pressure_center'][1] > normal_center[1] + 50: oop_type = "seat_recline" elif classification['pressure_center'][0] > normal_center[0] + 50: oop_type = "side_lying" else: oop_type = "unknown_oop" return is_oop, oop_type
if __name__ == "__main__": H, W = 200, 200 pressure_map = np.zeros((H, W)) cv2 = __import__('cv2') cv2.circle(pressure_map, (100, 150), 40, 80, -1) cv2.circle(pressure_map, (100, 80), 30, 60, -1) classification = classify_occupant_pressure(pressure_map) print("="*60) print("XSENSOR 座椅压力分布乘员分类测试") print("="*60) print(f"乘员类型: {classification['occupant_type']}") print(f"坐姿: {classification['posture']}") print(f"压力中心: {classification['pressure_center']}") print(f"接触面积: {classification['contact_area']:.0f} 像素") print(f"压力集中度: {classification['pressure_concentration']:.2f}")
|