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
| import numpy as np import torch import torch.nn as nn
class PostureClassifier(nn.Module): """ 基于压力矩阵的坐姿分类器 输入: (7, 7) 压力矩阵 输出: 姿态分类 + 不舒适度评分 """ POSTURES = [ 'normal_upright', 'normal_reclined', 'leaning_left', 'leaning_right', 'slouching', 'forward_hunch', 'crossed_legs', 'empty', ] def __init__(self, grid_size=7, num_classes=8): super().__init__() self.conv = nn.Sequential( nn.Conv2d(1, 16, 3, padding=1), nn.ReLU(), nn.MaxPool2d(2), nn.Conv2d(16, 32, 3, padding=1), nn.ReLU(), nn.AdaptiveAvgPool2d(1), ) self.classifier = nn.Linear(32, num_classes) self.discomfort = nn.Linear(32, 1) def forward(self, pressure_map): """ Args: pressure_map: (B, 1, 7, 7) 压力矩阵 kPa Returns: posture_logits: (B, 8) 姿态分类 discomfort_score: (B, 1) 不舒适度 0-1 """ feat = self.conv(pressure_map).flatten(1) posture = self.classifier(feat) discomfort = torch.sigmoid(self.discomfort(feat)) return posture, discomfort
class SmartSeatSystem: """ 智能座椅系统 功能: 1. 实时姿态识别 2. 不舒适度评估 3. 主动调节建议 4. 疲劳提醒(每2小时换坐姿) 5. 乘员分类(成人/儿童/物体) """ def __init__(self): self.posture_net = PostureClassifier() self.pressure_history = [] self.sit_duration = 0 self.last_posture = None def update(self, pressure_map, timestamp): """ 实时更新 Args: pressure_map: (7, 7) numpy数组 kPa """ x = torch.FloatTensor(pressure_map).unsqueeze(0).unsqueeze(0) with torch.no_grad(): posture_logits, discomfort = self.posture_net(x) posture_idx = posture_logits.argmax(1).item() posture_name = self.posture_net.POSTURES[posture_idx] discomfort_val = discomfort.item() if posture_name == self.last_posture: self.sit_duration += 1 else: self.sit_duration = 0 self.last_posture = posture_name remind_change = self.sit_duration > 7200 need_adjust = discomfort_val > 0.7 center_of_pressure = self._compute_cop(pressure_map) pressure_imbalance = self._check_imbalance(pressure_map) return { 'posture': posture_name, 'posture_confidence': torch.softmax(posture_logits, 1).max().item(), 'discomfort': discomfort_val, 'sit_duration_s': self.sit_duration, 'remind_posture_change': remind_change, 'need_adjust': need_adjust, 'center_of_pressure': center_of_pressure, 'pressure_imbalance': pressure_imbalance, } def _compute_cop(self, pressure_map): """计算压力中心""" total = pressure_map.sum() if total < 0.1: return None rows, cols = np.indices(pressure_map.shape) cop_x = (cols * pressure_map).sum() / total cop_y = (rows * pressure_map).sum() / total return (cop_x, cop_y) def _check_imbalance(self, pressure_map): """检查左右压力不平衡""" left = pressure_map[:, :3].sum() right = pressure_map[:, 4:].sum() total = left + right if total < 0.1: return 0 return abs(left - right) / total
if __name__ == "__main__": np.random.seed(42) system = SmartSeatSystem() normal_pressure = np.zeros((7, 7)) normal_pressure[2:5, 2:5] = 40 + np.random.randn(3, 3) * 5 normal_pressure[3, 3] = 60 left_pressure = np.zeros((7, 7)) left_pressure[2:5, :3] = 50 + np.random.randn(3, 3) * 5 slouch_pressure = np.zeros((7, 7)) slouch_pressure[4:7, 2:5] = 35 + np.random.randn(3, 3) * 5 slouch_pressure[5, 3] = 55 for name, pressure in [("正常", normal_pressure), ("左倾", left_pressure), ("瘫坐", slouch_pressure)]: result = system.update(pressure, 0) print(f"[{name}]") print(f" 姿态: {result['posture']}") print(f" 不舒适度: {result['discomfort']:.2f}") print(f" 压力中心: {result['center_of_pressure']}") print(f" 左右不平衡: {result['pressure_imbalance']:.2f}") print()
|